/*!**************************************************************************** @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 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 Name : InitView * Returns : true if no error occured * Description : Code in InitView() will be called by the Shell upon a change * in the rendering context. * Used to initialize variables that are dependant on the rendering * context (e.g. textures, vertex buffers, etc.) *******************************************************************************/ bool OGLESSkinning::InitView() { CPVRTString error; // Check to see whether the matrix palette extension is supported. if(!CPVRTglesExt::IsGLExtensionSupported("GL_OES_matrix_palette")) { PVRShellSet(prefExitMessage, "ERROR: The extension GL_OES_matrix_palette is unsupported.\n"); return false; } // Initialise the matrix palette extensions m_Extensions.LoadExtensions(); // Load the textures if(!LoadTextures(&error)) { PVRShellSet(prefExitMessage, error.c_str()); return false; } // Init Print3D to display text on screen bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); if(m_Print3D.SetTextures(0, PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n"); return false; } // Model View Matrix CameraGetMatrix(); // Projection Matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(m_mProjection.f); // GENERIC RENDER STATES // Enables Depth Testing glEnable(GL_DEPTH_TEST); // Enables Smooth Colour Shading glShadeModel(GL_SMOOTH); // Enable texturing glEnable(GL_TEXTURE_2D); // Define front faces glFrontFace(GL_CW); // Enables texture clamping glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); // Reset the model view matrix to position the light glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Setup ambiant light glEnable(GL_LIGHTING); PVRTVec4 lightGlobalAmbient = PVRTVec4(1.0f, 1.0f, 1.0f, 1.0f); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightGlobalAmbient.ptr()); // Setup a directional light source PVRTVec4 lightPosition = PVRTVec4(-0.7f, -1.0f, 0.2f, 0.0f); PVRTVec4 lightAmbient = PVRTVec4(1.0f, 1.0f, 1.0f, 1.0f); PVRTVec4 lightDiffuse = PVRTVec4(1.0f, 1.0f, 1.0f, 1.0f); PVRTVec4 lightSpecular = PVRTVec4(0.2f, 0.2f, 0.2f, 1.0f); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition.ptr()); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient.ptr()); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse.ptr()); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular.ptr()); LoadVbos(); /* Initialise an array to lookup the textures for each material in the scene. */ m_puiTextures = new GLuint[m_Scene.nNumMaterial]; for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i) { m_puiTextures[i] = m_uiLegTex; SPODMaterial* pMaterial = &m_Scene.pMaterial[i]; if(strcmp(pMaterial->pszName, "Mat_body") == 0) { m_puiTextures[i] = m_uiBodyTex; } else if(strcmp(pMaterial->pszName, "Mat_legs") == 0) { m_puiTextures[i] = m_uiLegTex; } else if(strcmp(pMaterial->pszName, "Mat_belt") == 0) { m_puiTextures[i] = m_uiBeltTex; } } return true; }
/*!**************************************************************************** @Function InitView @Return bool true if no error occured @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLESEvilSkull::InitView() { PVRTMat4 mPerspective; SPVRTContext sContext; // Initialize Print3D textures bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); if(m_Print3D.SetTextures(&sContext, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n"); return false; } /*********************** ** LOAD TEXTURES ** ***********************/ if(PVRTTextureLoadFromPVR(c_szIrisTexFile, &m_ui32Texture[0]) != PVR_SUCCESS) return false; myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(PVRTTextureLoadFromPVR(c_szMetalTexFile, &m_ui32Texture[1]) != PVR_SUCCESS) return false; myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(PVRTTextureLoadFromPVR(c_szFire02TexFile, &m_ui32Texture[2]) != PVR_SUCCESS) return false; myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(PVRTTextureLoadFromPVR(c_szFire03TexFile, &m_ui32Texture[3]) != PVR_SUCCESS) return false; myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /****************************** ** GENERIC RENDER STATES ** *******************************/ // The Type Of Depth Test To Do glDepthFunc(GL_LEQUAL); // Enables Depth Testing glEnable(GL_DEPTH_TEST); // Enables Smooth Color Shading glShadeModel(GL_SMOOTH); // Blending mode glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Create perspective matrix mPerspective = PVRTMat4::PerspectiveFovRH(f2vt(70.0f*(3.14f/180.0f)), f2vt((float)PVRShellGet(prefWidth) /(float)PVRShellGet(prefHeight) ), f2vt(10.0f), f2vt(10000.0f), PVRTMat4::OGL, bRotate); glMatrixMode(GL_PROJECTION); myglLoadMatrix(mPerspective.f); // Create viewing matrix m_mView = PVRTMat4::LookAtRH(m_CameraPos, m_CameraTo, m_CameraUp); glMatrixMode(GL_MODELVIEW); myglLoadMatrix(m_mView.f); // Enable texturing glEnable(GL_TEXTURE_2D); // Lights (only one side lighting) glEnable(GL_LIGHTING); // Light 0 (White directional light) PVRTVec4 fAmbient = PVRTVec4(f2vt(0.2f), f2vt(0.2f), f2vt(0.2f), f2vt(1.0f)); PVRTVec4 fDiffuse = PVRTVec4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f)); PVRTVec4 fSpecular = PVRTVec4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f)); myglLightv(GL_LIGHT0, GL_AMBIENT, fAmbient.ptr()); myglLightv(GL_LIGHT0, GL_DIFFUSE, fDiffuse.ptr()); myglLightv(GL_LIGHT0, GL_SPECULAR, fSpecular.ptr()); myglLightv(GL_LIGHT0, GL_POSITION, m_LightPos.ptr()); glEnable(GL_LIGHT0); glDisable(GL_LIGHTING); // Create the data used for the morphing CreateMorphData(); // Sets the clear color myglClearColor(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f)); // Create vertex buffer objects LoadVbos(); return true; }
/*!**************************************************************************** @Function RenderCubeScene @Input iFrame @Description Renders the pre-loaded scene. ******************************************************************************/ void OGLES2MultiThreading::RenderCubeScene(int iFrame) { bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); int iW = PVRShellGet(prefWidth); int iH = PVRShellGet(prefHeight); PVRTMat4 mxProjection = PVRTMat4::PerspectiveFovRH(0.7f, (float)iW / (float)iH, 1.0f, 1000.0f, PVRTMat4::OGL, bRotate); PVRTMat4 mxView = PVRTMat4::Translation(0.0f, 0.0f, -200.0f); PVRTMat4 mxModel = PVRTMat4::RotationX(-0.5f) * PVRTMat4::RotationY(iFrame * 0.016f) * PVRTMat4::Scale(30.0f, 30.0f, 30.0f); PVRTMat4 mxMVP = mxProjection * mxView * mxModel; PVRTVec4 vLightDir = PVRTVec4(0.0f, 0.3f, 1.0f, 0.0f) * mxModel; // Actually use the created program glUseProgram(handles.uiProgramObject); // Sets the clear color. // The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0 glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue glBindTexture(GL_TEXTURE_2D, handles.uiTexture); // Bind the VBO glBindBuffer(GL_ARRAY_BUFFER, handles.uiVbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.uiIndexVbo); /* Clears the color buffer and depth buffer */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Bind the projection model view matrix (PMVMatrix) to the associated uniform variable in the shader */ // First gets the location of that variable in the shader using its name int i32MVPLocation = glGetUniformLocation(handles.uiProgramObject, "myPMVMatrix"); int i32LDLocation = glGetUniformLocation(handles.uiProgramObject, "vLightDir"); int i32TexLocation = glGetUniformLocation(handles.uiProgramObject, "sTexture"); // Then passes the matrix to that variable glUniformMatrix4fv( i32MVPLocation, 1, GL_FALSE, mxMVP.ptr()); // Pass light direction glUniform3fv( i32LDLocation, 1, vLightDir.ptr()); // Set texture location glUniform1i( i32TexLocation, 0); /* Enable the custom vertex attribute at index VERTEX_ARRAY. We previously binded that index to the variable in our shader "vec4 MyVertex;" */ glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(NORMAL_ARRAY); glEnableVertexAttribArray(UV_ARRAY); // Sets the vertex data to this attribute index glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0); glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3*sizeof(GLfloat))); glVertexAttribPointer(UV_ARRAY, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6*sizeof(GLfloat))); /* Draws a non-indexed triangle array from the pointers previously given. This function allows the use of other primitive types : triangle strips, lines, ... For indexed geometry, use the function glDrawElements() with an index list. */ glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); // Disable states glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(NORMAL_ARRAY); glDisableVertexAttribArray(UV_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); }
/*!**************************************************************************** @Function 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 OGLES2MaximumIntensityBlend::RenderScene() { // Clears the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enable blending glEnable(GL_BLEND); glBlendEquation(GL_MAX_EXT); /* Calculates the frame number to animate in a time-based manner. Uses the shell function PVRShellGetTime() to get the time in milliseconds. */ unsigned long ulTime = PVRShellGetTime(); unsigned long ulDeltaTime = ulTime - m_ulTimePrev; m_ulTimePrev = ulTime; m_fFrame += (float)ulDeltaTime * DEMO_FRAME_RATE; if (m_fFrame > m_Scene.nNumFrame-1) m_fFrame = 0; // Sets the scene animation to this frame m_Scene.SetFrame(m_fFrame); PVRTVec3 vLightDir; { 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.6; /* 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); vLightDir = vFrom; // 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; // Retrieve the list of required uniforms CPVRTPFXEffect* pEffect; SPODMaterial* pMat = &m_Scene.pMaterial[pNode->nIdxMaterial]; if(pMat->nIdxTexDiffuse != -1) { pEffect = m_pEffectTextured; } else { pEffect = m_pEffect; } pEffect->Activate(); const CPVRTArray<SPVRTPFXUniform>& aUniforms = pEffect->GetUniformArray(); /* Now we loop over the uniforms requested by the PFX file. Using the switch statement allows us to handle all of the required semantics */ for(unsigned int j = 0; j < aUniforms.GetSize(); ++j) { switch(aUniforms[j].nSemantic) { case ePVRTPFX_UsPOSITION: { glVertexAttribPointer(aUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); glEnableVertexAttribArray(aUniforms[j].nLocation); } break; case ePVRTPFX_UsNORMAL: { glVertexAttribPointer(aUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); glEnableVertexAttribArray(aUniforms[j].nLocation); } break; case ePVRTPFX_UsUV: { glVertexAttribPointer(aUniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); glEnableVertexAttribArray(aUniforms[j].nLocation); } break; case ePVRTPFX_UsWORLDVIEWPROJECTION: { PVRTMat4 mWVP; // Passes the world-view-projection matrix (WVP) to the shader to transform the vertices mWVP = m_mProjection * mWorldView; glUniformMatrix4fv(aUniforms[j].nLocation, 1, GL_FALSE, mWVP.f); } break; case eUsINTENSITY: { int iMat = pNode->nIdxMaterial; SPODMaterial* pMat = &m_Scene.pMaterial[iMat]; float fIntensity = pMat->pfMatDiffuse[0]; // Take R value for intensity glUniform1f(aUniforms[j].nLocation, fIntensity); } break; case ePVRTPFX_UsTEXTURE: { glUniform1i(aUniforms[j].nLocation, 0); } break; case ePVRTPFX_UsWORLDVIEWIT: { PVRTMat3 mWorldViewIT3x3(mWorldView.inverse().transpose()); glUniformMatrix3fv(aUniforms[j].nLocation, 1, GL_FALSE, mWorldViewIT3x3.f); } break; case ePVRTPFX_UsLIGHTDIREYE: { PVRTVec4 vLightDirView = (m_mView * PVRTVec4(-vLightDir, 1.0f)).normalize(); glUniform3fv(aUniforms[j].nLocation, 1, vLightDirView.ptr()); } break; } } /* Now that the model-view matrix is set and the materials ready, call another function to actually draw the mesh. */ DrawMesh(pMesh); glBindBuffer(GL_ARRAY_BUFFER, 0); /* Now disable all of the enabled attribute arrays that the PFX requested. */ for(unsigned int j = 0; j < aUniforms.GetSize(); ++j) { switch(aUniforms[j].nSemantic) { case ePVRTPFX_UsNORMAL: case ePVRTPFX_UsUV: case ePVRTPFX_UsPOSITION: { glDisableVertexAttribArray(aUniforms[j].nLocation); } break; } } } // Reset blending // Enable blending glBlendEquation(GL_FUNC_ADD); glDisable(GL_BLEND); // Determine which title to show. The default title is quite long, so we display a shortened version if // it cannot fit on the screen. const char* pszTitle = NULL; { bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); float fW, fH; m_Print3D.MeasureText(&fW, &fH, 1.0f, c_pszTitle); int iScreenW = bRotate ? PVRShellGet(prefHeight) : PVRShellGet(prefWidth); if((int)fW >= iScreenW) { pszTitle = c_pszTitleShort; } else { pszTitle = c_pszTitle; } } // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle(pszTitle, "", 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 OGLES3DisplacementMap::RenderScene() { // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Calculates the the time since the last frame unsigned long ulTime = PVRShellGetTime(); unsigned long ulDeltaTime = ulTime - m_ulTimePrev; m_ulTimePrev = ulTime; // Use shader program glUseProgram(m_ShaderProgram.uiId); // Enable 2D texturing for the first texture. glActiveTexture(GL_TEXTURE0); // Set the sampler2D variable to the first texture unit glUniform1i(m_ShaderProgram.uiTexture, 0); // Enable 2D texturing for the second texture. glActiveTexture(GL_TEXTURE1); // Set the displacement map variable to the second texture unit glUniform1i(m_ShaderProgram.uiDisMap, 1); // Calculate and set the displacement factor if(m_bGrow) { m_DisplacementFactor += (float)ulDeltaTime * g_fDemoFrameRate; if(m_DisplacementFactor > 25.0f) { m_bGrow = false; m_DisplacementFactor = 25.0f; } } else { m_DisplacementFactor -= (float)ulDeltaTime * g_fDemoFrameRate; if(m_DisplacementFactor < 0.0f) { m_bGrow = true; m_DisplacementFactor = 0.0f; } } glUniform1f(m_ShaderProgram.uiDisplacementFactor, m_DisplacementFactor); // Bind the displacement map texture glBindTexture(GL_TEXTURE_2D, m_uiDisMapID); // Now the displacement map texture is bound set the active texture to texture 0 glActiveTexture(GL_TEXTURE0); // Draw the scene // Enable the vertex attribute arrays glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(NORMAL_ARRAY); glEnableVertexAttribArray(TEXCOORD_ARRAY); 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 = m_View * mWorld; mMVP = m_Projection * 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() * m_LightDir; PVRTVec3 vLightDirModel = *(PVRTVec3*) vLightDir.ptr(); vLightDirModel.normalize(); glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vLightDirModel.x); // Load the correct texture for the mesh 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 ready, call another function to actually draw the mesh. */ DrawMesh(i); } // Safely disable the vertex attribute arrays glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(NORMAL_ARRAY); glDisableVertexAttribArray(TEXCOORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Display the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("DisplacementMapping", "", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }