Esempio n. 1
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 OGLES3AlphaTest::RenderScene()
{
	// Clear color and z buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Set texture
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

	/*
		Draw the left cube using alpha blending
	*/
	glUseProgram(m_TexShaderProgram.uiId);

	glEnable(GL_BLEND);

	// Setup blending for transparency
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// Calculate the model matrix for the left cube
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += .005f;

	mModel.preTranslate(0.6f, 0, 0);

	// Calculate the model view projection (MVP) matrix and pass it to the shader
	PVRTMat4 mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_TexShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Draw left cube
	DrawModel();

	/*
		Draw the right cube using alpha test.
	*/
	glUseProgram(m_DiscardShaderProgram.uiId);

	glDisable(GL_BLEND);

	// Set alpha test to discard fragments with an alpha value of less than 0.2
	glUniform1f(m_DiscardShaderProgram.uiAlphaRefLoc, 0.2f);

	// Calculate the model matrix for the right cube
	mModel.preTranslate(-1.2f, 0, 0);

	// Calculate the model view projection (MVP) matrix and pass it to the shader
	mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_DiscardShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Draw right cube
	DrawModel();

	// Display the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("AlphaTest", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Print3D(10.0f, 10.0f, 1.0f, 0xFFFF00FF, "Alpha Blend");
	m_Print3D.Print3D(60.0f, 10.0f, 1.0f, 0xFFFF00FF, "Alpha Test");
	m_Print3D.Flush();

	return true;
}
Esempio 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 OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2Fog::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Keyboard input (cursor to change fog function)
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_eFogMode = EFogMode((m_eFogMode + eNumFogModes - 1) % eNumFogModes);
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_eFogMode = EFogMode((m_eFogMode + 1) % eNumFogModes);
	}

	// Use the loaded shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

	// Set uniforms
	glUniform1i(m_ShaderProgram.uiFogFuncLoc, m_eFogMode);

	// Rotate and translate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 90;
	mModel.preTranslate(0, 0, 500 * cos(m_fPositionZ) - 450);	
	m_fPositionZ += (2*PVRT_PI)*0.0008f;

	// Feed Projection and Model View matrices to the shaders
	PVRTMat4 mModelView = m_mView * mModel;
	PVRTMat4 mMVP = m_mProjection * mModelView;

	glUniformMatrix4fv(m_ShaderProgram.uiModelViewLoc, 1, GL_FALSE, mModelView.ptr());
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Pass the light direction transformed with the inverse of the ModelView matrix
	// This saves the transformation of the normals per vertex. A simple dot3 between this direction
	// and the un-transformed normal will allow proper smooth shading.
	PVRTVec3 vMsLightDir = (PVRTMat3(mModel).inverse() * PVRTVec3(1, 1, 1)).normalized();
	glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, vMsLightDir.ptr());

	/*
		Now that the model-view matrix is set and the materials ready,
		call another function to actually draw the mesh.
	*/
	DrawMesh(0);

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("Fog", "", ePVRTPrint3DLogoIMG);
	m_Print3D.Print3D(0.3f, 7.5f, 0.75f, PVRTRGBA(255,255,255,255), "Fog Mode: %s", g_FogFunctionList[m_eFogMode]);
	m_Print3D.Flush();

	return true;
}
Esempio n. 3
0
// ---------------------------------------------------------------
void MyPVRDemo::RenderStatue(const PVRTMat4& mxModel, const PVRTMat4& mxCam, const PVRTVec3& vLightPos, const StatueShader* pShader)
	{
	PVRTMat4 mxModelView = mxCam * mxModel;
	PVRTMat4 mxMVP = m_mxProjection * mxModelView;
	PVRTVec3 vLightPosModel = vLightPos;		// Light position in World space
	glUniform3fv(pShader->uiLightPos, 1, vLightPosModel.ptr());
	glUniformMatrix4fv(pShader->uiMVP, 1, GL_FALSE, mxMVP.ptr());
	glUniformMatrix4fv(pShader->uiModelView, 1, GL_FALSE, mxModelView.ptr());
	DrawMesh(enumMODEL_Statue, FLAG_VRT | FLAG_TEX0 | FLAG_NRM | FLAG_TAN);
	}
/*!****************************************************************************
 @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 OGLES2ParallaxBumpMap::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBaseTex);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiNormalMap);
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, m_uiHeightMap);

	// Calculate the model matrix
	PVRTMat4 mModel = PVRTMat4::Scale(g_CubeScale);
	mModel *= PVRTMat4::Translation(g_CubeTranslation);
	mModel *= PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 450;

	// Set the Model View matrix
	PVRTMat4 mMV = m_mView * mModel;
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eModelViewMatrix], 1, GL_FALSE, mMV.ptr());

	// Set the ModelViewIT Matrix
	PVRTMat4 mMIT = mMV.transpose();
	mMIT = mMIT.inverseEx();
	PVRTMat3 mMIT3x3 = PVRTMat3(mMIT);
	glUniformMatrix3fv(m_ShaderProgram.auiLoc[eNormal], 1, GL_FALSE, mMIT3x3.ptr());


	// Set model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eModelViewProj], 1, GL_FALSE, mMVP.ptr());

	// Set light position in eye space
	PVRTVec4 vEyeSpaceLightPos = m_mView * g_LightPos;
	glUniform3fv(m_ShaderProgram.auiLoc[eLightEyeSpacePos], 1, vEyeSpaceLightPos.ptr());

	DrawMesh(0);

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

	return true;
}
/*!****************************************************************************
 @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 OGLES3ComplexLighting::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Keyboard input (cursor to change light)
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_eLightType = ELightType((m_eLightType + eNumLightTypes - 1) % eNumLightTypes);
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_eLightType = ELightType((m_eLightType + 1) % eNumLightTypes);
	}

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

	glUniform1i(m_ShaderProgram.uiLightSelLoc, m_eLightType);

	// Rotate and Translation the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 150;

	// Set model view projection matrix
	PVRTMat4 mModelView = m_mView * mModel;
	PVRTMat4 mMVP = m_mProjection * mModelView;
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Set model view matrix
	glUniformMatrix4fv(m_ShaderProgram.uiModelViewLoc, 1, GL_FALSE, mModelView.ptr());

	// Set model view inverse transpose matrix
	PVRTMat3 mModelViewIT = PVRTMat3(mModelView).inverse().transpose();
	glUniformMatrix3fv(m_ShaderProgram.uiModelViewITLoc, 1, GL_FALSE, mModelViewIT.ptr());

	DrawMesh(0);

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

	return true;
}
Esempio n. 6
0
/*!****************************************************************************
 @Function		DrawSkybox
 @Description	Draws the skybox onto the screen.
******************************************************************************/
void OGLES2Glass::DrawSkybox()
{
	glUseProgram(m_SkyboxProgram.uiId);

	PVRTMat4 mVP = m_mProjection * m_mView;
	PVRTMat4 mInvVP = mVP.inverseEx();

	glUniformMatrix4fv(m_SkyboxProgram.auiLoc[eInvVPMatrix], 1, GL_FALSE, mInvVP.ptr());

	PVRTVec3 vEyePos = m_mView.inverse() * PVRTVec4(0, 0, 0, 1);

	glUniform3fv(m_SkyboxProgram.auiLoc[eEyePos], 1, vEyePos.ptr());

	glBindBuffer(GL_ARRAY_BUFFER, m_uiSquareVbo);

	glEnableVertexAttribArray(VERTEX_ARRAY);
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, m_uiCubeTex);

	glDrawArrays(GL_TRIANGLES, 0, 6);

	glDisableVertexAttribArray(VERTEX_ARRAY);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}
/*!****************************************************************************
 @Function		RenderLoadingScene
 @Input			iFrame
 @Description	Renders an animated loading screen.
******************************************************************************/
void OGLES2MultiThreading::RenderLoadingScene(int iFrame)
{
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
    float fHW      = PVRShellGet(prefWidth) / 2.0f;
    float fHH      = PVRShellGet(prefHeight) / 2.0f;

    PVRTMat4 mxProjection = PVRTMat4::Ortho(-fHW, fHH, fHW, -fHH, -1.0f, 1.0f, PVRTMat4::OGL, bRotate);

    /*
        Clears the color buffer.
    */
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Actually use the created program
    glUseProgram(handles.uiLoadProgram);
    
    // First gets the location of that variable in the shader using its name
    int i32MVPLocation = glGetUniformLocation(handles.uiLoadProgram, "myPMVMatrix");
    int i32ColLocation = glGetUniformLocation(handles.uiLoadProgram, "myCol");

    for(int iCircleIdx = 0; iCircleIdx < c_iNumCircles; ++iCircleIdx)
    {
        int iProg    = iFrame+iCircleIdx*4;
        float fScale = (0.75f + cos(iProg * 0.1f) * 0.25f);
        float fY     = sin(iProg * 0.1f) * 25.0f;
        
        // Then passes the matrix to that variable
        PVRTMat4 mxMVP = mxProjection * PVRTMat4::Translation(-175.0f + iCircleIdx * 50.0f, fY, 0.0f) * PVRTMat4::Scale(fScale,fScale,1.0f);
        glUniformMatrix4fv(i32MVPLocation, 1, GL_FALSE, mxMVP.ptr());
        
        // Pass the colour
        glUniform3f(i32ColLocation, c_vCircleCols[iCircleIdx].x, c_vCircleCols[iCircleIdx].y, c_vCircleCols[iCircleIdx].z);

        // Draw the loading circle
        glBindBuffer(GL_ARRAY_BUFFER, handles.uiLoadVbo);
        glEnableVertexAttribArray(VERTEX_ARRAY);
        glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
        
        // Submit
        glDrawArrays(GL_TRIANGLE_FAN, 0, c_iNumCirclePoints+2);
        
        glDisableVertexAttribArray(VERTEX_ARRAY);
        glBindBuffer(GL_ARRAY_BUFFER, 0);   
    }
            
    float fW;
    loadingText.SetProjection(mxProjection);
    
    ELoadingProgress eProgress = eProgress_Init;
    EnterCriticalSection(&handles.mutex);
        eProgress = g_eProgress;
    LeaveCriticalSection(&handles.mutex);
    
    loadingText.MeasureText(&fW, NULL, 1.0f, c_pszLoadingProgress[eProgress]);
    loadingText.Print3D(-fW*0.5f, -50.0f, 1.0f, 0xFFFFFFFF, c_pszLoadingProgress[eProgress]);
    loadingText.Flush();
}
Esempio n. 8
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 OGLES2FastTnL::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

	/*
		Now that the uniforms are set, call another function to actually draw the mesh.
	*/
	DrawMesh(0);

	// Rotate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += 0.02f;

	// Calculate model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;

	// Feeds Projection Model View matrix to the shaders
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	/*
		The inverse of a rotation matrix is the transposed matrix
		Because of v * M = transpose(M) * v, this means:
		v * R == inverse(R) * v
		So we don't have to actually invert or transpose the matrix
		to transform back from world space to model space
	*/
	PVRTVec3 vMsLightDir = (PVRTVec3(1, 1, 1) * PVRTMat3(mModel)).normalized();
	glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, vMsLightDir.ptr());

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

	return true;
}
Esempio n. 9
0
// ---------------------------------------------------------------
void MyPVRDemo::RenderShadowScene()
	{
	// --- Bind the shadow map FBO
	glBindFramebuffer(GL_FRAMEBUFFER, m_uiShadowMapFBO);
	glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);			// Turn off colour writing

	glUseProgram(m_SimpleShader.uiID);
	// Create MVP using the light's matrix properties
	PVRTMat4 mxMVP = m_mxLightProj * m_mxLightView * PVRTMat4::Identity();
	glUniformMatrix4fv(m_SimpleShader.uiMVP, 1, GL_FALSE, mxMVP.ptr());
	DrawMesh(enumMODEL_Statue, FLAG_VRT);

	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);				// We can turn colour writing back on.

	glBindFramebuffer(GL_FRAMEBUFFER, m_nOrigFBO);		// Done. Use the original framebuffer.
	glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
	}
Esempio n. 10
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 OGLES3Bumpmap::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBaseTex);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiNormalMap);

	// Calculate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 150;

	// Set model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

	// Set light position in model space
	/*
		The inverse of a rotation matrix is the transposed matrix
		Because of v * M = transpose(M) * v, this means:
		v * R == inverse(R) * v
		So we don't have to actually invert or transpose the matrix
		to transform back from world space to model space
	*/
	PVRTVec4 vMsLightPos = PVRTVec4(50, 20, 40, 1) * mModel;
	glUniform3fv(m_ShaderProgram.auiLoc[eLightPos], 1, &vMsLightPos.x);

	DrawMesh(0);

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

	return true;
}
/*!****************************************************************************
 @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 OGLES3CellShading::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use the loaded shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiShadingTex);

	// Calculate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 210;

	// Set model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Set eye position in model space
	PVRTVec4 vMsEyePos = PVRTVec4(0, 0, 125, 1) * mModel;
	glUniform3fv(m_ShaderProgram.uiEyePosLoc, 1, vMsEyePos.ptr());

	// transform directional light from world space to model space
	PVRTVec3 vMsLightDir = PVRTVec3(PVRTVec4(1, 2, 1, 0) * mModel).normalized();
	glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, vMsLightDir.ptr());

	DrawMesh(0);

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

	return true;
}
Esempio n. 12
0
// ---------------------------------------------------------------
void MyPVRDemo::RenderCurch(const PVRTMat4& mxCam)
	{
	PVRTMat4 mxModel = PVRTMat4::Identity();
	PVRTMat4 mxModelView = mxCam * mxModel;
	PVRTMat4 mxTexProj = m_mxLightBias * m_mxLightProj * m_mxLightView * mxCam.inverse();

	// --- Draw the floor reflected first, so we don't have to swap between GPU programs
	glUseProgram(m_ChurchReflShader.uiID);
	// Base map
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_ChurchWalls]);
	// Light map
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_ChurchLightmap]);

	glCullFace(GL_FRONT);
	PVRTMat4 mxReflChurchView = mxCam * PVRTMat4::Scale(1, -1, 1);
	glUniformMatrix4fv(m_ChurchReflShader.uiProjection, 1, GL_FALSE, m_mxProjection.ptr());
	glUniformMatrix4fv(m_ChurchReflShader.uiModelView, 1, GL_FALSE, mxReflChurchView.ptr());	// Reflected ModelView matrix
	DrawMesh(enumMODEL_Church, FLAG_VRT | FLAG_TEX0 | FLAG_TEX1);
	glCullFace(GL_BACK);

	// --- Activate the Church shader which utilises the Shadow Map.
	glUseProgram(m_ChurchShader.uiID);
	
	
	// --- Use the Shadow Map texture in texture unit 1
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiShadowMapTex);
	
	// --- Upload projection matrices
	glUniformMatrix4fv(m_ChurchShader.uiProjection, 1, GL_FALSE, m_mxProjection.ptr());	
	glUniformMatrix4fv(m_ChurchShader.uiTexProjection, 1, GL_FALSE, mxTexProj.ptr());
	glUniform1f(m_ChurchShader.uiAlpha, 1.0f);	// Set no alpha while we draw the walls.

	// --- Draw church walls	 (Textures are already bound)
	// Draw the walls as normal
	glUniformMatrix4fv(m_ChurchShader.uiModelView, 1, GL_FALSE, mxModelView.ptr());		// Standard ModelView matrix
	DrawMesh(enumMODEL_Church, FLAG_VRT | FLAG_TEX0 | FLAG_TEX1);

	// --- Draw floor
	glEnable(GL_BLEND);
	// Base map
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_Floor]);
	// Light map
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_FloorLightmap]);
	
	// Draw the floor
	glUniform1f(m_ChurchShader.uiAlpha, FLOOR_ALPHA);
	glUniformMatrix4fv(m_ChurchShader.uiModelView, 1, GL_FALSE, mxModelView.ptr());		// Standard ModelView matrix
	DrawMesh(enumMODEL_Floor, FLAG_VRT | FLAG_TEX0 | FLAG_TEX1);

	glBindTexture(GL_TEXTURE_2D, 0);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, 0);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, 0);
	glDisable(GL_BLEND);
	}
/*!****************************************************************************
 @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 OGLES3IntroducingPFX::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use the loaded effect
	m_pEffect->Activate();

	/*
		Calculates the frame number to animate in a time-based manner.
		Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	*/
	unsigned long ulTime = PVRShellGetTime();
	unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
	m_ulTimePrev	= ulTime;
	m_fFrame	+= (float)ulDeltaTime * DEMO_FRAME_RATE;

	if (m_fFrame > m_Scene.nNumFrame-1)
		m_fFrame = 0;

	// Sets the scene animation to this frame
	m_Scene.SetFrame(m_fFrame);

	{
		PVRTVec3	vFrom, vTo, vUp;
		VERTTYPE	fFOV;
		vUp.x = 0.0f;
		vUp.y = 1.0f;
		vUp.z = 0.0f;

		// We can get the camera position, target and field of view (fov) with GetCameraPos()
		fFOV = m_Scene.GetCameraPos(vFrom, vTo, 0) * 0.4f;

		/*
			We can build the world view matrix from the camera position, target and an up vector.
			For this we use PVRTMat4LookAtRH().
		*/
		m_mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);

		// Calculates the projection matrix
		bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
		m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);
	}

	// Retrieve the list of required uniforms
	const CPVRTArray<SPVRTPFXUniform>& aUniforms = m_pEffect->GetUniformArray();

	/*
		A scene is composed of nodes. There are 3 types of nodes:
		- MeshNodes :
			references a mesh in the pMesh[].
			These nodes are at the beginning of the pNode[] array.
			And there are nNumMeshNode number of them.
			This way the .pod format can instantiate several times the same mesh
			with different attributes.
		- lights
		- cameras
		To draw a scene, you must go through all the MeshNodes and draw the referenced meshes.
	*/

	for (int i=0; i<(int)m_Scene.nNumMeshNode; i++)
	{
		SPODNode* pNode = &m_Scene.pNode[i];

		// Gets pMesh referenced by the pNode
		SPODMesh* pMesh = &m_Scene.pMesh[pNode->nIdx];

		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);

		// Gets the node model matrix
		PVRTMat4 mWorld;
		mWorld = m_Scene.GetWorldMatrix(*pNode);

		PVRTMat4 mWorldView;
		mWorldView = m_mView * mWorld;

		/*	
			Now we loop over the uniforms requested by the PFX file.
			Using the switch statement allows us to handle all of the required semantics
		*/
		for(unsigned int j = 0; j < aUniforms.GetSize(); ++j)
		{
			switch(aUniforms[j].nSemantic)
			{
			case ePVRTPFX_UsPOSITION:
				{
					glVertexAttribPointer(aUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
					glEnableVertexAttribArray(aUniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsNORMAL:
				{
					glVertexAttribPointer(aUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
					glEnableVertexAttribArray(aUniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsUV:
				{
					glVertexAttribPointer(aUniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
					glEnableVertexAttribArray(aUniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mWVP;

					// Passes the world-view-projection matrix (WVP) to the shader to transform the vertices
					mWVP = m_mProjection * mWorldView;
					glUniformMatrix4fv(aUniforms[j].nLocation, 1, GL_FALSE, mWVP.f);
				}
				break;
			case ePVRTPFX_UsWORLDVIEWIT:
				{
					PVRTMat4 mWorldViewI, mWorldViewIT;

					// Passes the inverse transpose of the world-view matrix to the shader to transform the normals
					mWorldViewI  = mWorldView.inverse();
					mWorldViewIT = mWorldViewI.transpose();

					PVRTMat3 WorldViewIT = PVRTMat3(mWorldViewIT);

					glUniformMatrix3fv(aUniforms[j].nLocation, 1, GL_FALSE, WorldViewIT.f);
				}
				break;
			case ePVRTPFX_UsLIGHTDIREYE:
				{
					// Reads the light direction from the scene.
					PVRTVec4 vLightDirection;
					PVRTVec3 vPos;
					vLightDirection = m_Scene.GetLightDirection(0);

					vLightDirection.x = -vLightDirection.x;
					vLightDirection.y = -vLightDirection.y;
					vLightDirection.z = -vLightDirection.z;

					/*
						Sets the w component to 0, so when passing it to glLight(), it is
						considered as a directional light (as opposed to a spot light).
					*/
					vLightDirection.w = 0;

					// Passes the light direction in eye space to the shader
					PVRTVec4 vLightDirectionEyeSpace;
					vLightDirectionEyeSpace = m_mView * vLightDirection;

					glUniform3f(aUniforms[j].nLocation, vLightDirectionEyeSpace.x, vLightDirectionEyeSpace.y, vLightDirectionEyeSpace.z);
				}
				break;
			case ePVRTPFX_UsTEXTURE:
				{
					// Set the sampler variable to the texture unit
					glUniform1i(aUniforms[j].nLocation, aUniforms[j].nIdx);
				}
				break;
			case eUsMYCUSTOMSCALE:
				{
					PVRTMat4 mxScale = PVRTMat4::Identity();
					glUniformMatrix4fv(aUniforms[j].nLocation, 1, GL_FALSE, mxScale.ptr());
				}
				break;
			}
		}

		/*
			Now that the model-view matrix is set and the materials ready,
			call another function to actually draw the mesh.
		*/
		DrawMesh(pMesh);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		/*
			Now disable all of the enabled attribute arrays that the PFX requested.
		*/
		for(unsigned int j = 0; j < aUniforms.GetSize(); ++j)
		{
			switch(aUniforms[j].nSemantic)
			{
			case ePVRTPFX_UsPOSITION:
			case ePVRTPFX_UsNORMAL:
			case ePVRTPFX_UsUV:
				{
					glDisableVertexAttribArray(aUniforms[j].nLocation);
				}
				break;
			}
		}
	}

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

	return true;
}
/*!****************************************************************************
 @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 OGLES3Skinning::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);
	glActiveTexture(GL_TEXTURE0);

	/*
		Calculates the frame number to animate in a time-based manner.
		Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	*/
	unsigned long iTime = PVRShellGetTime();

	if(iTime > m_iTimePrev)
	{
		float fDelta = (float) (iTime - m_iTimePrev);
		m_fFrame += fDelta * g_fDemoFrameRate;

		// Modify the transformation matrix if it is needed
		bool bRebuildTransformation = false;

		if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
		{
			m_fAngle -= 0.03f;

			if(m_fAngle < PVRT_TWO_PIf)
				m_fAngle += PVRT_TWO_PIf;

			bRebuildTransformation = true;
		}

		if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
		{
			m_fAngle += 0.03f;

			if(m_fAngle > PVRT_TWO_PIf)
				m_fAngle -= PVRT_TWO_PIf;

			bRebuildTransformation = true;
		}

		if(PVRShellIsKeyPressed(PVRShellKeyNameUP))
		{
			m_fDistance -= 10.0f;

			if(m_fDistance < -500.0f)
				m_fDistance = -500.0f;

			bRebuildTransformation = true;
		}

		if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
		{
			m_fDistance += 10.0f;

			if(m_fDistance > 200.0f)
				m_fDistance = 200.0f;

			bRebuildTransformation = true;
		}

		if(bRebuildTransformation)
			m_Transform = PVRTMat4::Translation(0,0, m_fDistance) * PVRTMat4::RotationY(m_fAngle);

	}

	m_iTimePrev	= iTime;

	if(m_fFrame > m_Scene.nNumFrame - 1)
		m_fFrame = 0;

	// Set the scene animation to the current frame
	m_Scene.SetFrame(m_fFrame);

	/*
		Set up camera
	*/
	PVRTVec3	vFrom, vTo, vUp(0, 1, 0);
	PVRTMat4 mView, mProjection;
	float fFOV;

	// We can get the camera position, target and field of view (fov) with GetCameraPos()
	fFOV = m_Scene.GetCamera(vFrom, vTo, vUp, 0);

	/*
		We can build the model view matrix from the camera position, target and an up vector.
		For this we use PVRTMat4::LookAtRH().
	*/
	mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);

	// Calculate the projection matrix
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	mProjection = PVRTMat4::PerspectiveFovRH(fFOV,  (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate);

	// Read the light direction from the scene
	PVRTVec4 vLightDirWorld = PVRTVec4( 0, 0, 0, 0 );
	vLightDirWorld = m_Scene.GetLightDirection(0);
	glUniform3fv(m_ShaderProgram.auiLoc[eLightDirWorld], 1, &vLightDirWorld.x);

	// Set up the View * Projection Matrix
	PVRTMat4 mViewProjection;

	mViewProjection = mProjection * mView;
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eViewProj], 1, GL_FALSE, mViewProjection.ptr());

	/*
		A scene is composed of nodes. There are 3 types of nodes:
		- MeshNodes :
			references a mesh in the pMesh[].
			These nodes are at the beginning of the pNode[] array.
			And there are nNumMeshNode number of them.
			This way the .pod format can instantiate several times the same mesh
			with different attributes.
		- lights
		- cameras
		To draw a scene, you must go through all the MeshNodes and draw the referenced meshes.
	*/
	for (unsigned int i32NodeIndex = 0; i32NodeIndex < m_Scene.nNumMeshNode; ++i32NodeIndex)
	{
		SPODNode& Node = m_Scene.pNode[i32NodeIndex];

		// Get the node model matrix
		PVRTMat4 mWorld;
		mWorld = m_Scene.GetWorldMatrix(Node);

		// Set up shader uniforms
		PVRTMat4 mModelViewProj;
		mModelViewProj = mViewProjection * mWorld;
		glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mModelViewProj.ptr());

		PVRTVec4 vLightDirModel;
		vLightDirModel = mWorld.inverse() * vLightDirWorld;
		glUniform3fv(m_ShaderProgram.auiLoc[eLightDirModel], 1, &vLightDirModel.x);

		// Loads the correct texture using our texture lookup table
		if(Node.nIdxMaterial == -1)
			glBindTexture(GL_TEXTURE_2D, 0); // It has no pMaterial defined. Use blank texture (0)
		else
			glBindTexture(GL_TEXTURE_2D, m_puiTextures[Node.nIdxMaterial]);

		DrawMesh(i32NodeIndex);
	}

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

	return true;
}
/*!****************************************************************************
 @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 OGLESIntroducingPVRTools::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Binds the loaded texture
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

	// Use the loaded shader program
	glUseProgram(m_ShaderProgram.uiId);

	/*
		Creates the Model View Projection (MVP) matrix using the PVRTMat4 class from the tools.
		The tools contain a complete set of functions to operate on 4x4 matrices.
	*/
	PVRTMat4 mMVP = PVRTMat4::Identity();

	if(PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen)) // If the screen is rotated
		mMVP = PVRTMat4::RotationZ(-1.57f);

	/*
		Pass this matrix to the shader.
		The .m field of a PVRTMat4 contains the array of float used to
		communicate with OpenGL ES.
	*/
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

	/*
		Draw a triangle.
		Please refer to the training course IntroducingPVRShell for a detailed explanation.
	*/

	// Bind the VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);

	// Pass the vertex data
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);

	// Pass the texture coordinates data
	glEnableVertexAttribArray(TEXCOORD_ARRAY);
	glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (sizeof(GLfloat) * 3) /* Uvs start after the position */);

	// Draws a non-indexed triangle array
	glDrawArrays(GL_TRIANGLES, 0, 3);

	/*
		Display some text.
		Print3D() function allows to draw text anywhere on the screen using any color.
		Param 1: Position of the text along X (from 0 to 100 scale independent)
		Param 2: Position of the text along Y (from 0 to 100 scale independent)
		Param 3: Scale of the text
		Param 4: Colour of the text (0xAABBGGRR format)
		Param 5: Formated string (uses the same syntax as printf)
	*/
	m_Print3D.Print3D(8.0f, 30.0f, 1.0f, 0xFFAA4040, "example");

	/*
		DisplayDefaultTitle() writes a title and description text on the top left of the screen.
		It can also display the PVR logo (ePVRTPrint3DLogoPVR), the IMG logo (ePVRTPrint3DLogoIMG) or both (ePVRTPrint3DLogoPVR | ePVRTPrint3DLogoIMG).
		Set this last parameter to NULL not to display the logos.
	*/
	m_Print3D.DisplayDefaultTitle("IntroducingPVRTools", "Description", ePVRTPrint3DLogoIMG);

	// Tells Print3D to do all the pending text rendering now
	m_Print3D.Flush();

	return true;
}
/*!****************************************************************************
 @Function		RenderCubeScene
 @Input			iFrame
 @Description	Renders the pre-loaded scene.
******************************************************************************/
void OGLES2MultiThreading::RenderCubeScene(int iFrame)
{
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
    int  iW      = PVRShellGet(prefWidth);
    int  iH      = PVRShellGet(prefHeight);

    PVRTMat4 mxProjection = PVRTMat4::PerspectiveFovRH(0.7f, (float)iW / (float)iH, 1.0f, 1000.0f, PVRTMat4::OGL, bRotate);
    PVRTMat4 mxView       = PVRTMat4::Translation(0.0f, 0.0f, -200.0f);
    PVRTMat4 mxModel      = PVRTMat4::RotationX(-0.5f) * PVRTMat4::RotationY(iFrame * 0.016f) * PVRTMat4::Scale(30.0f, 30.0f, 30.0f);
    
    PVRTMat4 mxMVP        = mxProjection * mxView * mxModel;
    
    PVRTVec4 vLightDir    = PVRTVec4(0.0f, 0.3f, 1.0f, 0.0f) * mxModel;

    // Actually use the created program
    glUseProgram(handles.uiProgramObject);

    // Sets the clear color.
    // The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0
    glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue
    
    glBindTexture(GL_TEXTURE_2D, handles.uiTexture);
    
    // Bind the VBO
    glBindBuffer(GL_ARRAY_BUFFER, handles.uiVbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.uiIndexVbo);

    /*
        Clears the color buffer and depth buffer
    */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    /*
        Bind the projection model view matrix (PMVMatrix) to
        the associated uniform variable in the shader
    */

    // First gets the location of that variable in the shader using its name
    int i32MVPLocation  = glGetUniformLocation(handles.uiProgramObject, "myPMVMatrix");
    int i32LDLocation   = glGetUniformLocation(handles.uiProgramObject, "vLightDir");
    int i32TexLocation  = glGetUniformLocation(handles.uiProgramObject, "sTexture");

    // Then passes the matrix to that variable
    glUniformMatrix4fv( i32MVPLocation, 1, GL_FALSE, mxMVP.ptr());
    
    // Pass light direction
    glUniform3fv( i32LDLocation, 1, vLightDir.ptr());
    
    // Set texture location
    glUniform1i( i32TexLocation, 0);

    /*
        Enable the custom vertex attribute at index VERTEX_ARRAY.
        We previously binded that index to the variable in our shader "vec4 MyVertex;"
     */
    glEnableVertexAttribArray(VERTEX_ARRAY);
    glEnableVertexAttribArray(NORMAL_ARRAY);
    glEnableVertexAttribArray(UV_ARRAY);

    // Sets the vertex data to this attribute index
    glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
    glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));
    glVertexAttribPointer(UV_ARRAY,     2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6*sizeof(GLfloat)));

    /*
        Draws a non-indexed triangle array from the pointers previously given.
        This function allows the use of other primitive types : triangle strips, lines, ...
        For indexed geometry, use the function glDrawElements() with an index list.
    */
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
    
    // Disable states
    glDisableVertexAttribArray(VERTEX_ARRAY);
    glDisableVertexAttribArray(NORMAL_ARRAY);
    glDisableVertexAttribArray(UV_ARRAY);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    
    glBindTexture(GL_TEXTURE_2D, 0);
}
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occured
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES2LightMap::InitView()
{
	CPVRTString ErrorStr;

	/*
		Initialize VBO data
	*/
	m_Models[0].LoadVbos();
	m_Models[1].LoadVbos();

	/*
		Load textures
	*/
	if (!LoadTextures(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	// Clamp the shadow texture to edge (not repeat).
	glBindTexture(GL_TEXTURE_2D, m_uiShadowTex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	/*
		Load and compile the shaders & link programs
	*/
	if (!LoadShaders(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	// Set the sampler2D uniforms to corresponding texture units
	glUniform1i(glGetUniformLocation(m_ShaderProgram.uiId, "sBasetex"), 0);
	glUniform1i(glGetUniformLocation(m_ShaderProgram.uiId, "sReflect"), 1);
	glUniform1i(glGetUniformLocation(m_ShaderProgram.uiId, "sShadow"), 2);

	// Is the scene rotated?
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	/*
		Initialize Print3D
	*/
	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}

	/*
		Calculate the projection and view matrices
	*/
	m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI/6, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);

	m_mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 150), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0));

	// Defines the shadow matrix and stores it, shadow matrix for shadow texture mapping
	PVRTVec3 vLightFrom = PVRTVec3( 85, -85, 100);
	PVRTVec3 vLightTo = PVRTVec3(0, 0, -25);
	PVRTVec3 vLightUp = PVRTVec3(0, 1, 0);

	m_mShadowViewProj = PVRTMat4::LookAtRH(vLightFrom, vLightTo, vLightUp);

	// Project the shadow from a point (near and far clipping plane are not important here)
	PVRTMat4 mShadowProj;
	mShadowProj = PVRTMat4::PerspectiveFovRH(PVRT_PI/6, 1, 1, 2, PVRTMat4::OGL);

	m_mShadowViewProj = mShadowProj * m_mShadowViewProj;
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eShadowProj], 1, GL_FALSE, m_mShadowViewProj.ptr());

	/*
		Set OpenGL ES render states needed for this training course
	*/
	// Enable backface culling and depth test
	glCullFace(GL_BACK);
	glEnable(GL_CULL_FACE);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	// Use a nice bright blue as clear colour
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	return true;
}
/*!****************************************************************************
 @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 OGLES2ChameleonMan::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_SkinnedShaderProgram.uiId);

	if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
	{
		m_bEnableDOT3 = !m_bEnableDOT3;
		glUniform1i(m_SkinnedShaderProgram.auiLoc[ebUseDot3], m_bEnableDOT3);
	}

	/*
		Calculates the frame number to animate in a time-based manner.
		Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	*/
	unsigned long iTime = PVRShellGetTime();

	if(iTime > m_iTimePrev)
	{
		float fDelta = (float) (iTime - m_iTimePrev);
		m_fFrame += fDelta * g_fDemoFrameRate;

		// Increment the counters to make sure our animation works
		m_fLightPos	+= fDelta * 0.0034f;
		m_fWallPos	+= fDelta * 0.00027f;
		m_fBackgroundPos += fDelta * -0.000027f;

		// Wrap the Animation back to the Start
		if(m_fLightPos >= PVRT_TWO_PI)
			m_fLightPos -= PVRT_TWO_PI;

		if(m_fWallPos >= PVRT_TWO_PI)
			m_fWallPos -= PVRT_TWO_PI;

		if(m_fBackgroundPos <= 0)
			m_fBackgroundPos += 1.0f;

		if(m_fFrame > m_Scene.nNumFrame - 1)
			m_fFrame = 0;
	}

	m_iTimePrev	= iTime;

	// Set the scene animation to the current frame
	m_Scene.SetFrame(m_fFrame);

	// Set up camera
	PVRTVec3	vFrom, vTo, vUp(0.0f, 1.0f, 0.0f);
	PVRTMat4 mView, mProjection;
	PVRTVec3	LightPos;
	float fFOV;
	int i;

	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	// Get the camera position, target and field of view (fov)
	if(m_Scene.pCamera[0].nIdxTarget != -1) // Does the camera have a target?
		fFOV = m_Scene.GetCameraPos( vFrom, vTo, 0); // vTo is taken from the target node
	else
		fFOV = m_Scene.GetCamera( vFrom, vTo, vUp, 0); // vTo is calculated from the rotation

	fFOV *= bRotate ? (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight) : (float)PVRShellGet(prefHeight)/(float)PVRShellGet(prefWidth);

	/*
		We can build the model view matrix from the camera position, target and an up vector.
		For this we use PVRTMat4::LookAtRH().
	*/
	mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);

	// Calculate the projection matrix
	mProjection = PVRTMat4::PerspectiveFovRH(fFOV,  (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate);

	// Update Light Position and related VGP Program constant
	LightPos.x = 200.0f;
	LightPos.y = 350.0f;
	LightPos.z = 200.0f * PVRTABS(sin((PVRT_PI / 4.0f) + m_fLightPos));

	glUniform3fv(m_SkinnedShaderProgram.auiLoc[eLightPos], 1, LightPos.ptr());

	// Set up the View * Projection Matrix
	PVRTMat4 mViewProjection;

	mViewProjection = mProjection * mView;
	glUniformMatrix4fv(m_SkinnedShaderProgram.auiLoc[eViewProj], 1, GL_FALSE, mViewProjection.ptr());

	// Enable the vertex attribute arrays
	for(i = 0; i < eNumAttribs; ++i) glEnableVertexAttribArray(i);

	// Draw skinned meshes
	for(unsigned int i32NodeIndex = 0; i32NodeIndex < 3; ++i32NodeIndex)
	{
		// Bind correct texture
		switch(i32NodeIndex)
		{
			case eBody:
				glActiveTexture(GL_TEXTURE1);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexHeadNormalMap);
				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexHeadBody);
				break;
			case eLegs:
				glActiveTexture(GL_TEXTURE1);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexLegsNormalMap);
				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexLegs);
				break;
			default:
				glActiveTexture(GL_TEXTURE1);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexBeltNormalMap);
				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexBelt);
				break;
		}

		DrawSkinnedMesh(i32NodeIndex);
	}

	// Safely disable the vertex attribute arrays
	for(i = 0; i < eNumAttribs; ++i) glDisableVertexAttribArray(i);

	// Draw non-skinned meshes
	glUseProgram(m_DefaultShaderProgram.uiId);

	// Enable the vertex attribute arrays
	for(i = 0; i < eNumDefaultAttribs; ++i) glEnableVertexAttribArray(i);

	for(unsigned int i32NodeIndex = 3; i32NodeIndex < m_Scene.nNumMeshNode; ++i32NodeIndex)
	{
		SPODNode& Node = m_Scene.pNode[i32NodeIndex];
		SPODMesh& Mesh = m_Scene.pMesh[Node.nIdx];

		// bind the VBO for the mesh
		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[Node.nIdx]);

		// bind the index buffer, won't hurt if the handle is 0
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[Node.nIdx]);

		// Get the node model matrix
		PVRTMat4 mWorld;
		mWorld = m_Scene.GetWorldMatrix(Node);

		// Setup the appropriate texture and transformation (if needed)
		switch(i32NodeIndex)
		{
			case eWall:
				glBindTexture(GL_TEXTURE_2D, m_ui32TexWall);

				// Rotate the wall mesh which is circular
				mWorld *= PVRTMat4::RotationY(m_fWallPos);

				glUniform1f(m_DefaultShaderProgram.auiLoc[eDefaultUOffset], 0);

				break;
			case eBackground:
				glBindTexture(GL_TEXTURE_2D, m_ui32TexSkyLine);

				glUniform1f(m_DefaultShaderProgram.auiLoc[eDefaultUOffset], m_fBackgroundPos);
				break;
			case eLights:
				{
					glBindTexture(GL_TEXTURE_2D, m_ui32TexLamp);

					PVRTMat4 mWallWorld = m_Scene.GetWorldMatrix(m_Scene.pNode[eWall]);
					mWorld = mWallWorld * PVRTMat4::RotationY(m_fWallPos) * mWallWorld.inverse() * mWorld;

					glUniform1f(m_DefaultShaderProgram.auiLoc[eDefaultUOffset], 0);
				}
				break;
			default:
			break;
		};

		// Set up shader uniforms
		PVRTMat4 mModelViewProj;
		mModelViewProj = mViewProjection * mWorld;
		glUniformMatrix4fv(m_DefaultShaderProgram.auiLoc[eDefaultMVPMatrix], 1, GL_FALSE, mModelViewProj.ptr());

		// Set the vertex attribute offsets
		glVertexAttribPointer(DEFAULT_VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sVertex.nStride,  Mesh.sVertex.pData);
		glVertexAttribPointer(DEFAULT_TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, Mesh.psUVW[0].nStride, Mesh.psUVW[0].pData);

		// Indexed Triangle list
		glDrawElements(GL_TRIANGLES, Mesh.nNumFaces*3, GL_UNSIGNED_SHORT, 0);
	}

	// Safely disable the vertex attribute arrays
	for(i = 0; i < eNumAttribs; ++i) glDisableVertexAttribArray(i);

	// unbind the VBOs
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// Display the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	const char * pDescription;

	if(m_bEnableDOT3)
		pDescription = "Skinning with DOT3 Per Pixel Lighting";
	else
		pDescription = "Skinning with Vertex Lighting";

	m_Print3D.DisplayDefaultTitle("Chameleon Man", pDescription, ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
/*!****************************************************************************
 @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 OGLES2LightMap::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBaseTex);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiReflectTex);
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, m_uiShadowTex);

	// draw two models, mask and plane
	for (int i = 0; i < eNumModels; ++i)
	{
		// rotate and translate the model matrix
		PVRTMat4 mModel;

		if (i == eMask)
		{
			PVRTMat4 mRotX, mRotY;
			mRotX = PVRTMat4::RotationX(m_fAngleX);
			m_fAngleX += PVRT_PI / 300;
			mRotY = PVRTMat4::RotationY(m_fAngleY);
			m_fAngleY += PVRT_PI / 250;

			mModel = mRotY * mRotX;
		}
		else
		{
			mModel = PVRTMat4::Translation(0.0, 0.0, -25);
		}

		// Set model view projection matrix
		PVRTMat4 mModelView, mMVP;
		mModelView = m_mView * mModel;
		mMVP = m_mProjection * mModelView;
		glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

		// Set shadow projection matrix
		PVRTMat4 mShadowProj;
		mShadowProj = m_mShadowViewProj * mModel;
		glUniformMatrix4fv(m_ShaderProgram.auiLoc[eShadowProj], 1, GL_FALSE, mShadowProj.ptr());

		// Set model world matrix
		PVRTMat3 fModelWorld = PVRTMat3(mModel);

		glUniformMatrix3fv(m_ShaderProgram.auiLoc[eModelWorld], 1, GL_FALSE, fModelWorld.ptr());

		// Set light position in model space
		PVRTVec4 vLightDirModel;
		vLightDirModel =  mModel.inverse() *  PVRTVec4( 1, 1, 1, 0 );

		glUniform3fv(m_ShaderProgram.auiLoc[eLightDirModel], 1, &vLightDirModel.x);

		// Set eye position in model space
		PVRTVec4 vEyePosModel;
		vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1);

		glUniform3fv(m_ShaderProgram.auiLoc[eEyePosModel], 1, &vEyePosModel.x);

		m_Models[i].DrawMesh(0);
	}

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

	return true;
}
/*!****************************************************************************
 @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 OGLES2AnisotropicLighting::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Keyboard input (cursor to change render mode)
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_eRenderMode = ERenderMode((m_eRenderMode + eNumRenderModes - 1) % eNumRenderModes);
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_eRenderMode = ERenderMode((m_eRenderMode + 1) % eNumRenderModes);
	}

	// Rotate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += 0.02f;

	// Calculate model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;

	if (m_eRenderMode == eTexLookup)
	{
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiTexture);

		glUseProgram(m_FastShader.uiId);

		glUniformMatrix4fv(m_FastShader.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

		/*
			The inverse of a rotation matrix is the transposed matrix
			Because of v * M = transpose(M) * v, this means:
			v * R == inverse(R) * v
			So we don't have to actually invert or transpose the matrix
			to transform back from world space to model space
		*/
		PVRTVec3 vMsEyePos = PVRTVec3(PVRTVec4(0, 0, 150, 1) * mModel);
		glUniform3fv(m_FastShader.uiMsEyePosLoc, 1, vMsEyePos.ptr());

		PVRTVec3 vMsLightDir = PVRTVec3(PVRTVec4(1, 1, 1, 1) * mModel).normalized();
		glUniform3fv(m_FastShader.uiMsLightDirLoc, 1, vMsLightDir.ptr());
	}
	else
	{
		glUseProgram(m_SlowShader.uiId);

		glUniformMatrix4fv(m_SlowShader.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

		PVRTVec3 vMsEyeDir = PVRTVec3(PVRTVec4(0, 0, 150, 1) * mModel).normalized();
		glUniform3fv(m_SlowShader.uiMsEyeDirLoc, 1, vMsEyeDir.ptr());

		PVRTVec3 vMsLightDir = PVRTVec3(PVRTVec4(1, 1, 1, 1) * mModel).normalized();
		glUniform3fv(m_SlowShader.uiMsLightDirLoc, 1, vMsLightDir.ptr());
	}

	/*
		Now that the uniforms are set, call another function to actually draw the mesh.
	*/
	DrawMesh(0);

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("AnisotropicLighting", "", ePVRTPrint3DLogoIMG);
	m_Print3D.Print3D(0.3f, 7.5f, 0.75f, PVRTRGBA(255,255,255,255), c_aszRenderModes[m_eRenderMode]);
	m_Print3D.Flush();

	return true;
}
Esempio n. 21
0
bool OGLES2RenderToTexture::DrawScreen()
{
	/*
		We're going to do the following steps to create the effect. Texture 1 refers to the texture
		attached to the first FBO. Texture 2 refers to the texture attached to the second FBO.

		Frame 0

			1.	We bind the second frame buffer object so we can do things to it.
			2.	We draw two quads with Texture 1 applied.
			3.	We draw the trunk.
			4.	We make the back buffer current.
			5.	We draw 6 quads with Texture 2 applied.

		Frame 1

			6.	We bind the first frame buffer object so we can do things to it.
			7.	We draw two quads with Texture 2 applied. Texture 2 still contains
				the image from the last frame.
			8.	We draw the trunk.
			9.	We make the back buffer current.
			10.	We draw 6 quads with Texture 1 applied.

		Frame 2

			11.	We bind the second frame buffer object so we can do things to it.
			12.	We draw two quads with Texture 1 applied. Texture 1 still contains
				the image from the last frame.
			13.	We draw the trunk.
			14.	We make the back buffer current.
			15.	We draw 6 quads with Texture 2 applied.

			16.	We repeat steps 6 through to 16 for consecutive frames.
	*/

	/* Use the program created with the fragment and vertex shaders. */
	glUseProgram(m_ShaderProgram.uiId);
	glBindBuffer(GL_ARRAY_BUFFER, m_uiVbo);
	glDisable(GL_CULL_FACE);

	glEnableVertexAttribArray(VERTEX_ARRAY);
	glEnableVertexAttribArray(TEXCOORD_ARRAY);
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
	glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));

	/*
		Draw the fractal onto the current m_ui32Texture
	*/
	if(!RenderFractal())
		return false;

	PVRTMat4 fMatrix;
	fMatrix = PVRTMat4::Identity();

	/*
		Bind the projection model view matrix (PMVMatrix) to
		the associated uniform variable in the shader
	*/
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, fMatrix.ptr());

	// Clear the color and depth buffer
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	/*
		Set the viewport ot fill the screen.
	*/
	glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

	/*	Set up the matrix we are going to use to rotate and scale the 6 quads.	*/
	PVRTMat4 fRotZ;
	fMatrix = PVRTMat4::Scale(0.8f *(float)PVRShellGet(prefHeight) / (float)PVRShellGet(prefWidth), 0.8f, 0.8f);
	fRotZ = PVRTMat4::RotationZ(1.047f);

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

	/* Bind the texture that we have rendered too.*/
	glBindTexture(GL_TEXTURE_2D, m_auiTexture[m_i32CurrentFbo]);

	/* Draws 6 rotated quads */
	for(int i = 0; i < 6; ++i)
	{
		// Set the transformationh matrix
		glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, fMatrix.ptr());

		// Draw the quad
		glDrawArrays(GL_TRIANGLE_STRIP, 5, 4);

		// Rotate the object by another 60 degrees.
		fMatrix = fMatrix * fRotZ;
	}

	// Swap the FBOs
	m_i32CurrentFbo = 1 - m_i32CurrentFbo;

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glDisableVertexAttribArray(VERTEX_ARRAY);
	glDisableVertexAttribArray(TEXCOORD_ARRAY);

	return true;
}