Пример #1
0
	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));
		}
	}
Пример #2
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);
		}
	}
Пример #3
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
}
Пример #6
0
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
}
Пример #9
0
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;
}
Пример #10
0
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
}
Пример #11
0
	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);
		}
	}
Пример #12
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


}
Пример #13
0
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);
}
Пример #14
0
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
}
Пример #15
0
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;
}