/*!**************************************************************************** @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 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 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 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(); }
/*!**************************************************************************** @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 RenderTitle @Input fFadeAmount @Description Draws the title text. *****************************************************************************/ void OGLES2IntroducingPrint3D::RenderTitle(float fFadeAmount) { unsigned int uiCol = (((unsigned int)(fFadeAmount * 255)) << 24) | 0x00FFFF; float fW = PVRShellGet(prefWidth) * 0.5f; float fH = PVRShellGet(prefHeight) * 0.5f; bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); /* Print3D can optionally be provided with user-defined projection and modelview matrices which allow custom layout of text. Here we are just providing a projection matrix so that text can be placed in viewport coordinates, rather than the default, more abstract coordinate system of 0.0-100.0. */ PVRTMat4 mProjection = PVRTMat4::Ortho(-fW, fH, fW, -fH, -1.0f, 1.0f, PVRTMat4::OGL, bRotate); m_IntroText.SetProjection(mProjection); /* Using the MeasureText() method provided by Print3D, we can determine the bounding-box size of a string of text. This can be useful for justify text centrally, as we are doing here. */ float fLine1W = 0.0f; float fLine2W = 0.0f; m_IntroText.MeasureText(&fLine1W, NULL, 1.0f, "introducing"); m_IntroText.MeasureText(&fLine2W, NULL, 1.0f, "print3d"); /* Display some text. Print3D() function allows to draw text anywhere on the screen using any colour. Param 1: Position of the text along X Param 2: Position of the text along Y Param 3: Scale of the text Param 4: Colour of the text (0xAABBGGRR format) Param 5: Formatted string (uses the same syntax as printf) ... */ m_IntroText.Print3D(-fLine1W*0.5f, 50.0f, 1.0f, uiCol, "introducing"); m_IntroText.Print3D(-fLine2W*0.5f, 0.0f, 1.0f, uiCol, "print3d"); // Tells Print3D to do all the pending text rendering now m_IntroText.Flush(); }
void RudeText::Print(float x, float y, float scale, unsigned int color, const char * const pszFormat, ...) { va_list args; char text[512]; va_start(args, pszFormat); vsprintf(text, pszFormat, args); va_end(args); gTextPrint.Print3D(x, y, scale, color, text); }
/*!**************************************************************************** @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 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 and relevant OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLES3EdgeDetection::RenderScene() { // Declares world orientation variables. PVRTMat4 mWorld, mMVP; // Updates the current time. m_ulCurrentTime=PVRShellGetTime(); #ifdef SHOW_MAX_FPS //Updates and checks framerate. m_iFrameCount+=1; if (m_ulCurrentTime-m_ulPreviousTimeFPS>=1000) { m_fFPS=(GLfloat)m_iFrameCount/(GLfloat)(m_ulCurrentTime-m_ulPreviousTimeFPS)*1000.0f; m_ulPreviousTimeFPS=m_ulCurrentTime; m_iFrameCount=0; } // Display fps data m_Print3D.Print3D(2.0f, 10.0f, 0.75f, 0xff0000ff, "%i fps", (int)m_fFPS); #endif // Time dependant updates for the rotational velocity of the scene. m_fAngleY += 0.0002f*PVRT_PI*(m_ulCurrentTime-m_ulPreviousTimeAngle); m_ulPreviousTimeAngle=PVRShellGetTime(); // Render to our texture (bracketed for viewing convenience) { // Use the first shader program to perform the initial render of the mask. glUseProgram(m_PreShader.uiId); // Bind render-to-texture frame buffer and set the viewPort glBindFramebuffer(GL_FRAMEBUFFER, m_uiFramebufferObject); if(m_i32TexWidth != m_i32WinWidth || m_i32TexHeight != m_i32WinHeight) glViewport(0, 0, m_i32TexWidth, m_i32TexHeight); #if defined(__PALMPDK__) // Enable writing to the alpha channel again as usually it is disabled so // we don't blend with the video layer on webOS devices. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); #endif // Clear the color and depth buffer of our FBO glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Rotates the scene and sets the model-view-projection matrix mWorld = PVRTMat4::RotationY(m_fAngleY); mMVP = m_mR2TProjection * m_mR2TView * mWorld; // Send the view matrix information to the shader. glUniformMatrix4fv(m_PreShader.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.f); // Enable vertex attribute array glEnableVertexAttribArray(eVERTEX_ARRAY); //Enable depth testing and culling. glEnable(GL_DEPTH_TEST); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Draw our models by looping through each mesh as defined by nNumMesh. for (unsigned int i=0; i<m_Scene.nNumMeshNode; i++) { DrawMesh(i); } // Unbind the VBO and index buffer. glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); //Invalidate the framebuffer attachments we don't need to avoid unnecessary copying to system memory const GLenum attachment = GL_DEPTH_ATTACHMENT; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachment); } // Bind the original frame buffer to draw to screen and set the Viewport. glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFramebuffer); if(m_i32TexWidth != m_i32WinWidth || m_i32TexHeight != m_i32WinHeight) glViewport(0, 0, m_i32WinWidth, m_i32WinHeight); // Clear the color and depth buffers for the screen. glClear(GL_COLOR_BUFFER_BIT); // Uses PVRShell input handling to update the line width in the edge detection shaders. if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { m_fLineWidth++; if (m_fLineWidth>10) m_fLineWidth=10; } if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) { m_fLineWidth--; if (m_fLineWidth<1) m_fLineWidth=1; } // Uses PVRShell input to choose which post shader program to use for post processing. // Loops through all shaders defined in EPostShaders if (PVRShellIsKeyPressed(PVRShellKeyNameUP)) { if (m_uiShaderID==eNumPostShaders-1) m_uiShaderID=0; else m_uiShaderID++; } else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN)) { if (m_uiShaderID==0) m_uiShaderID=eNumPostShaders-1; else m_uiShaderID--; } // Sets the shader based on the shader ID value, and sets the line width each frame (as it can change); glUseProgram(m_PostShaders[m_uiShaderID].uiId); glUniform2f(m_PostShaders[m_uiShaderID].auiLoc[ePixelSize],m_fLineWidth/(float)m_i32TexWidth,m_fLineWidth/(float)m_i32TexHeight); /* Note: We do not need to pass any projection data to these shaders as they are used only to render a texture to a full screen quad which is parallel with the viewport. The model meshes have already been positioned in the previous shader and now only exist as a 2D image.*/ // Enable texture attribute array glEnableVertexAttribArray(eTEXCOORD_ARRAY); // Draw the fullscreen quad to render the screen to. DrawQuad(); // Disable the vertex and texture attribute arrays glDisableVertexAttribArray(eTEXCOORD_ARRAY); glDisableVertexAttribArray(eVERTEX_ARRAY); // Print the demo title, current post shader's name and the line width if applicable m_Print3D.DisplayDefaultTitle("Edge Detection", "", ePVRTPrint3DSDKLogo); m_Print3D.Print3D(5,80,1,0xff885500,g_aszPostShaderNames[m_uiShaderID]); if (!strcmp(c_aszPostShaderDefines[m_uiShaderID][0],"EDGE_DETECTION")) m_Print3D.Print3D(5,90,0.7f,0xff000055,"Line Width = %i", (int)m_fLineWidth); m_Print3D.Flush(); return true; }
/*!**************************************************************************** @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 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 OGLESFur::RenderScene() { // Reset the states that print3D changes glDisable(GL_CULL_FACE); glEnable(GL_FOG); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); // User input bool bNewPage = false; if(PVRShellIsKeyPressed(PVRShellKeyNameSELECT)) m_bPause = !m_bPause; if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) { if(--m_i32WndPage < 0) m_i32WndPage = 5; bNewPage = true; } if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { if(++m_i32WndPage > 5) m_i32WndPage = 0; bNewPage = true; } if(bNewPage) { switch(m_i32WndPage) { case 0: m_bViewMode = false; m_i32FurShellNo = 7; break; case 1: m_bViewMode = true; m_i32FurShellNo = 0; break; case 2: m_bViewMode = true; m_i32FurShellNo = 1; break; case 3: m_bViewMode = true; m_i32FurShellNo = 2; break; case 4: m_bViewMode = true; m_i32FurShellNo = 7; break; case 5: m_bViewMode = false; m_i32FurShellNo = 7; break; } // Since the number of fur shells has changed, update them UpdateFurShells(); } // Clear glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Animation DoAnimation(); // View matrix glMatrixMode(GL_MODELVIEW); glLoadMatrixf(m_mView.f); // Enable the vertex and normal arrays glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Begin Scene if(!m_bViewMode) DrawEnvironment(); // Draw the Duck DrawDuck(); // Display Paused if the app is paused if(m_bPause) m_Print3D.Print3D(78.0f, 2.0f, 1.0f, PVRTRGBA(255,255,255,255), "Paused"); // Disable the normals before our drawing of the print3D content glDisableClientState(GL_NORMAL_ARRAY); char szDesc[256]; snprintf(szDesc, 256, "Displaying %d shells", m_i32FurShellNo); // Display the IMG logo m_Print3D.DisplayDefaultTitle("Fur", szDesc, 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 OGLES2Iridescence::RenderScene() { // Keyboard input (cursor up/down to change thickness variation) if (PVRShellIsKeyPressed(PVRShellKeyNameUP)) { m_fMaxVariation += 1.0f; } else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN)) { m_fMaxVariation = PVRT_MAX(0.0f, m_fMaxVariation - 1.0f); } // Keyboard input (cursor left/right to change minimum thickness) if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) { m_fMinThickness += 1.0f; } else if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) { m_fMinThickness = PVRT_MAX(0.0f, m_fMinThickness - 1.0f); } // 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); m_Print3D.Print3D(2.0f, 10.0f, 0.75f, 0xffffffff, "Minimum Thickness:"); m_Print3D.Print3D(2.0f, 15.0f, 0.75f, 0xffffffff, "%8.0f nm", m_fMinThickness); m_Print3D.Print3D(2.0f, 20.0f, 0.75f, 0xffffffff, "Maximum Variation:"); m_Print3D.Print3D(2.0f, 25.0f, 0.75f, 0xffffffff, "%8.0f nm", m_fMaxVariation); // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("Iridescence", "", ePVRTPrint3DLogoIMG); m_Print3D.Flush(); return true; }
/*!*************************************************************************** @Function RenderText @Description Draws the 3D text and scrolls in to the screen. *****************************************************************************/ void OGLES2IntroducingPrint3D::RenderText() { float fAspect = (float)PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight); bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); // Calculate the frame delta. unsigned long ulNow = PVRShellGetTime(); if(m_ulPrevFrameT == 0) m_ulPrevFrameT = ulNow; float fDT = (ulNow - m_ulPrevFrameT) * 0.001f; m_ulPrevFrameT = ulNow; // Calculate the FPS scale. float fFPSScale = fDT / c_fTargetFPS; // Move the text. Progressively speed up. float fSpeedInc = 0.0f; if(m_fTextOffset > 0.0f) fSpeedInc = m_fTextOffset / TEXT_END_Y; m_fTextOffset += (0.75f + (1.0f * fSpeedInc)) * fFPSScale; if(m_fTextOffset > TEXT_END_Y) m_fTextOffset = TEXT_START_Y; PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(0.7f, fAspect, 1.0f, 2000.0f, PVRTMat4::OGL, bRotate); PVRTMat4 mScale = PVRTMat4::Scale(PVRTVec3(1.0f, -1.0f, 1.0f)); PVRTMat4 mCamera = PVRTMat4::LookAtRH(PVRTVec3(0.0f, -900.0f, 700.0f), PVRTVec3(0.0f,-200.0f,0.0f), PVRTVec3(0.0f,1.0f,0.0f)); PVRTMat4 mTrans = PVRTMat4::Translation(PVRTVec3(0.0f, m_fTextOffset, 0.0f)); PVRTMat4 mModelView = mCamera * mTrans; float fStrWidth = 0.0f; /* Print3D can optionally be provided with user-defined projection and model-view matrices which allow custom layout of text. Here we are proving both a projection and model-view matrix. The projection matrix specified here uses perspective projection which will provide the 3D effect. The model-view matrix positions the the text in world space providing the 'camera' position and the scrolling of the text. */ m_CentralText.SetProjection(mProjection); m_CentralText.SetModelView(mModelView); /* The previous method (RenderTitle()) explains the following functions in more detail however put simply, we are looping the entire array of loaded text which is encoded in UTF-8. Print3D batches this internally and the call to Flush() will render the text to the frame buffer. We are also fading out the text over a certain distance. */ float fPos, fFade; unsigned int uiCol; for(unsigned int uiIndex = 0; uiIndex < m_TextLines.GetSize(); ++uiIndex) { fPos = (m_fTextOffset - (uiIndex * 36.0f)); fFade = 1.0f; if(fPos > TEXT_FADE_START) { fFade = PVRTClamp(1.0f - ((fPos - TEXT_FADE_START) / (TEXT_FADE_END - TEXT_FADE_START)), 0.0f, 1.0f); } uiCol = (((unsigned int)(fFade * 255)) << 24) | 0x00FFFF; m_CentralText.MeasureText(&fStrWidth, NULL, 1.0f, (const char*)m_TextLines[uiIndex]); m_CentralText.Print3D(-(fStrWidth*0.5f), -(uiIndex * 36.0f), 1.0f, uiCol, (const char*)m_TextLines[uiIndex]); } m_CentralText.Flush(); }
/*!**************************************************************************** @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 OGLES2Refraction::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", "", ePVRTPrint3DLogoIMG); m_Print3D.Print3D(0.3f, 7.5f, 0.75f, PVRTRGBA(255,255,255,255), "Specular reflection: %s", (m_bSpecular) ? "on" : "off" ); 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; }
/*!**************************************************************************** @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 OGLES2IntroducingPrint3D::RenderScene() { // Clears the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); unsigned long ulCurrentTime = PVRShellGetTime() - m_ulStartTime; // Draw star background m_BG.Draw(m_uiStarTex); // Render the 'Introducing Print3D' title for the first n seconds. if(ulCurrentTime < INTRO_TIME) { float fFadeAmount = 1.0f; // Fade in if(ulCurrentTime < INTRO_FADE_TIME) { fFadeAmount = ulCurrentTime / (float)INTRO_FADE_TIME; } // Fade out else if(ulCurrentTime > INTRO_TIME - INTRO_FADE_TIME) { fFadeAmount = 1.0f - ((ulCurrentTime - (INTRO_TIME - INTRO_FADE_TIME)) / (float)INTRO_FADE_TIME); } RenderTitle(fFadeAmount); } // Render the 3D text. else { RenderText(); } /* Here we are passing in a wide-character string to Print3D function. This allows Unicode to be compiled in to string-constants, which this code snippet demonstrates. Because we are not setting a projection or a model-view matrix the default projection matrix is used. */ unsigned int uiTitleLang = (unsigned int) ((ulCurrentTime / 1000) / (TITLE_TIME / 1000)) % eLang_Size; unsigned int uiNextLang = (uiTitleLang + 1) % eLang_Size; unsigned int ulModTime = (unsigned int) ulCurrentTime % TITLE_TIME; float fTitlePerc = 1.0f; float fNextPerc = 0.0f; if(ulModTime > TITLE_TIME - TITLE_FADE_TIME) { fTitlePerc = 1.0f - ((ulModTime - (INTRO_TIME - INTRO_FADE_TIME)) / (float)INTRO_FADE_TIME); fNextPerc = 1.0f - fTitlePerc; } unsigned int uiTitleCol = (((unsigned int)(fTitlePerc * 255)) << 24) | 0xFFFFFF; unsigned int uiNextCol = (((unsigned int)(fNextPerc * 255)) << 24) | 0xFFFFFF; m_TitleText.Print3D(0, 0, 1, uiTitleCol, c_pwzTitles[uiTitleLang]); m_TitleText.Print3D(0, 0, 1, uiNextCol, c_pwzTitles[uiNextLang]); m_TitleText.Flush(); /* DisplayDefaultTitle() writes a title and description text on the top left of the screen. It can also display the PVR logo (ePVRTPrint3DLogoPowerVR), the IMG logo (ePVRTPrint3DLogoIMG) or both (ePVRTPrint3DLogoPowerVR | ePVRTPrint3DLogoIMG) which is what we are using the function for here. Set this last parameter to NULL not to display the logos. Passing NULL for the first two parameters will not display any text. */ m_Print3D.DisplayDefaultTitle(NULL, NULL, ePVRTPrint3DSDKLogo); // Tells Print3D to do all the pending text rendering now m_Print3D.Flush(); return true; }