void OGLESRenderView::DoDiscardColor() { if (glloader_GLES_EXT_discard_framebuffer()) { GLenum attachment; if (fbo_ != 0) { attachment = GL_COLOR_ATTACHMENT0 + index_; } else { attachment = GL_COLOR_EXT; } OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); GLuint old_fbo = re.BindFramebuffer(); re.BindFramebuffer(fbo_); glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment); re.BindFramebuffer(old_fbo); } else { this->ClearColor(Color(0, 0, 0, 0)); } }
void OGLESRenderView::DoDiscardDepthStencil() { if (glloader_GLES_EXT_discard_framebuffer()) { GLenum attachments[2]; if (fbo_ != 0) { attachments[0] = GL_DEPTH_ATTACHMENT; attachments[1] = GL_STENCIL_ATTACHMENT; } else { attachments[0] = GL_DEPTH_EXT; attachments[1] = GL_STENCIL_EXT; } OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); GLuint old_fbo = re.BindFramebuffer(); re.BindFramebuffer(fbo_); glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments); re.BindFramebuffer(old_fbo); } else { this->ClearDepthStencil(1, 0); } }
void teRenderGL::End() { #ifdef TE_DEBUG switch(glGetError()) { case GL_NO_ERROR: break; case GL_INVALID_ENUM: TE_LOG_ERR("OpenGL Error : Invalid enum"); break; case GL_INVALID_VALUE: TE_LOG_ERR("OpenGL Error : Invalid value"); break; case GL_INVALID_OPERATION: TE_LOG_ERR("OpenGL Error : Invalid operation"); break; case GL_OUT_OF_MEMORY: TE_LOG_ERR("OpenGL Error : Out of memory"); break; #if defined(TE_OPENGL_ES_11) || defined(TE_OPENGL_15) case GL_STACK_OVERFLOW: TE_LOG_ERR("OpenGL Error : Stack overflow"); break; case GL_STACK_UNDERFLOW: TE_LOG_ERR("OpenGL Error : Stack underflow"); break; #endif default: TE_LOG_ERR("OpenGL Error : Unknown error") break; } #endif #if defined (TE_PLATFORM_IPHONE) const GLenum discards[] = {GL_DEPTH_ATTACHMENT}; te::app::GetApplicationManager()->GetFrameBuffer()->Bind(); glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); #else glFlush(); glFinish(); #endif if(CurrentContext) CurrentContext->PresentCurrentTexture(); }
EXTERN_C_ENTER JNIEXPORT void JNICALL Java_org_lwjgl_opengles_EXTDiscardFramebuffer_nglDiscardFramebufferEXT__IIJ(JNIEnv *__env, jclass clazz, jint target, jint numAttachments, jlong attachmentsAddress) { glDiscardFramebufferEXTPROC glDiscardFramebufferEXT = (glDiscardFramebufferEXTPROC)tlsGetFunction(405); intptr_t attachments = (intptr_t)attachmentsAddress; UNUSED_PARAM(clazz) glDiscardFramebufferEXT(target, numAttachments, attachments); }
void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments) { #ifndef MAGNUM_TARGET_GLES2 glInvalidateFramebuffer(GLenum(bindInternal()), count, attachments); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glDiscardFramebufferEXT(GLenum(bindInternal()), count, attachments); #else static_cast<void>(count); static_cast<void>(attachments); CORRADE_ASSERT_UNREACHABLE(); #endif }
void RenderingEngine2::resolve_msaa(const GLuint readFBO, const GLuint writeFBO) { #if defined (MSAA_ENABLED) glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, readFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, writeFBO); glResolveMultisampleFramebufferAPPLE(); GLenum discardAttachments[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT }; glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discardAttachments); #else GLenum discardAttachments[] = { GL_DEPTH_ATTACHMENT }; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discardAttachments); #endif }
void PreparePresentSurfaceGLES(EAGLSurfaceDesc* surface) { #if GL_APPLE_framebuffer_multisample if( surface->msaaSamples > 0 && _supportsMSAA ) { Profiler_StartMSAAResolve(); UNITY_DBG_LOG (" ResolveMSAA: samples=%i msaaFBO=%i destFBO=%i\n", surface->msaaSamples, surface->msaaFramebuffer, surface->framebuffer); GLES_CHK( glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, surface->msaaFramebuffer) ); GLES_CHK( glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, surface->framebuffer) ); GLES_CHK( glResolveMultisampleFramebufferAPPLE() ); Profiler_EndMSAAResolve(); } #endif // update screenshot here if( UnityIsCaptureScreenshotRequested() ) { GLint curfb = 0; GLES_CHK( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curfb) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->framebuffer) ); UnityCaptureScreenshot(); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, curfb) ); } #if GL_EXT_discard_framebuffer if( _supportsDiscard ) { GLenum attachments[3]; int discardCount = 0; if (surface->msaaSamples > 1 && _supportsMSAA) attachments[discardCount++] = GL_COLOR_ATTACHMENT0_OES; if (surface->depthFormat) attachments[discardCount++] = GL_DEPTH_ATTACHMENT_OES; attachments[discardCount++] = GL_STENCIL_ATTACHMENT_OES; GLenum target = (surface->msaaSamples > 1 && _supportsMSAA) ? GL_READ_FRAMEBUFFER_APPLE: GL_FRAMEBUFFER_OES; if (discardCount > 0) { GLES_CHK( glDiscardFramebufferEXT(target, discardCount, attachments) ); } } #endif }
void LayerRenderer::flushLayer(Layer* layer) { #if defined(GL_EXT_discard_framebuffer) && !defined(EXYNOS4_ENHANCEMENTS) GLuint fbo = layer->getFbo(); if (layer && fbo) { // If possible, discard any enqueud operations on deferred // rendering architectures if (Extensions::getInstance().hasDiscardFramebuffer()) { GLuint previousFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo); const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 }; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments); if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); } } #endif }
void GLES_GPU::CopyDisplayToOutputInternal() { glstate.depthWrite.set(GL_TRUE); glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); transformDraw_.Flush(); framebufferManager_.CopyDisplayToOutput(); framebufferManager_.EndFrame(); shaderManager_->EndFrame(); // If buffered, discard the depth buffer of the backbuffer. Don't even know if we need one. #if 0 #ifdef USING_GLES2 if (gl_extensions.EXT_discard_framebuffer && g_Config.iRenderingMode != 0) { GLenum attachments[] = {GL_DEPTH_EXT, GL_STENCIL_EXT}; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments); } #endif #endif gstate_c.textureChanged = true; }
void LayerRenderer::flushLayer(RenderState& renderState, Layer* layer) { #if defined(GL_EXT_discard_framebuffer) && !defined(EXYNOS4_ENHANCEMENTS) if (!layer) return; GLuint fbo = layer->getFbo(); if (fbo) { // If possible, discard any enqueud operations on deferred // rendering architectures if (Caches::getInstance().extensions().hasDiscardFramebuffer()) { GLuint previousFbo = renderState.getFramebuffer(); if (fbo != previousFbo) { renderState.bindFramebuffer(fbo); } const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 }; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments); if (fbo != previousFbo) { renderState.bindFramebuffer(previousFbo); } } } #endif }
void OGLESFrameBuffer::Discard(uint32_t flags) { if (glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_discard_framebuffer()) { std::vector<GLenum> attachments; if (fbo_ != 0) { if (flags & CBM_Color) { for (size_t i = 0; i < clr_views_.size(); ++ i) { if (clr_views_[i]) { attachments.push_back(static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i)); } } } if (flags & CBM_Depth) { if (rs_view_) { attachments.push_back(GL_DEPTH_ATTACHMENT); } } if (flags & CBM_Stencil) { if (rs_view_) { attachments.push_back(GL_STENCIL_ATTACHMENT); } } } else { if (flags & CBM_Color) { attachments.push_back(GL_COLOR); } if (flags & CBM_Depth) { attachments.push_back(GL_DEPTH); } if (flags & CBM_Stencil) { attachments.push_back(GL_STENCIL); } } OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); GLuint old_fbo = re.BindFramebuffer(); re.BindFramebuffer(fbo_); if (glloader_GLES_VERSION_3_0()) { glInvalidateFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(attachments.size()), &attachments[0]); } else { glDiscardFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLsizei>(attachments.size()), &attachments[0]); } re.BindFramebuffer(old_fbo); } else { this->Clear(flags, Color(0, 0, 0, 0), 1, 0); } }
void RenderScene::RenderScene(RenderLists* renderLists, Camera* camera, DirectionalLight* directionalLight, std::vector<DirectionalLight*> additionalLights) { #ifdef PLATFORM_IOS GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo); #endif std::vector<DirectionalLight*> emptyVector; { // Switch off blend for depth pass: GLCALL(glDisable, GL_BLEND); Camera* depthCamera = ENGINE->GetShadowMap()->GetDepthCamera(); #if defined(DRAWING_DEPTH_BUFFER_CONTENTS) GLCALL(glViewport, 0, 0, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels()); GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */); #else /* * Draw to the depth buffer: */ unsigned int depthMap_width, depthMap_height; ENGINE->GetShadowMap()->GetDepthMapResolution(depthMap_width, depthMap_height); // GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, g_depth_fbo_id); GLCALL(glViewport, 0, 0, depthMap_width, depthMap_height); GLCALL(glClear, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif // Depth pass draw: ENGINE->GetSceneGraph3D()->SetMainCameraId(depthCamera->GetObject()->GetId()); renderLists->Draw(depthCamera, nullptr /* no lights in depth pass */, emptyVector /* no lights in depth pass */, true, DISTANCE_FROM_CAMERA_COMPARE_TYPE_perspective); // Switch blend back on: GLCALL(glEnable, GL_BLEND); } #if MULTISAMPLING_ENABLED glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif { #if !defined(DRAWING_DEPTH_BUFFER_CONTENTS) /* * Draw again, this time to the screen: */ ENGINE->GetSceneGraph3D()->SetMainCameraId(camera->GetObject()->GetId()); #if !MULTISAMPLING_ENABLED GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */); #endif GLCALL(glViewport, 0, 0, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels()); renderLists->Draw(camera, directionalLight, additionalLights, false, DISTANCE_FROM_CAMERA_COMPARE_TYPE_perspective); #endif } #if MULTISAMPLING_ENABLED // Apple (and the khronos group) encourages you to discard depth // render buffer contents whenever is possible const GLenum discard1[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT}; glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discard1); const GLenum discard2[] = {GL_DEPTH_ATTACHMENT}; glDiscardFramebufferEXT(GL_DRAW_FRAMEBUFFER_APPLE, 1, discard2); //Bind both MSAA and View FrameBuffers. glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, SCREEN_FRAME_BUFFER); // Call a resolve to combine both buffers glResolveMultisampleFramebufferAPPLE(); // Present final image to screen glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); // [context presentRenderbuffer:GL_RENDERBUFFER]; #endif }
bool gl_initialize(int screen_wid,int screen_high,int fsaa_mode,char *err_str) { int sdl_flags; GLint ntxtsize; #if defined(D3_OS_LINUX) || defined(D3_OS_WINDOWS) GLenum glew_error; #endif #ifdef D3_OS_IPHONE const GLenum discards[]={GL_DEPTH_ATTACHMENT,GL_STENCIL_ATTACHMENT}; #endif // reset sizes to the desktop // if they are at default if ((screen_wid==-1) || (screen_high==-1)) { screen_wid=render_info.desktop.wid; screen_high=render_info.desktop.high; } // setup rendering sizes #ifndef D3_ROTATE_VIEW view.screen.x_sz=screen_wid; view.screen.y_sz=screen_high; #else view.screen.x_sz=screen_high; view.screen.y_sz=screen_wid; #endif view.screen.wide=gl_is_size_widescreen(view.screen.x_sz,view.screen.y_sz); // normal attributes SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); #ifdef D3_OPENGL_ES SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,0); #endif #ifdef D3_OS_IPHONE SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING,1); #endif // full screen anti-aliasing attributes switch (fsaa_mode) { case fsaa_mode_2x: SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,2); break; case fsaa_mode_4x: SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4); break; case fsaa_mode_8x: SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,8); break; } // start window or full screen sdl_flags=SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN; if (!gl_in_window_mode()) sdl_flags|=(SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS); sdl_wind=SDL_CreateWindow("dim3",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,screen_wid,screen_high,sdl_flags); if (sdl_wind==NULL) { sprintf(err_str,"SDL: Could not create window (Error: %s)",SDL_GetError()); return(FALSE); } sdl_gl_ctx=SDL_GL_CreateContext(sdl_wind); // use glew on linux and windows #if defined(D3_OS_LINUX) || defined(D3_OS_WINDOWS) glew_error=glewInit(); if (glew_error!=GL_NO_ERROR) { strcpy(err_str,glewGetErrorString(glew_error)); return(FALSE); } #endif // grab openGL attributes strncpy(render_info.name,(char*)glGetString(GL_RENDERER),64); render_info.name[63]=0x0; strncpy(render_info.ext_string,(char*)glGetString(GL_EXTENSIONS),8192); render_info.ext_string[8191]=0x0; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&ntxtsize); render_info.texture_max_size=(int)ntxtsize; if (!gl_check_initialize(err_str)) return(FALSE); // stick refresh rate to 60 render_info.monitor_refresh_rate=60; #ifndef D3_ROTATE_VIEW gl_set_viewport(0,0,view.screen.x_sz,view.screen.y_sz); #else gl_set_viewport(0,0,view.screen.y_sz,view.screen.x_sz); #endif gl_setup_context(); #ifndef D3_OPENGL_ES if (fsaa_mode!=fsaa_mode_none) glEnable(GL_MULTISAMPLE); #endif // clear the entire window so it doesn't flash glClearColor(0.0f,0.0f,0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT); #ifdef D3_OS_IPHONE glDiscardFramebufferEXT(GL_FRAMEBUFFER,2,discards); #endif SDL_GL_SwapWindow(sdl_wind); // texture utility initialize gl_texture_initialize(); return(TRUE); }
void PreparePresentSurfaceGLES(EAGLSurfaceDesc* surface) { #if GL_APPLE_framebuffer_multisample if( surface->msaaSamples > 1 && _supportsMSAA ) { Profiler_StartMSAAResolve(); GLuint drawFB = surface->targetFramebuffer ? surface->targetFramebuffer : surface->systemFramebuffer; GLES_CHK( glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, surface->msaaFramebuffer) ); GLES_CHK( glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, drawFB) ); GLES_CHK( glResolveMultisampleFramebufferAPPLE() ); Profiler_EndMSAAResolve(); } #endif // update screenshot from target FBO to get requested resolution if( UnityIsCaptureScreenshotRequested() ) { GLint target = surface->targetFramebuffer ? surface->targetFramebuffer : surface->systemFramebuffer; GLint curfb = 0; GLES_CHK( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curfb) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, target) ); UnityCaptureScreenshot(); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, curfb) ); } if( surface->targetFramebuffer ) { gDefaultFBO = surface->systemFramebuffer; GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); UnityBlitToSystemFB(surface->targetRT, surface->targetW, surface->targetH, surface->systemW, surface->systemH); gDefaultFBO = surface->msaaFramebuffer ? surface->msaaFramebuffer : surface->targetFramebuffer; GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); } #if GL_EXT_discard_framebuffer if( _supportsDiscard ) { GLenum discardAttach[] = {GL_COLOR_ATTACHMENT0_OES, GL_DEPTH_ATTACHMENT_OES, GL_STENCIL_ATTACHMENT_OES}; if( surface->msaaFramebuffer ) GLES_CHK( glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, discardAttach) ); if(surface->targetFramebuffer) { GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->targetFramebuffer) ); GLES_CHK( glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 3, discardAttach) ); } GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->systemFramebuffer) ); GLES_CHK( glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 2, &discardAttach[1]) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); } #endif }
bool AppCore::render() { #if !DISCARD_SKYBOX // Try to load textures if not already completed if (_staticTextureCompleteCount <= 6) loadStaticTextureIfAvailable(); #endif APIFactory::GetInstance().lock(OPENGL_LOCK); double timestamp = APIFactory::GetInstance().getTimeInMS(); #if !(RENDER_OCTREE_DEBUG_VOXELS || USE_STATIC_POINT_CLOUD) if ( !(_currentCameraParameterRequest & 1) && (timestamp - _lastCameraParameterChangeTimestamp > WVS_RELOAD_DELAY[0])) { // Request 1/4 of screen resolution from WVS requestPointCloudForCurrentView(4); _currentCameraParameterRequest |= 1; } else if ( !(_currentCameraParameterRequest & 2) && (timestamp - _lastCameraParameterChangeTimestamp > WVS_RELOAD_DELAY[1])) { // Request full screen resolution from WVS requestPointCloudForCurrentView(1); _currentCameraParameterRequest |= 3; } #endif if (_isUserInputMode) _renderingRequired = true; if (_renderQuality < 1.0f) _renderingRequired = true; #if !(RENDER_OCTREE_DEBUG_VOXELS || USE_STATIC_POINT_CLOUD) if (_isNewDataAvialable) { _renderingRequired = true; _isNewDataAvialable = false; } #endif if (!_renderingRequired) { APIFactory::GetInstance().unlock(OPENGL_LOCK); APIFactory::GetInstance().processUserInterfaceEvents(); return false; } _renderingRequired = false; // Updates the view frustum that is used for culling etc. based on the current // camera parameters _viewFrustum->updateCameraViewParameterCache(); // Clear context glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #if !DISCARD_SKYBOX // Render Skybox and ground plane if (_staticTextureCompleteCount > 0) { glUseProgram(_textureShaderProgram.handle); glUniformMatrix4fv( _textureShaderProgram.uniforms[SHADER_UNIFORM_VIEW_PROJECTION_MATRIX], 1, GL_FALSE, _viewFrustum->getViewProjectionMatrixCachePtr()->f); MATRIX model; MatrixTranslation(model, _viewFrustum->getCameraPostionCachePtr()->x, _viewFrustum->getCameraPostionCachePtr()->y, _viewFrustum->getCameraPostionCachePtr()->z); glUniformMatrix4fv( _textureShaderProgram.uniforms[SHADER_UNIFORM_MODEL_MATRIX], 1, GL_FALSE, model.f); _skybox->render(); } #endif // Render points glUseProgram(_pointShaderProgram.handle); glUniform3fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_REGION_ORIGIN], OCTREE_LEAF_LEVEL + 1, _octree->getRegionOrginArray()); glUniform1fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VOXEL_INCIRCLE_DIAMETER], OCTREE_LEAF_LEVEL + 1, _octree->getVoxelIncircleDiameterArray()); glUniform1fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_NODE_INCIRCLE_DIAMETER], OCTREE_LEAF_LEVEL + 1, _octree->getNodeIncircleDiameterArray()); glUniform1fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VOXEL_SCREENSIZE_CIRCUMCIRCLE_RADIUS], OCTREE_LEAF_LEVEL + 1, _voxelScreensizeCircumcircleRadius); // Set camera position (necessary for backface culling) glUniform3fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_CAMERA_POSITION], 1, (GLfloat*)(_viewFrustum->getCameraPostionCachePtr())); glUniformMatrix4fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_PROJECTION_MATRIX], 1, GL_FALSE, _viewFrustum->getProjectionMatrixCachePtr()->f); glUniformMatrix4fv( _pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VIEW_MATRIX], 1, GL_FALSE, _viewFrustum->getViewMatrixCachePtr()->f); #if COMPACT_NODE_REGION_ENCODING const uint32_t regionVoxelFactor = 1; const uint8_t regionLevelStride = 4; const uint32_t regionLevelDataType = GL_UNSIGNED_BYTE; #else const uint32_t regionVoxelFactor = 2; const uint8_t regionLevelStride = 8; const uint32_t regionLevelDataType = GL_UNSIGNED_SHORT; #endif #if DIRECT_VBO #if DIRECT_VBO_DOUBLE_BUFFERED if (bufferID == 0) bufferID = 1; else bufferID = 0; #endif glBindBuffer(GL_ARRAY_BUFFER, _dataVBO[bufferID]); uint32_t* const gpuBuffer = (uint32_t*)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); uint32_t* const regionLevelBuffer = gpuBuffer; uint32_t* const voxelBuffer = gpuBuffer + GPU_MAX_POINTS * regionVoxelFactor; glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, (void *)(GPU_MAX_POINTS * regionLevelStride)); glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA2, 4, regionLevelDataType, GL_FALSE, 0, 0); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); // Traverse octree, copy points into buffer and call rendering callback _octree->copyPointsToBuffer( _renderQuality, !_isInteractiveMode, regionLevelBuffer, voxelBuffer, &_pointsToRenderCount, &_renderingRequired); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); glUnmapBufferOES(GL_ARRAY_BUFFER); #elif NO_VBO uint32_t* const regionLevelBuffer = _gpuBuffer; uint32_t* const voxelBuffer = _gpuBuffer + GPU_MAX_POINTS * regionVoxelFactor; glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4, voxelBuffer); glVertexAttribPointer( POINT_SHADER_ATTRIBUTE_DATA2, 4, regionLevelDataType, GL_FALSE, regionLevelStride, regionLevelBuffer); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); // Traverse octree, copy points into buffer and call rendering callback _octree->copyPointsToBuffer( _renderQuality, !_isInteractiveMode, regionLevelBuffer, voxelBuffer, &_pointsToRenderCount, &_renderingRequired); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1); glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2); #endif #ifdef OPENGL_ES const GLenum discard_attachments[] = { GL_DEPTH_ATTACHMENT }; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discard_attachments); #endif if (_renderingRequired & Octree::OCTREE_RENDERING_CANCELED) { APIFactory::GetInstance().unlock(OPENGL_LOCK); //TODO: In case we overestimate the render quality by far this becomes a stupid loop _octree->estimateInteractiveRenderQuality(&_renderQuality, OCTREE_INTERACTIVE_RENDERING_POINT_THRESHOLD); return false; } #if BENCHMARK_1_MILLION if (_pointsToRenderCount >= 1000000) { _renderingRequired = true; double time = APIFactory::GetInstance().getTimeInMS(); printf("%f\n", time - _lastFrame); _lastFrame = time; } #endif if (_isUserInputMode || ((timestamp - _lastCameraParameterChangeTimestamp) < 500)) { // Within 500ms we consider any input as movement double_t renderingTimeInMS = APIFactory::GetInstance().getTimeInMS() - timestamp; if (renderingTimeInMS > (1000.0 / MINIMUM_FRAMERATE)) { // Time to render last frame took longer than target framerate. // Lower render quality to speed up framerate. _renderQuality -= RENDER_QUALITY_FINE_ADJUSTMENT; _nodeRestoreQuota = 0; } else if (renderingTimeInMS < (1000.0 / MAXIMUM_FRAMERATE)) { _renderQuality += RENDER_QUALITY_FINE_ADJUSTMENT; _nodeRestoreQuota = 32; } _renderingRequired = true; } else { // No movement with in the last 500ms. Increase render quality _renderQuality += RENDER_QUALITY_COARSE_ADJUSTMENT; _isInteractiveMode = false; } // Check range of render quality if (_renderQuality > 1.0f) _renderQuality = 1.0f; else if (_renderQuality < RENDER_QUALITY_FINE_ADJUSTMENT) _renderQuality = RENDER_QUALITY_FINE_ADJUSTMENT; APIFactory::GetInstance().unlock(OPENGL_LOCK); return true; }