Ejemplo n.º 1
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occurred
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevant OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2FilmTV::RenderScene()
{
	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Enable the vertex attribute arrays
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glEnableVertexAttribArray(NORMAL_ARRAY);

    // Render everything from the mini-camera's point of view if we have the FBOs
    CalcMiniCameraView();

    if(m_bFBOsCreated)
    {
		// Setup the Viewport to the dimensions of the texture
		glViewport(0, 0, m_i32TexSize, m_i32TexSize);

		glBindFramebuffer(GL_FRAMEBUFFER, m_uiFbo[m_i32CurrentFBO]);

		DrawPODScene(m_MiniCamViewProj, false);

		if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
		{
			/*
				Give the drivers a hint that we don't want the depth and stencil information stored for future use.

				Note: This training course doesn't have any stencil information so the STENCIL_ATTACHMENT enum 
				is used for demonstrations purposes only and will be ignored by the driver.
			*/
			const GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
			m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments);
		}

		glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFB);

		// Render everything

		// Setup the Viewport to the dimensions of the screen
		glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
    }

	DrawPODScene(m_ViewProjection, true);

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("FilmTV", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	// Swap the FBO that we want to render to
	m_i32CurrentFBO = 1 - m_i32CurrentFBO;

	++m_i32Frame;
	return true;
}
Ejemplo n.º 2
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important and relevant OS events.
				The user has access to these events through an abstraction
				layer provided by PVRShell.
******************************************************************************/
bool OGLES2EdgeDetection::RenderScene()
{
	// Declares world orientation variables.
	PVRTMat4 mWorld, mMVP;

	// Updates the current time.
	m_ulCurrentTime=PVRShellGetTime();

#ifdef SHOW_MAX_FPS
	//Updates and checks framerate.
	m_iFrameCount+=1;
	if (m_ulCurrentTime-m_ulPreviousTimeFPS>=1000)
	{
		m_fFPS=(GLfloat)m_iFrameCount/(GLfloat)(m_ulCurrentTime-m_ulPreviousTimeFPS)*1000.0f;
		m_ulPreviousTimeFPS=m_ulCurrentTime;
		m_iFrameCount=0;
	}
	// Display fps data
	m_Print3D.Print3D(2.0f, 10.0f, 0.75f, 0xff0000ff, "%i fps", (int)m_fFPS);
#endif

	// Time dependant updates for the rotational velocity of the scene.
	m_fAngleY += 0.0002f*PVRT_PI*(m_ulCurrentTime-m_ulPreviousTimeAngle);
	m_ulPreviousTimeAngle=PVRShellGetTime();

	// Render to our texture (bracketed for viewing convenience)
	{
		// Use the first shader program to perform the initial render of the mask.
		glUseProgram(m_PreShader.uiId);

		// Bind render-to-texture frame buffer and set the viewPort
		glBindFramebuffer(GL_FRAMEBUFFER, m_uiFramebufferObject);
		glViewport(0, 0, m_i32TexWidth, m_i32TexHeight);

#if defined(__PALMPDK__)
		// Enable writing to the alpha channel again as usually it is disabled so
		// we don't blend with the video layer on webOS devices.
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
#endif
		// Clear the color and depth buffer of our FBO
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Rotates the scene and sets the model-view-projection matrix
		mWorld = PVRTMat4::RotationY(m_fAngleY);
		mMVP = m_mR2TProjection * m_mR2TView * mWorld;

		// Send the view matrix information to the shader.
		glUniformMatrix4fv(m_PreShader.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.f);

		// Enable vertex attribute array
		glEnableVertexAttribArray(eVERTEX_ARRAY);

		//Enable depth testing and culling.
		glEnable(GL_DEPTH_TEST);
		glFrontFace(GL_CCW);
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);

		// Draw our models by looping through each mesh as defined by nNumMesh.
		for (unsigned int i=0; i<m_Scene.nNumMeshNode; i++)
		{
			DrawMesh(i);
		}

		// Unbind the VBO and index buffer.
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);

		if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
		{
			//Give the drivers a hint that we don't want stencil or depth information to be stored for later.
			const GLenum attachment = GL_DEPTH_ATTACHMENT;
			m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
		}

#if defined(__PALMPDK__)
		// Disable writing to the alpha channel again so we don't blend with the video layer on webOS devices
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
#endif
	}

	// Bind the original frame buffer to draw to screen and set the Viewport.
	glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFramebuffer);
	glViewport(0, 0, m_i32TexWidth, m_i32TexHeight);

	// Clear the color and depth buffers for the screen.
	glClear(GL_COLOR_BUFFER_BIT);

	// Uses PVRShell input handling to update the line width in the edge detection shaders.
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_fLineWidth++;
		if (m_fLineWidth>10) m_fLineWidth=10;
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_fLineWidth--;
		if (m_fLineWidth<1) m_fLineWidth=1;
	}
	// Uses PVRShell input to choose which post shader program to use for post processing.
	// Loops through all shaders defined in EPostShaders
	if (PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		if (m_uiShaderID==eNumPostShaders-1) m_uiShaderID=0;
		else m_uiShaderID++;
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		if (m_uiShaderID==0) m_uiShaderID=eNumPostShaders-1;
		else m_uiShaderID--;
	}

	// Sets the shader based on the shader ID value, and sets the line width each frame (as it can change);
	glUseProgram(m_PostShaders[m_uiShaderID].uiId);
	glUniform2f(m_PostShaders[m_uiShaderID].auiLoc[ePixelSize],m_fLineWidth/(float)m_i32TexWidth,m_fLineWidth/(float)m_i32TexHeight);

	/*  Note: We do not need to pass any projection data to these shaders as they are used only to render a texture to a
		full screen quad which is parallel with the viewport. The model meshes have already been positioned in the previous
		shader and now only exist as a 2D image.*/

	// Enable texture attribute array
	glEnableVertexAttribArray(eTEXCOORD_ARRAY);
	// Draw the fullscreen quad to render the screen to.
	DrawQuad();

	// Disable the vertex and texture attribute arrays
	glDisableVertexAttribArray(eTEXCOORD_ARRAY);
	glDisableVertexAttribArray(eVERTEX_ARRAY);

	// Print the demo title, current post shader's name and the line width if applicable
	m_Print3D.DisplayDefaultTitle("Edge Detection", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Print3D(5,80,1,0xff885500,g_aszPostShaderNames[m_uiShaderID]);
	if (!strcmp(c_aszPostShaderDefines[m_uiShaderID][0],"EDGE_DETECTION"))
		m_Print3D.Print3D(5,90,0.7f,0xff000055,"Line Width = %i", (int)m_fLineWidth);
	m_Print3D.Flush();

	return true;
}
Ejemplo n.º 3
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2Bloom::RenderScene()
{
	HandleInput();

	// Calculate the mask and light rotation based on the passed time
	static unsigned long ulPreviousTime = PVRShellGetTime();
	unsigned long ulNowTime = PVRShellGetTime();
	m_fRotation += PVRT_PI * (ulNowTime - ulPreviousTime) * 0.0002f;
	ulPreviousTime = ulNowTime;
	if (m_fRotation > (PVRT_PI * 2.0f))
		m_fRotation -= PVRT_PI * 2.0f;
	
	// Calculate the model, view and projection matrix
	float fModelAngleY = m_fRotation;
	float fLightAngleY = -m_fRotation;

	PVRTMat4 mWorld = PVRTMat4::RotationY(fModelAngleY);
	PVRTMat4 mLight = PVRTMat4::RotationY(fLightAngleY);
	PVRTMat4 mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 150), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0));

	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(g_fCameraFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate);
	PVRTMat4 mMVP = mProjection * mView * mWorld;

	// Simple rotating directional light in model-space
	PVRTVec4 vMsLightPos = mWorld.inverse() * mLight * PVRTVec4(0.5f, -1, -0.5f, 0).normalize();

	glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);
	glClearColor(0.075f, 0.1f, 0.125f, 0.0f);
	glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use simple shader program to render the mask
	glUseProgram(m_ShaderProgram.uiId);
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.f);
	glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vMsLightPos.x);

	// Draw the mesh
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBaseTex);
	DrawMesh(0);

	if (m_bApplyBloom)
	{
		// First render the objects which shall have the bloom effect to a texture
		glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[0]);
		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glViewport(0, 0, m_i32TexSize, m_i32TexSize);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glUseProgram(m_PreBloomShaderProgram.uiId);
		glUniformMatrix4fv(m_PreBloomShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.f);
		glUniform3fv(m_PreBloomShaderProgram.uiLightDirLoc, 1, &vMsLightPos.x);
		glUniform1f(m_PreBloomShaderProgram.uiBloomIntensity, m_fBloomIntensity);

		// Draw the mesh
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiBloomMappingTexture);
		DrawMesh(0);

		if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
		{
			//Give the drivers a hint that we don't want depth information to be stored for later.
			const GLenum attachment = GL_DEPTH_ATTACHMENT;
			m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
		}
		/*
		  Blur the generated image n-times
		*/
		for (unsigned int i=0; i < m_ui32BlurPasses; i++)
		{
			/*
			 Apply horizontal blur
			*/
			glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[1]);
			glViewport(0, 0, m_i32TexSize, m_i32TexSize);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, m_uiBlurTextures[0]);

			// Use the shader program for the scene
			glUseProgram(m_BlurShaderProgram.uiId);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetX, m_fTexelOffset);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetY, 0.0f);

			DrawAxisAlignedQuad(PVRTVec2(-1, -1), PVRTVec2(1, 1));


			//No attachments we can invalidate here, as only color was used which is necessary.
			/*
			   Apply vertical blur
			*/
			glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[0]);
			glViewport(0, 0, m_i32TexSize, m_i32TexSize);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, m_uiBlurTextures[1]);

			// Use the shader program for the scene
			glUseProgram(m_BlurShaderProgram.uiId);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetX, 0.0f);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetY, m_fTexelOffset);

			DrawAxisAlignedQuad(PVRTVec2(-1, -1), PVRTVec2(1, 1));

			if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
			{
				//Give the drivers a hint that we don't want depth information to be stored for later.
				const GLenum attachment = GL_DEPTH_ATTACHMENT;
				m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
			}
		}

		/*
		  Draw scene with bloom
		*/
		glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);
		glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

		glEnable(GL_BLEND);
		glBlendFunc(GL_ONE, GL_ONE);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiBlurTextures[0]);

		// Use the shader program for the scene
		glUseProgram(m_PostBloomShaderProgram.uiId);

		/*
		    The following section will draw a quad on the screen
			where the post processing pixel shader shall be executed.
			Try to minimize the area by only drawing where the actual
			post processing should happen, as this is a very costly operation.
		*/
		if (PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen)) {
			DrawAxisAlignedQuad(PVRTVec2(-0.875f, -0.5f), PVRTVec2(0.0625f, 0.25f),
					            PVRTVec2(0.8755f, 0.5f), PVRTVec2(0.9375f, 0.75f));
		}
		else
		{
			DrawAxisAlignedQuad(PVRTVec2(-0.5f, -0.875f), PVRTVec2(0.25f, 0.0625f),
				                PVRTVec2(0.5f, 0.875f), PVRTVec2(0.75f, 0.9375f));
		}

		glDisable(GL_BLEND);
	}

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("Bloom", NULL, ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();


	return true;
}