/*!**************************************************************************** @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 OGLES2Glass::RenderScene() { if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) m_iEffect -= 1; if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) m_iEffect += 1; m_iEffect = (m_iEffect + g_iNumEffects) % g_iNumEffects; UpdateScene(); DrawIntoParaboloids(PVRTVec3(0, 0, 0)); // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw the ball DrawBall(); // Draw the balloons DrawBalloons(&m_DefaultProgram, m_mProjection, m_mView, m_mModels, 2); // Draw the skybox DrawSkybox(); // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("Glass", g_aszEffectNames[m_iEffect], 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 OGLES3ShadowMapping::RenderScene() { Update(); // Bind the frame buffer object glBindFramebuffer(GL_FRAMEBUFFER, m_uiFrameBufferObject); // Clear the screen and depth buffer so we can render from the light's view glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); // Set the current viewport to our texture size but leave a one pixel margin. // As we are clamping to the edge of the texture when shadow mapping, no object // should be rendered to the border, otherwise stretching artefacts might occur // outside of the coverage of the shadow map. glViewport(1, 1, m_ui32ShadowMapSize-2, m_ui32ShadowMapSize-2); // Since we don't care about colour when rendering the depth values to // the shadow-map texture, we disable color writing to increase speed. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Cull the front faces, so that only the backfaces are rendered into the shadowmap glCullFace(GL_FRONT); // Draw everything that we would like to cast a shadow RenderSceneWithEffect(INDEX_RENDERSHADOW, m_mLightProjection, m_mLightView); // Set the culling mode for the normal rendering glCullFace(GL_BACK); // Turn colour buffer writes back on again glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Restore our normal viewport size to our screen width and height glViewport(0, 0,PVRShellGet(prefWidth),PVRShellGet(prefHeight)); //Invalidate the framebuffer attachments we don't need to avoid unnecessary copying to system memory const GLenum attachment = GL_COLOR_ATTACHMENT0; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachment); glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo); // Clear the colour and depth buffers, we are now going to render the scene again from scratch glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Load the shadow shader. This shader requires additional parameters; texProjMatrix for the depth buffer // look up and the light direction for diffuse light (the effect is a lot nicer with the addition of the // diffuse light). glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_uiShadowMapTexture); glActiveTexture(GL_TEXTURE0); RenderSceneWithEffect(INDEX_RENDERSCENE, m_mProjection, m_mView); m_Print3D.DisplayDefaultTitle("ShadowMap", "", ePVRTPrint3DSDKLogo); m_Print3D.Print3D(5.0f, 90.0f, 1.0f, 0xFFFFFFFF, "Bias: %f", m_fBias); 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 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; }
/*!**************************************************************************** @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; }
/*!**************************************************************************** @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 OGLES3TextureStreaming::RenderScene() { // Clears the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Time based animation and locks the app to 60 FPS. // 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 * (60.0f/1000.0f); m_fBandScroll += (float)ulDeltaTime * (60.0f/1000.0f) * c_fBandScrollSpeed; if(m_fFrame > m_Scene.nNumFrame - 1) m_fFrame = 0.0f; if(m_fBandScroll > 1.0f) m_fBandScroll = -c_fBandWidth; bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); m_Scene.SetFrame(m_fFrame); // Setup the main camera PVRTVec3 vFrom, vTo(0.0f), vUp(0.0f, 1.0f, 0.0f); float fFOV; // Camera nodes are after the mesh and light nodes in the array int i32CamID = m_Scene.pNode[m_Scene.nNumMeshNode + m_Scene.nNumLight + c_ui32Camera].nIdx; // Get the camera position, target and field of view (fov) if(m_Scene.pCamera[i32CamID].nIdxTarget != -1) // Does the camera have a target? fFOV = m_Scene.GetCameraPos( vFrom, vTo, c_ui32Camera); // vTo is taken from the target node else fFOV = m_Scene.GetCamera( vFrom, vTo, vUp, c_ui32Camera); // vTo is calculated from the rotation float fTargetAspect = 960.0f/640.0f; float fAspect = (float)PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight); fFOV *= fTargetAspect / fAspect; PVRTMat4 mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp); PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), c_fCameraNear, c_fCameraFar, PVRTMat4::OGL, bRotate); PVRTMat4 mViewProjection = mProjection * mView; DrawPODScene(mViewProjection); // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("Texture Streaming", c_pszDescription, ePVRTPrint3DSDKLogo); m_Print3D.Flush(); ++m_i32Frame; return true; }
/*!**************************************************************************** @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; }
/*!**************************************************************************** @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 OGLES2MultiThreading::RenderScene() { // Render the loading screen while we wait for resources to load. if(bLoading) { // Render the animated loading scene. RenderLoadingScene(iFrame++); /* Check if the resources are still being loaded. This is performed by querying EGL to determine if a sync object has been signalled. */ EnterCriticalSection(&handles.mutex); if(handles.eglSync != EGL_NO_SYNC_KHR) { // Perform a non-blocking poll to check if the shared egl sync object has been signalled. EGLint status = eglClientWaitSyncKHR(handles.eglDisplay, handles.eglSync, 0, 0); if(status == EGL_CONDITION_SATISFIED_KHR) { // Destroy the egl sync object as soon as we aware of it's signal status. if(eglDestroySyncKHR(handles.eglDisplay, handles.eglSync) != EGL_TRUE) { PVRShellSet(prefExitMessage, "eglDestroySyncKHR returned unexpected EGL_FALSE.\n"); return false; } bLoading = false; } else if(status == EGL_FALSE) { PVRShellSet(prefExitMessage, "eglClientWaitSyncKHR returned unexpected EGL_FALSE.\n"); return false; } } LeaveCriticalSection(&handles.mutex); } else { glEnable(GL_DEPTH_TEST); // Render the pre-loaded scene RenderCubeScene(iFrame++); glDisable(GL_DEPTH_TEST); } print3D.DisplayDefaultTitle("MultiThreading", "", ePVRTPrint3DSDKLogo); 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 OGLES2ProceduralTextures::RenderScene() { if (!HandleInput()) { return false; } glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_ui32ColourSplineTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_FnTexture); glDisable(GL_CULL_FACE); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glUseProgram(m_auiShaderProgramId[m_uiVisualisation]); const float fIndex = m_uiGenerator / (float)(NUM_GENERATORS - 1); glUniform1f(m_aiColourSplineIndices[m_uiGenerator], fIndex); glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(TEXTURE_ARRAY); // Pass the vertex data GLfloat pfVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f }; glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, pfVertices); // Pass the texture coordinates data GLfloat pfTexCoord[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; glVertexAttribPointer(TEXTURE_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, pfTexCoord); unsigned short indices[] = { 0, 1, 3, 1, 2, 3 }; glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(TEXTURE_ARRAY); glUseProgram(0); m_Print3D.DisplayDefaultTitle("OpenGL ES Compute Shader Procedural Textures", NULL, ePVRTPrint3DSDKLogo); m_Print3D.Print3D(1.0f, 80.0f, 1.0f, 0xFFFFFFFF, "Metric: %s", m_pProceduralTextures->GetModeDescription((eGenerator)m_uiGenerator)); m_Print3D.Print3D(1.0f, 90.0f, 1.0f, 0xFFFFFFFF, "Evaluator: %s", c_szVisualisationsDescriptions[m_uiVisualisation]); m_Print3D.Flush(); return true; }
/*!**************************************************************************** @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; }
/*!**************************************************************************** @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; }
/*!**************************************************************************** @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 OGLES3PerturbedUvs::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_uiReflectTex); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_uiNormalTex); // Rotate and translate the model matrix PVRTMat4 mModel; mModel = PVRTMat4::RotationY(m_fAngleY); m_fAngleY += PVRT_PI / 210; // 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 eye position in model space PVRTVec4 vEyePosModel; vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1); glUniform3fv(m_ShaderProgram.auiLoc[eEyePosModel], 1, &vEyePosModel.x); /* 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("PerturbedUvs", "", 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 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 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 OGLES2Shaders::RenderScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Keyboard input (cursor to change shaders and meshes) if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) { m_nCurrentShader--; if(m_nCurrentShader<0) m_nCurrentShader=(g_numShaders-1); } if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { m_nCurrentShader++; if(m_nCurrentShader>(g_numShaders-1)) m_nCurrentShader=0; } if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN)) { m_nCurrentSurface--; if(m_nCurrentSurface<0) m_nCurrentSurface=(g_numSurfaces-1); ComputeSurface(m_nCurrentSurface); } if (PVRShellIsKeyPressed(PVRShellKeyNameUP)) { m_nCurrentSurface++; if(m_nCurrentSurface>(g_numSurfaces-1)) m_nCurrentSurface=0; ComputeSurface(m_nCurrentSurface); } // Draw the mesh ComputeViewMatrix(); DrawModel(); // Display screen info m_Print3D.DisplayDefaultTitle("Shaders", NULL, ePVRTPrint3DSDKLogo); m_Print3D.Print3D(0.3f, 7.5f, 0.75f, 0xFFFFFFFF, "Shader: %s\nMesh: %s", g_ShaderList[m_nCurrentShader], g_SurfacesList[m_nCurrentSurface]); 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 OGLES2ParticleSystem::RenderScene() { HandleInput(); UpdateParticles(); UpdateFramerateCounter(); float time_delta = PVRShellGetTime() / 10000.0f; PVRTVec3 vFrom = PVRTVec3((float) sin(time_delta) * 50.0f, 30.0f, (float) cos(time_delta) * 50.0f); m_mView = PVRTMat4::LookAtRH(vFrom, PVRTVec3(0.0f, 5.0f, 0.0f), PVRTVec3(0.0f, 1.0f, 0.0f)); m_mViewProjection = m_mProjection * m_mView; // Clear colour and depth buffers glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enables depth testing glEnable(GL_DEPTH_TEST); // Render floor RenderFloor(); for (unsigned int i=0; i < g_cuiNumSpheres; i++) RenderSphere(g_caSpheres[i].aPosition, g_caSpheres[i].fRadius); // Render particles RenderParticles(); // Display info text. char lower_buffer[64]; unsigned int numParticles = m_pParticleSystem->GetNumberOfParticles(); sprintf(lower_buffer, "No. of Particles: %d", numParticles); m_Print3D.DisplayDefaultTitle("Particle System", NULL, ePVRTPrint3DSDKLogo); m_Print3D.Print3D(2.0f, 90.0f, 1.0f, 0xFFFFFFFF, "No. of Particles: %d", numParticles); 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; }
/*!**************************************************************************** @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 OGLES2RenderToTexture::RenderScene() { /* vary the branch angles on the fractal sinusoidally */ m_fAngle = (float)(sin(0.25*PVRT_PIf*(float)(m_ui32Framenum)/256.0f))* 70.0f; /* largeish prime number in the angular frequency here, so the motion's not obviously periodic */ m_fAngle2 = (float)(sin((79.0f/256.0f)*2.0*PVRT_PIf*(float)(m_ui32Framenum)/256.0f))*100.0f + 30.0f; /* Convert the angles to radians. */ m_fAngle *= 0.017453f; m_fAngle2 *= 0.017453f; /* Increase the frame count */ if(PVRShellGetTime() - m_ui32Time > 10) { m_ui32Time = PVRShellGetTime(); m_ui32Framenum += 2; if(m_ui32Framenum > 20000) m_ui32Framenum = 0; } // Disable depth test and culling as we don't need it glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); // Draw the RenderToTexture if(!DrawScreen()) return false; // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("Render to Texture", "Using FBO", ePVRTPrint3DLogoIMG); 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 OGLESParticles::RenderScene() { int i; PVRTMat4 mRotY; // Clear colour and depth buffers myglClearColor(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enables depth testing glEnable(GL_DEPTH_TEST); // Modify per-frame variables controlling the particle mouvements. float fSpeedCtrl = (float) (PVRTFSIN(m_fRot*0.01f)+1.0f)/2.0f; float fStopNo = 0.8f; float fStep = 0.1f; if(fSpeedCtrl > fStopNo) fStep = 0.0f; // Generate particles as needed. if((m_i32NumParticles < (int) g_ui32MaxParticles) && (fSpeedCtrl <= fStopNo)) { int num_to_gen = (int) (RandPositiveFloat()*(g_ui32MaxParticles/100.0)); if(num_to_gen == 0) num_to_gen = 1; for(i = 0; (i < num_to_gen) && (m_i32NumParticles < (int) g_ui32MaxParticles); ++i) SpawnParticle(&m_Particles[m_i32NumParticles++]); } // Build rotation matrix around axis Y. mRotY = PVRTMat4::RotationY(f2vt((m_fRot2*PVRT_PIf)/180.0f)); for(i = 0; i < m_i32NumParticles; ++i) { // Transform particle with rotation matrix m_sParticleVTXPSBuf[i].x = VERTTYPEMUL(mRotY.f[ 0], m_Particles[i].m_fPosition.x) + VERTTYPEMUL(mRotY.f[ 4], m_Particles[i].m_fPosition.y) + VERTTYPEMUL(mRotY.f[ 8], m_Particles[i].m_fPosition.z) + mRotY.f[12]; m_sParticleVTXPSBuf[i].y = VERTTYPEMUL(mRotY.f[ 1], m_Particles[i].m_fPosition.x) + VERTTYPEMUL(mRotY.f[ 5], m_Particles[i].m_fPosition.y) + VERTTYPEMUL(mRotY.f[ 9], m_Particles[i].m_fPosition.z) + mRotY.f[13]; m_sParticleVTXPSBuf[i].z = VERTTYPEMUL(mRotY.f[ 2], m_Particles[i].m_fPosition.x) + VERTTYPEMUL(mRotY.f[ 6], m_Particles[i].m_fPosition.y) + VERTTYPEMUL(mRotY.f[10], m_Particles[i].m_fPosition.z) + mRotY.f[14]; m_sParticleVTXPSBuf[i].fSize = m_Particles[i].m_fSize; m_sNormalColour[i].r = vt2b(m_Particles[i].m_fColour.x); m_sNormalColour[i].g = vt2b(m_Particles[i].m_fColour.y); m_sNormalColour[i].b = vt2b(m_Particles[i].m_fColour.z); m_sNormalColour[i].a = (unsigned char)255; m_sReflectColour[i].r = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.x, g_fFactor)); m_sReflectColour[i].g = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.y, g_fFactor)); m_sReflectColour[i].b = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.z, g_fFactor)); m_sReflectColour[i].a = (unsigned char)255; } glBindBuffer(GL_ARRAY_BUFFER, m_i32VertVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SVtxPointSprite)*m_i32NumParticles, m_sParticleVTXPSBuf,GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_i32ColAVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sNormalColour,GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_i32ColBVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sReflectColour,GL_DYNAMIC_DRAW); // clean up render states glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); // Draw floor. // Save modelview matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); myglRotate(f2vt(-m_fRot), f2vt(0.0f), f2vt(1.0f), f2vt(0.0f)); // setup render states glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); // Set texture and texture environment glBindTexture(GL_TEXTURE_2D, m_ui32FloorTexName); glBlendFunc(GL_ONE, GL_ONE); // Render floor RenderFloor(); // clean up render states glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glPopMatrix(); // Render particles reflections. // set up render states glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDepthFunc(GL_ALWAYS); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); myglTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindTexture(GL_TEXTURE_2D, m_ui32TexName); // Set model view matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); myglScale(f2vt(1.0f), f2vt(-1.0f), f2vt(1.0f)); myglTranslate(f2vt(0.0f), f2vt(0.01f), f2vt(0.0f)); glEnable(GL_POINT_SPRITE_OES); if(((int)(m_i32NumParticles * 0.5f)) > 0) RenderParticle(((int)(m_i32NumParticles*0.5f)),true); glPopMatrix(); // Render particles. // Sets the model view matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); if(m_i32NumParticles > 0) RenderParticle(m_i32NumParticles,false); glPopMatrix(); glDisable(GL_POINT_SPRITE_OES); PVRTVec3 Force = PVRTVec3(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f)); Force.x = f2vt(1000.0f*(float)PVRTFSIN(m_fRot*0.01f)); for(i = 0; i < m_i32NumParticles; ++i) { /* Move the particle. If the particle exceeds its lifetime, create a new one in its place. */ if(m_Particles[i].Step(f2vt(fStep), Force)) SpawnParticle(&m_Particles[i]); } // clean up render states glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); // Increase rotation angles m_fRot += 1; m_fRot2 = m_fRot + 36; // Unbinds the vertex buffer if we are using OpenGL ES 1.1 glBindBuffer(GL_ARRAY_BUFFER, 0); // Display info text. m_Print3D.DisplayDefaultTitle("Particles", "Using point sprites", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }
/*!**************************************************************************** @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 OGLESPVRScopeRemote::RenderScene() { CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); if(m_psSPSCommsData) { // mark every N frames if(!(m_i32FrameCounter % 100)) { char buf[128]; const int nLen = sprintf(buf, "frame %u", m_i32FrameCounter); m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen); } // Check for dirty items m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "dirty", static_cast<unsigned int>(strlen("dirty")), m_i32FrameCounter); { unsigned int nItem, nNewDataLen; const char *pData; while(pplLibraryDirtyGetFirst(m_psSPSCommsData, &nItem, &nNewDataLen, &pData)) { PVRShellOutputDebug("dirty item %u %u 0x%08x\n", nItem, nNewDataLen, pData); switch(nItem) { case 0: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMinThickness = psData->fCurrent; } break; case 1: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMaxVariation = psData->fCurrent; } break; } } } m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "draw", static_cast<unsigned int>(strlen("draw")), m_i32FrameCounter); } // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Loads the projection matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(m_mProjection.f); // Specify the modelview matrix PVRTMat4 mModel; SPODNode& Node = m_Scene.pNode[0]; m_Scene.GetWorldMatrix(mModel, Node); // Rotate and Translate the model matrix m_fAngleY += (2*PVRT_PIf/60)/7; // Set model view projection matrix PVRTMat4 mModelView; mModelView = m_mView * PVRTMat4::RotationY(m_fAngleY) * mModel; glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mModelView.f); /* Load the light direction from the scene if we have one */ // Enables lighting. See BasicTnL for a detailed explanation glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Set light direction PVRTVec4 vLightDirModel; vLightDirModel = mModel.inverse() * PVRTVec4(1, 1, 1, 0); glLightfv(GL_LIGHT0, GL_POSITION, (float*)&vLightDirModel.x); // Enable the vertex position attribute array glEnableClientState(GL_VERTEX_ARRAY); // bind the texture glBindTexture(GL_TEXTURE_2D, m_uiTexture); /* Now that the model-view matrix is set and the materials are ready, call another function to actually draw the mesh. */ DrawMesh(Node.nIdx); // Disable the vertex positions glDisableClientState(GL_VERTEX_ARRAY); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "Print3D", static_cast<unsigned int>(strlen("Print3D")), m_i32FrameCounter); } // Displays the demo name using the tools. For a detailed explanation, see the example IntroducingPVRTools if(m_bCommsError) { m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs\n\nError:\n PVRScopeComms failed\n Is PVRPerfServer connected?", ePVRTPrint3DSDKLogo); m_bCommsError = false; } else m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } // send counters m_anCounterReadings[eCounter] = m_i32FrameCounter; m_anCounterReadings[eCounter10] = m_i32Frame10Counter; if(m_psSPSCommsData) { m_bCommsError |= !pplCountersUpdate(m_psSPSCommsData, m_anCounterReadings); } // update some counters ++m_i32FrameCounter; if(0 == (m_i32FrameCounter / 10) % 10) { m_i32Frame10Counter += 10; } 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 OGLES3IntroducingPOD::RenderScene() { // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use shader program glUseProgram(m_ShaderProgram.uiId); /* 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(); if(m_ulTimePrev > ulTime) m_ulTimePrev = ulTime; unsigned long ulDeltaTime = ulTime - m_ulTimePrev; m_ulTimePrev = ulTime; m_fFrame += (float)ulDeltaTime * g_fDemoFrameRate; if (m_fFrame > m_Scene.nNumFrame - 1) m_fFrame = 0; // Sets the scene animation to this frame m_Scene.SetFrame(m_fFrame); /* Get the direction of the first light from the scene. */ PVRTVec4 vLightDirection; vLightDirection = m_Scene.GetLightDirection(0); // For direction vectors, w should be 0 vLightDirection.w = 0.0f; /* Set up the view and projection matrices from the camera */ PVRTMat4 mView, mProjection; PVRTVec3 vFrom, vTo(0.0f), vUp(0.0f, 1.0f, 0.0f); float fFOV; // Setup the camera // Camera nodes are after the mesh and light nodes in the array int i32CamID = m_Scene.pNode[m_Scene.nNumMeshNode + m_Scene.nNumLight + g_ui32Camera].nIdx; // Get the camera position, target and field of view (fov) if(m_Scene.pCamera[i32CamID].nIdxTarget != -1) // Does the camera have a target? fFOV = m_Scene.GetCameraPos( vFrom, vTo, g_ui32Camera); // vTo is taken from the target node else fFOV = m_Scene.GetCamera( vFrom, vTo, vUp, g_ui32Camera); // vTo is calculated from the rotation // 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); /* 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 i = 0; i < m_Scene.nNumMeshNode; ++i) { SPODNode& Node = m_Scene.pNode[i]; // Get the node model matrix PVRTMat4 mWorld; mWorld = m_Scene.GetWorldMatrix(Node); // Pass the model-view-projection matrix (MVP) to the shader to transform the vertices PVRTMat4 mModelView, mMVP; mModelView = mView * mWorld; mMVP = mProjection * mModelView; glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.f); // Pass the light direction in model space to the shader PVRTVec4 vLightDir; vLightDir = mWorld.inverse() * vLightDirection; PVRTVec3 vLightDirModel = *(PVRTVec3*)&vLightDir; vLightDirModel.normalize(); glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vLightDirModel.x); // Load the correct texture using our texture lookup table GLuint uiTex = 0; if(Node.nIdxMaterial != -1) uiTex = m_puiTextureIDs[Node.nIdxMaterial]; glBindTexture(GL_TEXTURE_2D, uiTex); /* Now that the model-view matrix is set and the materials are ready, call another function to actually draw the mesh. */ DrawMesh(i); } // Display the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("IntroducingPOD", "", 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 OGLES3AlphaBlend::RenderScene() { // Do our clear glClear(GL_COLOR_BUFFER_BIT); // Use the loaded shader program glUseProgram(m_ShaderProgram.uiId); // Draws the background glDisable(GL_BLEND); DrawQuad(-1, -1, +1, +1, m_uiTexBackground); /* Prepares to draw the different blend modes, activate blending. Now we can use glBlendFunc() to specify the blending mode wanted. */ glEnable(GL_BLEND); // Prepares the variables used to divide the screen in NUM_BLEND x NUM_BLEND rectangles float fX1 = -1; float fX2 = +1; float fY1 = -1; float fY2 = +.85f; float fPosX = fX1; float fPosY = fY1; float fMarginX = .25f; float fMarginY = .25f; float fBlockWidth = ((fX2-fX1) - fMarginX * 3.0f) * 0.5f; float fBlockHeight= ((fY2-fY1) - fMarginY * 3.0f) * 0.5f; //Position and draw the first quad (Transparency) fPosY = fY2 - fBlockHeight - fMarginY; fPosX += fMarginX; //Set up the blend function for this quad glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground); //Draw the text for this quad to the screen. m_Print3D.Print3D(18,12, 0.6f, 0xff00ffff, "Transparency"); m_Print3D.Print3D(7,16, 0.6f, 0xff00ffff, "(SRC_ALPHA, 1 - SRC_ALPHA)"); //Position and draw the second quad (Additive) fPosX += fMarginX + fBlockWidth; glBlendFunc(GL_ONE, GL_ONE); DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground); m_Print3D.Print3D(66,12, 0.6f, 0xff00ffff, "Additive"); m_Print3D.Print3D(64,16, 0.6f, 0xff00ffff, "(ONE, ONE)"); //Position and draw the third quad (Modulate) fPosX = fX1 + fMarginX; fPosY -= fMarginY + fBlockHeight; glBlendFunc(GL_DST_COLOR, GL_ZERO); DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground); m_Print3D.Print3D(22,52, 0.6f, 0xff00ffff, "Modulate"); m_Print3D.Print3D(14,56, 0.6f, 0xff00ffff, "(DST_COLOR, ZERO)"); //Position and draw the fourth quad (Modulate X 2) fPosX += fMarginX + fBlockWidth; glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground); m_Print3D.Print3D(64,52, 0.6f, 0xff00ffff, "Modulate X2"); m_Print3D.Print3D(53,56, 0.6f, 0xff00ffff, "(DST_COLOR, SRC_COLOR)"); /* Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools */ m_Print3D.DisplayDefaultTitle("AlphaBlend", "", 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 OGLESEvilSkull::RenderScene() { unsigned int i; float fCurrentfJawRotation, fCurrentfBackRotation; float fFactor, fInvFactor; // Update Skull Weights and Rotations using Animation Info if(m_i32Frame > g_fExprTime) { m_i32Frame = 0; m_i32BaseAnim = m_i32TargetAnim; ++m_i32TargetAnim; if(m_i32TargetAnim > 6) { m_i32TargetAnim = 0; } } fFactor = float(m_i32Frame) / g_fExprTime; fInvFactor = 1.0f - fFactor; m_fSkullWeights[0] = (m_fExprTable[0][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[0][m_i32TargetAnim] * fFactor); m_fSkullWeights[1] = (m_fExprTable[1][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[1][m_i32TargetAnim] * fFactor); m_fSkullWeights[2] = (m_fExprTable[2][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[2][m_i32TargetAnim] * fFactor); m_fSkullWeights[3] = (m_fExprTable[3][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[3][m_i32TargetAnim] * fFactor); fCurrentfJawRotation = m_fJawRotation[m_i32BaseAnim] * fInvFactor + (m_fJawRotation[m_i32TargetAnim] * fFactor); fCurrentfBackRotation = m_fBackRotation[m_i32BaseAnim] * fInvFactor + (m_fBackRotation[m_i32TargetAnim] * fFactor); // Update Base Animation Value - FrameBased Animation for now ++m_i32Frame; // Update Skull Vertex Data using Animation Params for(i = 0; i < m_Scene.pMesh[eSkull].nNumVertex * 3; ++i) { m_pMorphedVertices[i]= f2vt(m_pAVGVertices[i] + (m_pDiffVertices[0][i] * m_fSkullWeights[0]) \ + (m_pDiffVertices[1][i] * m_fSkullWeights[1]) \ + (m_pDiffVertices[2][i] * m_fSkullWeights[2]) \ + (m_pDiffVertices[3][i] * m_fSkullWeights[3])); } // Buffer Clear glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Render Skull and Jaw Opaque with Lighting glDisable(GL_BLEND); // Opaque = No Blending glEnable(GL_LIGHTING); // Lighting On // Set skull and jaw texture glBindTexture(GL_TEXTURE_2D, m_ui32Texture[1]); // Enable and set vertices, normals and index data glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Render Animated Jaw - Rotation Only glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); myglMultMatrix(m_mView.f); myglTranslate(f2vt(0),f2vt(-50.0f),f2vt(-50.0f)); myglRotate(f2vt(-fCurrentfJawRotation), f2vt(1.0f), f2vt(0.0f), f2vt(0.0f)); myglRotate(f2vt(fCurrentfJawRotation) - f2vt(30.0f), f2vt(0), f2vt(1.0f), f2vt(-1.0f)); RenderJaw(); glPopMatrix(); // Render Morphed Skull glPushMatrix(); myglRotate(f2vt(fCurrentfJawRotation) - f2vt(30.0f), f2vt(0), f2vt(1.0f), f2vt(-1.0f)); RenderSkull(); // Render Eyes and Background with Alpha Blending and No Lighting glEnable(GL_BLEND); // Enable Alpha Blending glDisable(GL_LIGHTING); // Disable Lighting // Disable the normals as they aren't needed anymore glDisableClientState(GL_NORMAL_ARRAY); // Render Eyes using Skull Model Matrix DrawQuad(-30.0f ,0.0f ,50.0f ,20.0f , m_ui32Texture[0]); DrawQuad( 33.0f ,0.0f ,50.0f ,20.0f , m_ui32Texture[0]); glPopMatrix(); // Render Dual Texture Background with different base color, rotation, and texture rotation glPushMatrix(); glDisable(GL_BLEND); // Disable Alpha Blending myglColor4(f2vt(0.7f+0.3f*((m_fSkullWeights[0]))), f2vt(0.7f), f2vt(0.7f), f2vt(1.0f)); // Animated Base Color myglTranslate(f2vt(10.0f), f2vt(-50.0f), f2vt(0.0f)); myglRotate(f2vt(fCurrentfBackRotation*4.0f),f2vt(0),f2vt(0),f2vt(-1.0f)); // Rotation of Quad // Animated Texture Matrix glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); myglTranslate(f2vt(-0.5f), f2vt(-0.5f), f2vt(0.0f)); myglRotate(f2vt(fCurrentfBackRotation*-8.0f), f2vt(0), f2vt(0), f2vt(-1.0f)); myglTranslate(f2vt(-0.5f), f2vt(-0.5f), f2vt(0.0f)); // Draw Geometry DrawDualTexQuad (0.0f ,0.0f ,-100.0f ,300.0f, m_ui32Texture[3], m_ui32Texture[2]); // Disable Animated Texture Matrix glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); // Make sure to disable the arrays glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glMatrixMode(GL_MODELVIEW); glPopMatrix(); // Reset Colour myglColor4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f)); // Display info text m_Print3D.DisplayDefaultTitle("EvilSkull", "Morphing.", 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 OGLES2ShadowMapping::RenderScene() { //rotate light position m_fLightAngle += 0.01f; m_vLightPosition.x = m_fLightDistance * (float) cos(m_fLightAngle); m_vLightPosition.z = m_fLightDistance * (float) sin(m_fLightAngle); m_vLightDirection.x = -m_vLightPosition.x; m_vLightDirection.z = -m_vLightPosition.z; SetUpMatrices(); glEnable(GL_DEPTH_TEST); // Bind the frame buffer object glBindFramebuffer(GL_FRAMEBUFFER, m_uiFrameBufferObject); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { // Clear the screen and depth buffer so we can render from the light's view glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set the current viewport to our texture size glViewport(0, 0, m_ui32ShadowMapSize, m_ui32ShadowMapSize); // Since we don't care about colour when rendering the depth values to // the shadow-map texture, we disable color writing to increase speed. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Enable the simple shader for the light view pass. This render will not be shown to the user // so only the simplest render needs to be implemented glUseProgram(m_SimpleShaderProgram.uiId); // Set the light projection matrix glUniformMatrix4fv(m_SimpleShaderProgram.uiProjectionMatrixLoc, 1, GL_FALSE, m_LightProjection.f); // Render the world according to the light's view DrawScene(m_LightView); // We can turn color writing back on since we already stored the depth values glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Restore our normal viewport size to our screen width and height glViewport(0, 0,PVRShellGet(prefWidth),PVRShellGet(prefHeight)); } glBindFramebuffer(GL_FRAMEBUFFER, 0); // Clear the colour and depth buffers, we are now going to render the scene again from scratch glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Load the shadow shader. This shader requires additional parameters; texProjMatrix for the depth buffer // look up and the light direction for diffuse light (the effect is a lot nicer with the additon of the // diffuse light). glUseProgram(m_ShadowShaderProgram.uiId); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_uiShadowMapTexture); glUniformMatrix4fv(m_ShadowShaderProgram.uiProjectionMatrixLoc, 1, GL_FALSE, m_Projection.f); PVRTMat4 mViewInv, mTextureMatrix, mMatrix; mViewInv = m_View.inverse(); // We need to calculate the texture projection matrix. This matrix takes the pixels from world space to previously rendered light projection space //where we can look up values from our saved depth buffer. The matrix is constructed from the light view and projection matrices as used for the previous render and //then multiplied by the inverse of the current view matrix. mTextureMatrix = m_BiasMatrix * m_LightProjection * m_LightView * mViewInv; glUniformMatrix4fv(m_ShadowShaderProgram.uiTexProjMatrixLoc, 1, GL_FALSE, mTextureMatrix.f); DrawSceneWithShadow(m_View); // Re-enable the simple shader to draw the light source object glUseProgram(m_SimpleShaderProgram.uiId); SPODNode& Node = m_Scene.pNode[1]; PVRTMat4 mWorld, mModelView; m_Scene.GetWorldMatrix(mWorld, Node); mWorld.f[12] = m_vLightPosition.x; mWorld.f[13] = m_vLightPosition.y; mWorld.f[14] = m_vLightPosition.z; mModelView = m_View * mWorld; glUniformMatrix4fv(m_SimpleShaderProgram.uiModelViewMatrixLoc, 1, GL_FALSE, mModelView.f); glUniformMatrix4fv(m_SimpleShaderProgram.uiProjectionMatrixLoc, 1, GL_FALSE, m_LightProjection.f); DrawMesh(1); m_Print3D.DisplayDefaultTitle("ShadowMap", "", 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 OGLES3Refraction::RenderScene() { // Keyboard input (cursor to change Reflection Flag) if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT) || PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { m_bSpecular = !m_bSpecular; } // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_Background.Draw(m_uiTexture); // Enable backface culling and depth test glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // Use shader program glUseProgram(m_ShaderProgram.uiId); // Bind textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_uiTexture); // Calculate the model matrix PVRTMat4 mRotX, mRotY, mModel; mRotX = PVRTMat4::RotationX(m_fAngleX); mRotY = PVRTMat4::RotationY(m_fAngleY); mModel = mRotX * mRotY; m_fAngleX += PVRT_PI / 111; m_fAngleY += PVRT_PI / 150; // 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 light direction in model space PVRTVec4 vLightDirModel; vLightDirModel = mModelView.inverse() * PVRTVec4(0.57735f, 0.57735f, 0.57735f, 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); // Set specular flag glUniform1i(m_ShaderProgram.auiLoc[eSpecular], m_bSpecular); // Set rotation flag glUniform1i(m_ShaderProgram.auiLoc[eRotate], m_bRotate); /* 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("Refraction", m_bSpecular ? "Specular reflection: on" : "Specular reflection: off", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }
/*!**************************************************************************** @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 OGLES3Skybox2::RenderScene() { unsigned int i, j; // Clears the colour and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 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(!bPause) { // Calculate the model view matrix turning around the balloon ComputeViewMatrix(); if(iTime > m_iTimePrev) { float fDelta = (float) (iTime - m_iTimePrev) * g_fFrameRate; m_fFrame += fDelta; fDemoFrame += fDelta; fBurnAnim += fDelta * 0.02f; if(fBurnAnim >= 1.0f) fBurnAnim = 1.0f; } } m_iTimePrev = iTime; /* KeyBoard input processing */ if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1)) bPause=!bPause; if(PVRShellIsKeyPressed(PVRShellKeyNameACTION2)) fBurnAnim = 0.0f; /* Keyboard Animation and Automatic Shader Change over time */ if(!bPause && (fDemoFrame > 500 || (m_i32Effect == 2 && fDemoFrame > 80))) { if(++m_i32Effect >= (int) g_ui32NoOfEffects) { m_i32Effect = 1; m_fFrame = 0.0f; } fDemoFrame = 0.0f; fBurnAnim = 0.0f; } /* Change Shader Effect */ if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { if(++m_i32Effect >= (int) g_ui32NoOfEffects) m_i32Effect = 1; fDemoFrame = 0.0f; fBurnAnim = 0.0f; m_fFrame = 0.0f; } if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) { if(--m_i32Effect < 1) m_i32Effect = g_ui32NoOfEffects - 1; fDemoFrame = 0.0f; fBurnAnim = 0.0f; m_fFrame = 0.0f; } /* Change Skybox Texture */ if(PVRShellIsKeyPressed(PVRShellKeyNameUP)) { for(i = 0; i < g_ui32NoOfEffects; ++i) ChangeSkyboxTo(m_ppEffects[i], m_ui32TextureIDs[4]); fBurnAnim = 0.0f; } if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN)) { for(i = 0; i < g_ui32NoOfEffects; ++i) ChangeSkyboxTo(m_ppEffects[i], m_ui32TextureIDs[3]); fBurnAnim = 0.0f; } /* Setup Shader and Shader Constants */ int location; glDisable(GL_CULL_FACE); DrawSkybox(); glEnable(GL_CULL_FACE); m_ppEffects[m_i32Effect]->Activate(); for(i = 0; i < m_Scene.nNumMeshNode; i++) { SPODNode* pNode = &m_Scene.pNode[i]; // Gets pMesh referenced by the pNode SPODMesh* pMesh = &m_Scene.pMesh[pNode->nIdx]; // Gets the node model matrix PVRTMat4 mWorld, mWORLDVIEW; mWorld = m_Scene.GetWorldMatrix(*pNode); mWORLDVIEW = m_mView * mWorld; glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]); const CPVRTArray<SPVRTPFXUniform>& Uniforms = m_ppEffects[m_i32Effect]->GetUniformArray(); for(j = 0; j < Uniforms.GetSize(); ++j) { switch(Uniforms[j].nSemantic) { case ePVRTPFX_UsPOSITION: { glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); glEnableVertexAttribArray(Uniforms[j].nLocation); } break; case ePVRTPFX_UsNORMAL: { glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); glEnableVertexAttribArray(Uniforms[j].nLocation); } break; case ePVRTPFX_UsUV: { glVertexAttribPointer(Uniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); glEnableVertexAttribArray(Uniforms[j].nLocation); } break; case ePVRTPFX_UsWORLDVIEWPROJECTION: { PVRTMat4 mMVP; /* Passes the model-view-projection matrix (MVP) to the shader to transform the vertices */ mMVP = m_mProjection * mWORLDVIEW; glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mMVP.f); } break; case ePVRTPFX_UsWORLDVIEW: { glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mWORLDVIEW.f); } break; case ePVRTPFX_UsWORLDVIEWIT: { PVRTMat4 mWORLDVIEWI, mWORLDVIEWIT; mWORLDVIEWI = mWORLDVIEW.inverse(); mWORLDVIEWIT= mWORLDVIEWI.transpose(); PVRTMat3 WORLDVIEWIT = PVRTMat3(mWORLDVIEWIT); glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, WORLDVIEWIT.f); } break; case ePVRTPFX_UsVIEWIT: { PVRTMat4 mViewI, mViewIT; mViewI = m_mView.inverse(); mViewIT = mViewI.transpose(); PVRTMat3 ViewIT = PVRTMat3(mViewIT); glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, ViewIT.f); } break; case ePVRTPFX_UsLIGHTDIREYE: { PVRTVec4 vLightDirectionEyeSpace; // Passes the light direction in eye space to the shader vLightDirectionEyeSpace = m_mView * PVRTVec4(1.0,1.0,-1.0,0.0); glUniform3f(Uniforms[j].nLocation, vLightDirectionEyeSpace.x, vLightDirectionEyeSpace.y, vLightDirectionEyeSpace.z); } break; case ePVRTPFX_UsTEXTURE: { // Set the sampler variable to the texture unit glUniform1i(Uniforms[j].nLocation, Uniforms[j].nIdx); } break; } } location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "myEyePos"); if(location != -1) glUniform3f(location, vCameraPosition.x, vCameraPosition.y, vCameraPosition.z); //set animation location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "fAnim"); if(location != -1) glUniform1f(location, fBurnAnim); location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "myFrame"); if(location != -1) glUniform1f(location, m_fFrame); if(g_bBlendShader[m_i32Effect]) { glEnable(GL_BLEND); // Correct render order for alpha blending through culling // Draw Back faces glCullFace(GL_FRONT); location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "bBackFace"); glUniform1i(location, 1); DrawMesh(pMesh); glUniform1i(location, 0); glCullFace(GL_BACK); } else { location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "bBackFace"); if(location != -1) glUniform1i(location, 0); glDisable(GL_BLEND); } /* Everything should now be setup, therefore draw the mesh*/ DrawMesh(pMesh); glBindBuffer(GL_ARRAY_BUFFER, 0); for(j = 0; j < Uniforms.GetSize(); ++j) { switch(Uniforms[j].nSemantic) { case ePVRTPFX_UsPOSITION: { glDisableVertexAttribArray(Uniforms[j].nLocation); } break; case ePVRTPFX_UsNORMAL: { glDisableVertexAttribArray(Uniforms[j].nLocation); } break; case ePVRTPFX_UsUV: { glDisableVertexAttribArray(Uniforms[j].nLocation); } break; } } } // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools if(!bPause) m_Print3D.DisplayDefaultTitle("Skybox2", "", ePVRTPrint3DSDKLogo); else m_Print3D.DisplayDefaultTitle("Skybox2", "Paused", 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 OGLES2PVRScopeRemote::RenderScene() { CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); if(m_psSPSCommsData) { // mark every N frames if(!(m_i32FrameCounter % 100)) { char buf[128]; const int nLen = sprintf(buf, "frame %u", m_i32FrameCounter); m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen); } // Check for dirty items m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "dirty", static_cast<unsigned int>(strlen("dirty")), m_i32FrameCounter); { unsigned int nItem, nNewDataLen; const char *pData; bool bRecompile = false; while(pplLibraryDirtyGetFirst(m_psSPSCommsData, &nItem, &nNewDataLen, &pData)) { PVRShellOutputDebug("dirty item %u %u 0x%08x\n", nItem, nNewDataLen, pData); switch(nItem) { case 0: delete [] m_pszFragShader; m_pszFragShader = new char [nNewDataLen+1]; strncpy(m_pszFragShader, (char*)pData, nNewDataLen); m_pszFragShader[nNewDataLen] = 0; bRecompile = true; break; case 1: delete [] m_pszVertShader; m_pszVertShader = new char [nNewDataLen+1]; strncpy(m_pszVertShader, (char*)pData, nNewDataLen); m_pszVertShader[nNewDataLen] = 0; bRecompile = true; break; case 2: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMinThickness = psData->fCurrent; } break; case 3: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMaxVariation = psData->fCurrent; } break; } } if(bRecompile) { CPVRTString ErrorStr; glDeleteProgram(m_ShaderProgram.uiId); glDeleteShader(m_uiVertShader); glDeleteShader(m_uiFragShader); if (!LoadShaders(&ErrorStr, m_pszFragShader, m_pszVertShader)) { PVRShellOutputDebug("%s", ErrorStr.c_str()); } } } m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "draw", static_cast<unsigned int>(strlen("draw")), m_i32FrameCounter); } // 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); // Rotate and Translation the model matrix PVRTMat4 mModel; mModel = PVRTMat4::RotationY(m_fAngleY); m_fAngleY += (2*PVRT_PI/60)/7; // Set model view projection matrix PVRTMat4 mModelView, mMVP; mModelView = m_mView * mModel; mMVP = m_mProjection * mModelView; glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr()); // Set light direction in model space PVRTVec4 vLightDirModel; vLightDirModel = mModel.inverse() * PVRTVec4(1, 1, 1, 0); glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vLightDirModel.x); // Set eye position in model space PVRTVec4 vEyePosModel; vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1); glUniform3fv(m_ShaderProgram.uiEyePosLoc, 1, &vEyePosModel.x); /* Set the iridescent shading parameters */ // Set the minimum thickness of the coating in nm glUniform1f(m_ShaderProgram.uiMinThicknessLoc, m_fMinThickness); // Set the maximum variation in thickness of the coating in nm glUniform1f(m_ShaderProgram.uiMaxVariationLoc, m_fMaxVariation); /* Now that the uniforms are set, call another function to actually draw the mesh. */ DrawMesh(0); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "Print3D", static_cast<unsigned int>(strlen("Print3D")), m_i32FrameCounter); } // Displays the demo name using the tools. For a detailed explanation, see the example IntroducingPVRTools if(m_bCommsError) { m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs\n\nError:\n PVRScopeComms failed\n Is PVRPerfServer connected?", ePVRTPrint3DSDKLogo); m_bCommsError = false; } else m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } // send counters m_anCounterReadings[eCounter] = m_i32FrameCounter; m_anCounterReadings[eCounter10] = m_i32Frame10Counter; if(m_psSPSCommsData) { m_bCommsError |= !pplCountersUpdate(m_psSPSCommsData, m_anCounterReadings); } // update some counters ++m_i32FrameCounter; if(0 == (m_i32FrameCounter / 10) % 10) { m_i32Frame10Counter += 10; } 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; }
/******************************************************************************* * Function Name : RenderScene * Returns : true if no error occured * Description : Main rendering loop function of the program. The shell will * call this function every frame. *******************************************************************************/ bool OGLESVase::RenderScene() { PVRTMat4 RotationMatrix, RotateX, RotateY; // Increase rotation angles m_fAngleX += VERTTYPEDIV(PVRT_PI, f2vt(100.0f)); m_fAngleY += VERTTYPEDIV(PVRT_PI, f2vt(150.0f)); if(m_fAngleX >= PVRT_PI) m_fAngleX -= PVRT_TWO_PI; if(m_fAngleY >= PVRT_PI) m_fAngleY -= PVRT_TWO_PI; // Clear the buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Setup the vase rotation // Calculate rotation matrix RotateX = PVRTMat4::RotationX(m_fAngleX); RotateY = PVRTMat4::RotationY(m_fAngleY); RotationMatrix = RotateY * RotateX; // Modelview matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); myglTranslate(f2vt(0.0f), f2vt(0.0f), f2vt(-200.0f)); myglMultMatrix(RotationMatrix.f); // Draw the scene // Use PVRTools to draw a background image m_Background.Draw(m_uiBackTex); // Enable client states glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable depth test glEnable(GL_DEPTH_TEST); // Draw vase outer glBindTexture(GL_TEXTURE_2D, m_pui32Textures[m_Scene.pNode[eVase].nIdxMaterial]); DrawReflectiveMesh(m_Scene.pNode[eVase].nIdx, &RotationMatrix); // Draw glass glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, m_pui32Textures[m_Scene.pNode[eGlass].nIdxMaterial]); // Pass 1: only render back faces (model has reverse winding) glFrontFace(GL_CW); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); DrawMesh(m_Scene.pNode[eGlass].nIdx); // Pass 2: only render front faces (model has reverse winding) glCullFace(GL_FRONT); DrawMesh(m_Scene.pNode[eGlass].nIdx); // Disable blending as it isn't needed glDisable(GL_BLEND); // Disable client states glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Display info text m_Print3D.DisplayDefaultTitle("Vase", "Translucency and reflections.", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }
/******************************************************************************* * Function Name : RenderScene * Returns : true if no error occured * Description : Main rendering loop function of the program. The shell will * call this function every frame. *******************************************************************************/ bool OGLESSkinning::RenderScene() { // Increase the frame number m_fFrame += 0.3f; while(m_fFrame > m_Scene.nNumFrame-1) m_fFrame -= m_Scene.nNumFrame-1; // 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_mTransform = PVRTMat4::Translation(0,0, m_fDistance) * PVRTMat4::RotationY(m_fAngle); // Clear the depth and frame buffer glClearColor(0.6f, 0.8f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set Z compare properties glEnable(GL_DEPTH_TEST); // Disable Blending glDisable(GL_BLEND); // Calculate the model view matrix glMatrixMode(GL_MODELVIEW); glLoadMatrixf(m_mView.f); // Draw the model DrawModel(); // Print text on screen m_Print3D.DisplayDefaultTitle("Skinning", "", ePVRTPrint3DSDKLogo); // Flush all Print3D commands 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 OGLESIntroducingPFX::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. */ int iTime = PVRShellGetTime(); int iDeltaTime = iTime - m_iTimePrev; m_iTimePrev = iTime; m_fFrame += (float)iDeltaTime * 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); } /* 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; for(unsigned int j = 0; j < m_nUniformCnt; ++j) { switch(m_psUniforms[j].nSemantic) { case eUsPOSITION: { glVertexAttribPointer(m_psUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); glEnableVertexAttribArray(m_psUniforms[j].nLocation); } break; case eUsNORMAL: { glVertexAttribPointer(m_psUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); glEnableVertexAttribArray(m_psUniforms[j].nLocation); } break; case eUsUV: { glVertexAttribPointer(m_psUniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); glEnableVertexAttribArray(m_psUniforms[j].nLocation); } break; case eUsWORLDVIEWPROJECTION: { PVRTMat4 mWVP; /* Passes the world-view-projection matrix (WVP) to the shader to transform the vertices */ mWVP = m_mProjection * mWorldView; glUniformMatrix4fv(m_psUniforms[j].nLocation, 1, GL_FALSE, mWVP.f); } break; case eUsWORLDVIEWIT: { 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(m_psUniforms[j].nLocation, 1, GL_FALSE, WorldViewIT.f); } break; case eUsLIGHTDIREYE: { // 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(m_psUniforms[j].nLocation, vLightDirectionEyeSpace.x, vLightDirectionEyeSpace.y, vLightDirectionEyeSpace.z); } break; case eUsTEXTURE: { // Set the sampler variable to the texture unit glUniform1i(m_psUniforms[j].nLocation, m_psUniforms[j].nIdx); } 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); for(unsigned int j = 0; j < m_nUniformCnt; ++j) { switch(m_psUniforms[j].nSemantic) { case eUsPOSITION: { glDisableVertexAttribArray(m_psUniforms[j].nLocation); } break; case eUsNORMAL: { glDisableVertexAttribArray(m_psUniforms[j].nLocation); } break; case eUsUV: { glDisableVertexAttribArray(m_psUniforms[j].nLocation); } break; } } } // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("IntroducingPFX", "", ePVRTPrint3DLogoIMG); m_Print3D.Flush(); return true; }