/*!**************************************************************************** @Function DrawBalloons @Input psProgram Program to use mProjection Projection matrix to use mView View matrix to use pmModels A pointer to an array of model matrices iNum Number of balloons to draw @Description Draws balloons. ******************************************************************************/ void OGLES2Glass::DrawBalloons(Program* psProgram, PVRTMat4 mProjection, PVRTMat4 mView, PVRTMat4* pmModels, int iNum) { // Use shader program glUseProgram(psProgram->uiId); // Bind texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_uiBalloonTex); PVRTMat4 mModelView, mMVP; for (int i = 0; i < iNum; ++i) { mModelView = mView * pmModels[i]; mMVP = mProjection * mModelView; glUniformMatrix4fv(psProgram->auiLoc[eMVMatrix], 1, GL_FALSE, mModelView.ptr()); glUniformMatrix4fv(psProgram->auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr()); // Calculate and set the model space light direction PVRTVec3 vLightDir = pmModels[i].inverse() * PVRTVec4(19, 22, -50, 0); vLightDir = vLightDir.normalize(); glUniform3fv(psProgram->auiLoc[eLightDir], 1, vLightDir.ptr()); // Calculate and set the model space eye position PVRTVec3 vEyePos = mModelView.inverse() * PVRTVec4(0.0f, 0.0f, 0.0f, 1.0f); glUniform3fv(psProgram->auiLoc[eEyePos], 1, vEyePos.ptr()); // Now that the uniforms are set, call another function to actually draw the mesh. DrawMesh(0, &m_Balloon, &m_puiBalloonVbo, &m_puiBalloonIndexVbo, 3); } }
/******************************************************************************* * Function Name : DrawModel * Inputs : iOptim * Description : Draws the balloon *******************************************************************************/ void OGLESOptimizeMesh::DrawModel( int iOptim ) { SPODMesh *pMesh; glMatrixMode(GL_MODELVIEW); glPushMatrix(); PVRTMATRIX worldMatrix; m_Model.GetWorldMatrix(worldMatrix, m_Model.pNode[0]); glMultMatrixf(worldMatrix.f); // Enable States glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); // Set Data Pointers and bing the VBOs switch(iOptim) { default: pMesh = m_Model.pMesh; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[0]); break; case 1: pMesh = m_ModelOpt.pMesh; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[1]); break; } // Load the meshes material properties SPODMaterial& Material = m_Model.pMaterial[m_Model.pNode[0].nIdxMaterial]; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, PVRTVec4(Material.pfMatAmbient, 1.0f).ptr()); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, PVRTVec4(Material.pfMatDiffuse, 1.0f).ptr()); // Used to display interleaved geometry glVertexPointer(3, GL_FLOAT, pMesh->sVertex.nStride, pMesh->sVertex.pData); glNormalPointer(GL_FLOAT, pMesh->sNormals.nStride, pMesh->sNormals.pData); // Draw glDrawElements(GL_TRIANGLES, pMesh->nNumFaces * 3, GL_UNSIGNED_SHORT, 0); // Disable States glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); // unbind the vertex buffers as we don't need them bound anymore glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glPopMatrix(); }
// --------------------------------------------------------------- bool MyPVRDemo::InitApplication() { #ifdef PLATFORM_IOS CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath)); #endif if (m_Model.ReadFromFile(c_szSceneFile) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n"); return false; } assert(enumMODEL_MAX == m_Model.nNumMesh); // Calculate a bounding box around the statue that we can use later on SPODMesh* pMesh = &m_Model.pMesh[m_Model.pNode[enumMODEL_Statue].nIdx]; PVRTBOUNDINGBOX bb; PVRTBoundingBoxComputeInterleaved(&bb, pMesh->pInterleaved, pMesh->nNumVertex, 0, pMesh->sVertex.nStride); // We need to calculate the longest possible length for our bounding box on the X and Z axis (as we're rotating around Y). float fLen[4]; fLen[0] = sqrt(bb.Point[7].x * bb.Point[7].x + bb.Point[7].z * bb.Point[7].z); // FR quadrant fLen[1] = sqrt(bb.Point[3].x * bb.Point[3].x + bb.Point[3].z * bb.Point[3].z); // FL quadrant fLen[2] = sqrt(bb.Point[6].x * bb.Point[6].x + bb.Point[6].z * bb.Point[6].z); // BR quadrant fLen[3] = sqrt(bb.Point[2].x * bb.Point[2].x + bb.Point[2].z * bb.Point[2].z); // BL quadrant float fLongest = max(fLen[0], fLen[1]); fLongest = max(fLongest, fLen[2]); fLongest = max(fLongest, fLen[3]); // Calculate the top left and bottom right of the bounding box in 2D space m_bbStatueTL = PVRTVec4(-fLongest, bb.Point[3].y, bb.Point[3].z, 1.0f); m_bbStatueBR = PVRTVec4( fLongest, bb.Point[5].y, bb.Point[5].z, 1.0f); // Some nice variables m_fAngleY = 0.0f; m_fBloomMulti = 0.3f; m_ulCurrTime = 0; m_fLightAngle = PVRT_PI / 8; // Offset by 22.5degrees to begin with, so we see the shadow slightly offset from behind the model. m_fTexelOffset = 1.0f / RTT_SIZE; float w1 = 0.0555555f; float w2 = 0.2777777f; float intraTexelOffset = (w2 / (w1 + w2)) * m_fTexelOffset; // Weight between 2 texels so that hardware filtering will // interpolate the texels for us. Effectively reducing a 5x5 kernel // to a 3x3. m_fTexelOffset += intraTexelOffset; return true; }
/*!**************************************************************************** @Function DrawBall @Description Draws the reflective and refractive ball onto the screen. ******************************************************************************/ void OGLES2Glass::DrawBall() { // Set model view projection matrix PVRTMat4 mModel, mModelView, mMVP; mModel = PVRTMat4::Scale(6.0f, 6.0f, 6.0f); mModelView = m_mView * mModel; mMVP = m_mProjection * mModelView; // Use shader program glUseProgram(m_aEffectPrograms[m_iEffect].uiId); // Bind textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_uiParaboloidTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, m_uiCubeTex); glUniformMatrix4fv(m_aEffectPrograms[m_iEffect].auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr()); // Set model matrix PVRTMat3 Model3x3 = PVRTMat3(mModel); glUniformMatrix3fv(m_aEffectPrograms[m_iEffect].auiLoc[eMMatrix], 1, GL_FALSE, Model3x3.ptr()); // Set eye position in model space PVRTVec4 vEyePosModel; vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1); glUniform3fv(m_aEffectPrograms[m_iEffect].auiLoc[eEyePos], 1, &vEyePosModel.x); // Now that the uniforms are set, call another function to actually draw the mesh DrawMesh(0, &m_Ball, &m_puiVbo, &m_puiIndexVbo, 2); }
/*!**************************************************************************** @Function RenderFloor @Description Renders the floor as a quad. ******************************************************************************/ void OGLES2ParticleSystem::RenderFloor() { glUseProgram(m_SimpleShaderProgram.uiId); PVRTMat3 mViewIT(m_mView.inverse().transpose()); glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewProjectionMatrixLoc, 1, GL_FALSE, m_mViewProjection.f); glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewMatrixLoc, 1, GL_FALSE, m_mView.f); glUniformMatrix3fv(m_SimpleShaderProgram.iModelViewITMatrixLoc, 1, GL_FALSE, mViewIT.f); PVRTVec3 vLightPosition = m_mView * PVRTVec4(g_caLightPosition, 1.0f); glUniform3fv(m_SimpleShaderProgram.iLightPosition, 1, &vLightPosition.x); // Enable vertex arributes glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(NORMAL_ARRAY); PVRTVec2 minCorner(-100.0f, -100.0f); PVRTVec2 maxCorner( 100.0f, 100.0f); const float afVertexData[] = { minCorner.x, 0.0f, minCorner.y, maxCorner.x, 0.0f, minCorner.y, minCorner.x, 0.0f, maxCorner.y, maxCorner.x, 0.0f, maxCorner.y }; const float afNormalData[] = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, afVertexData); glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, afNormalData); // Draw the quad glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Safely disable the vertex attribute arrays glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(NORMAL_ARRAY); }
/*!**************************************************************************** @Function DrawSkybox @Description Draws the skybox onto the screen. ******************************************************************************/ void OGLES2Glass::DrawSkybox() { glUseProgram(m_SkyboxProgram.uiId); PVRTMat4 mVP = m_mProjection * m_mView; PVRTMat4 mInvVP = mVP.inverseEx(); glUniformMatrix4fv(m_SkyboxProgram.auiLoc[eInvVPMatrix], 1, GL_FALSE, mInvVP.ptr()); PVRTVec3 vEyePos = m_mView.inverse() * PVRTVec4(0, 0, 0, 1); glUniform3fv(m_SkyboxProgram.auiLoc[eEyePos], 1, vEyePos.ptr()); glBindBuffer(GL_ARRAY_BUFFER, m_uiSquareVbo); glEnableVertexAttribArray(VERTEX_ARRAY); glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, m_uiCubeTex); glDrawArrays(GL_TRIANGLES, 0, 6); glDisableVertexAttribArray(VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); }
bool UniformHandler::isVisibleSphere(const PVRTVec3& v3Centre, const VERTTYPE fRadius) { // get in view space PVRTVec4 v4TransCentre = m_mWorldView * PVRTVec4(v3Centre,f2vt(1.0f)); // find clip space coord for centre v4TransCentre = m_mProjection * v4TransCentre; VERTTYPE fRadX,fRadY; // scale radius according to perspective if(m_bRotate) { fRadX = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(0,1))); fRadY = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(1,0))); } else { fRadX = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(0,0))); fRadY = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(1,1))); } VERTTYPE fRadZ = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(2,2))); // check if inside frustums // X if(v4TransCentre.x+fRadX<-v4TransCentre.w) { // 'right' side out to 'left' def out return false; } if(v4TransCentre.x-fRadX>v4TransCentre.w) { // 'left' side out to 'right' def out return false; } // Y if(v4TransCentre.y+fRadY<-v4TransCentre.w) { // 'up' side out to 'top' def out return false; } if(v4TransCentre.y-fRadY>v4TransCentre.w) { // 'down' side out to 'bottom' def out return false; } // Z if(v4TransCentre.z+fRadZ<-v4TransCentre.w) { // 'far' side out to 'back' def out return false; } if(v4TransCentre.z-fRadZ>v4TransCentre.w) { // 'near' side out to 'front' def out return false; } return true; }
OGLESEvilSkull() : m_puiVbo(0), m_puiIndexVbo(0), m_pMorphedVertices(0), m_pAVGVertices(0), m_i32BaseAnim(0), m_i32TargetAnim(1), m_i32Frame(0) { for(unsigned int i = 0; i < g_ui32NoOfMorphTargets; ++i) m_pDiffVertices[i] = 0; // Setup base constants in contructor // Camera and Light details m_LightPos = PVRTVec4(f2vt(-1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(0.0f)); m_CameraPos = PVRTVec3(f2vt(0.0f), f2vt(0.0f), f2vt(300.0f)); m_CameraTo = PVRTVec3(f2vt(0.0f), f2vt(-30.0f), f2vt(0.0f)); m_CameraUp = PVRTVec3(f2vt(0.0f), f2vt(1.0f), f2vt(0.0f)); // Animation Table m_fSkullWeights[0] = 0.0f; m_fSkullWeights[1] = 1.0f; m_fSkullWeights[2] = 0.0f; m_fSkullWeights[3] = 0.0f; m_fSkullWeights[4] = 0.0f; m_fExprTable[0][0] = 1.0f; m_fExprTable[1][0] = 1.0f; m_fExprTable[2][0] = 1.0f; m_fExprTable[3][0] = 1.0f; m_fExprTable[0][1] = 0.0f; m_fExprTable[1][1] = 0.0f; m_fExprTable[2][1] = 0.0f; m_fExprTable[3][1] = 1.0f; m_fExprTable[0][2] = 0.0f; m_fExprTable[1][2] = 0.0f; m_fExprTable[2][2] = 1.0f; m_fExprTable[3][2] = 1.0f; m_fExprTable[0][3] = 0.3f; m_fExprTable[1][3] = 0.0f; m_fExprTable[2][3] = 0.3f; m_fExprTable[3][3] = 0.0f; m_fExprTable[0][4] =-1.0f; m_fExprTable[1][4] = 0.0f; m_fExprTable[2][4] = 0.0f; m_fExprTable[3][4] = 0.0f; m_fExprTable[0][5] = 0.0f; m_fExprTable[1][5] = 0.0f; m_fExprTable[2][5] =-0.7f; m_fExprTable[3][5] = 0.0f; m_fExprTable[0][6] = 0.0f; m_fExprTable[1][6] = 0.0f; m_fExprTable[2][6 ]= 0.0f; m_fExprTable[3][6] =-0.7f; m_fJawRotation[0] = 45.0f; m_fJawRotation[1] = 25.0f; m_fJawRotation[2] = 40.0f; m_fJawRotation[3] = 20.0f; m_fJawRotation[4] = 45.0f; m_fJawRotation[5] = 25.0f; m_fJawRotation[6] = 30.0f; m_fBackRotation[0] = 0.0f; m_fBackRotation[1] = 25.0f; m_fBackRotation[2] = 40.0f; m_fBackRotation[3] = 90.0f; m_fBackRotation[4] = 125.0f; m_fBackRotation[5] = 80.0f; m_fBackRotation[6] = 30.0f; }
/*!**************************************************************************** @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; }
// --------------------------------------------------------------- bool MyPVRDemo::RenderScene() { // --- Work out DT unsigned long ulPrevTime = m_ulCurrTime; m_ulCurrTime = PVRShellGetTime(); m_fDT = ((float)m_ulCurrTime - (float)ulPrevTime) * 0.001f; // Calculate a new light matrix PVRTVec3 vLightPos = PVRTVec4(m_vLightPos, 1.0f) * PVRTMat4::RotationY(m_fLightAngle); m_mxLightView = PVRTMat4::LookAtRH(vLightPos, PVRTVec3(0,25,0), PVRTVec3(0,1,0)); // --- Render the scene from the light's POV RenderShadowScene(); // --- Clear buffers glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); PVRTMat4 mxCam = m_mxCam * PVRTMat4::RotationY(m_fAngleY); PVRTMat4 mxModel = PVRTMat4::Identity(); // --- Draw the Statue glUseProgram(m_StatueShader.uiID); glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_StatueNormals]); RenderStatue(mxModel, mxCam, vLightPos, &m_StatueShader); // --- Draw the Statue reflected glCullFace(GL_FRONT); PVRTMat4 mxModelRefl = PVRTMat4::Scale(1,-1,1) * mxModel; RenderStatue(mxModelRefl, mxCam, vLightPos, &m_StatueShader); glCullFace(GL_BACK); // --- Draw the Floor (with shadow) RenderCurch(mxCam); // --- Render the bloom effect RenderBloom(mxModel, mxCam, vLightPos); // --- Increment the camera angle m_fAngleY += 0.5f * m_fDT; // --- Increment the light angle m_fLightAngle += 0.5f * m_fDT; return true; }
void ShaderEnvMap::UseProgram() { Shader::UseProgram(); glUniform1i(myCubeReflection, false); glUniform1i(my2DMap, 0); glUniform1i(myCubeMap, 1); CameraManager * pCameraManager = CameraManager::GetCameraManager(); Camera * pCurrentCamera = pCameraManager->GetCurrentCamera(); RenderLayerManager & renderManager = RenderLayerManager::GetRenderLayerManager(); Mesh * pCurrentMesh = renderManager.GetCurrentMesh(); PVRTMat4 viewMtx(pCurrentCamera->GetViewMtx().f); static float m_fAngleX = 0.0; static float m_fAngleY = 0.0; PVRTMat4 mModel, mRotX, mRotY; mRotX = PVRTMat4::RotationX(m_fAngleX); mRotY = PVRTMat4::RotationY(m_fAngleY); mModel = mRotY * mRotX; m_fAngleX += 0.01f; //m_fAngleY += 0.011f; //PVRTMat4 meshWorld( pCurrentMesh->GetWorldMtx().f ); PVRTMat4 meshWorld = mModel; PVRTMat4 modelView = viewMtx * meshWorld; // Set model matrix PVRTMat3 model3x3 = PVRTMat3(meshWorld); glUniformMatrix3fv( myModelWorld, 1, GL_FALSE, model3x3.ptr()); // Set eye position in model space PVRTVec4 eyePosModel; eyePosModel = modelView.inverse() * PVRTVec4(0, 0, 0, 1); glUniform3fv(myEyePosModel, 1, &eyePosModel.x); }
/*!**************************************************************************** @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 DrawMesh @Input meshID The number of the mesh to draw @Description Draws a SPODMesh after the model view matrix has been set. Also works out and passes color and ID data to the shader in this case. ******************************************************************************/ void OGLES3EdgeDetection::DrawMesh(unsigned int ui32MeshID) { // Calls the mesh and its material index. SPODMesh& Mesh = m_Scene.pMesh[ui32MeshID]; GLuint ui32MaterialIndex = m_Scene.pNode[ui32MeshID].nIdxMaterial; // Works out an ID Number for the mesh - somewhere between 0 and 1. GLfloat ID = (GLfloat)ui32MeshID/(GLfloat)m_Scene.nNumMeshNode; // Binds color and ID data to the shader program. glUniform4fv(m_PreShader.auiLoc[eColorData], 1, PVRTVec4(m_pvColorData[ui32MaterialIndex],ID).ptr()); // Bind the VBO for the mesh and the index buffer. glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[ui32MeshID]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[ui32MeshID]); // Set the vertex attribute offsets from the mesh glVertexAttribPointer(eVERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sVertex.nStride, Mesh.sVertex.pData); // Indexed Triangle list glDrawElements(GL_TRIANGLES, Mesh.nNumFaces*3, GL_UNSIGNED_SHORT, 0); }
/*!**************************************************************************** @Function RenderSphere @Description Renders a sphere at the specified position. ******************************************************************************/ void OGLES2ParticleSystem::RenderSphere(PVRTVec3 position, float radius) { glUseProgram(m_SimpleShaderProgram.uiId); PVRTMat4 mModel = PVRTMat4::Translation(position) * PVRTMat4::Scale(radius, radius, radius); PVRTMat4 mModelView = m_mView * mModel; PVRTMat4 mModelViewProj = m_mProjection * mModelView; PVRTMat3 mModelViewIT(mModelView.inverse().transpose()); glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewProjectionMatrixLoc, 1, GL_FALSE, mModelViewProj.f); glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewMatrixLoc, 1, GL_FALSE, mModelView.f); glUniformMatrix3fv(m_SimpleShaderProgram.iModelViewITMatrixLoc, 1, GL_FALSE, mModelViewIT.f); PVRTVec3 vLightPosition = m_mView * PVRTVec4(g_caLightPosition, 1.0f); glUniform3fv(m_SimpleShaderProgram.iLightPosition, 1, &vLightPosition.x); // Enable vertex arributes glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(NORMAL_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, m_uiVbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiIbo); SPODMesh* pMesh = &m_Scene.pMesh[0]; glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); // Indexed Triangle list glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0); // Safely disable the vertex attribute arrays glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(NORMAL_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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 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 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 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 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; }
#include "OGLES2Tools.h" /****************************************************************************** Constants ******************************************************************************/ // Camera constants used to generate the projection matrix const float CAM_FOV = PVRT_PI / 6; const float CAM_NEAR = 75.0f; const float g_SomeRotation = 45.0f/(2*PVRT_PI); const PVRTVec3 g_CubeTranslation = PVRTVec3(0.0f, -20.0f, 0.f); const PVRTVec3 g_CubeScale = PVRTVec3(1.4f, 1.4f, 1.4f); const PVRTVec4 g_LightPos = PVRTVec4(0.f, 30.f, 10.f, 1); /****************************************************************************** shader attributes ******************************************************************************/ // vertex attributes enum EVertexAttrib { VERTEX_ARRAY, NORMAL_ARRAY, TEXCOORD_ARRAY, TANGENT_ARRAY, eNumAttribs }; const char* g_aszAttribNames[] = { "vertPos", "vertNormal", "vertUV", "vertTangent" }; // shader uniforms enum EUniform { eModelViewMatrix, eModelViewProj, eNormal, eLightEyeSpacePos, eNumUniforms }; const char* g_aszUniformNames[] = {
/*!**************************************************************************** @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 OGLESRenderToTexture::InitView() { CPVRTString ErrorStr; /* Initialise Print3D */ 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; } // Enables texturing glEnable(GL_TEXTURE_2D); // Initialize VBO data if(!LoadVbos(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } /* Load textures */ if(!LoadTextures(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } // Create a FBO or PBuffer if(!CreateFBOorPBuffer()) return false; // Setup some render states // Enable the depth test glEnable(GL_DEPTH_TEST); // Enable culling glEnable(GL_CULL_FACE); // Setup the material parameters our meshes will use glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, PVRTVec4(1.0f).ptr()); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, PVRTVec4(1.0f).ptr()); // Setup view and projection matrices used for when rendering to the texture // Caculate the view matrix m_mR2TView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 60), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0)); // Calculate the projection matrix // Note: As we'll be rendering to a texture we don't need to take the screen rotation into account m_mR2TProjection = PVRTMat4::PerspectiveFovRH(1, 1, g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, false); // Setup view and projection matrices used for when rendering the main scene // Caculate the view matrix m_mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 125), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0)); // Calculate the projection matrix m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI/6, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate); 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 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; }
//this function creates the vertex position, colour, normal, and tex coordiante values for one cover. void OGLESCoverflow::CreateCover() { unsigned short i, row, col; float width = 6.0f; float height = 6.0f; float heightFromMirror = 0.0f; float dim = 0.5f; //initialise vertices to normalised size, can then also be used as uv coorda and scales up after m_fBorderFraction = 0.00f; float dimLess = 0.5f - (0.5f*m_fBorderFraction);//size minus the fraction of the border PVRTVec3 normal = PVRTVec3(0.0f, 1.0f, 0.0f); //all the normals are the same /* The covers are made up of 16 vertices, 9 quads, 18 triangles. The four colours of the center vertices are fully opaque while all the outside vertices are fully transparent. This produces a thin fade out at the edges which avoids antialiasing. 0--1------2--3 | | | | 4--5------6--7 | | | | | | | | | | | | 8--9-----10--11 | | | | 12-13----14--15 */ m_coverPoints[0].p = PVRTVec3(-dim, dim, 0); m_coverPoints[1].p = PVRTVec3(-dimLess, dim, 0); m_coverPoints[2].p = PVRTVec3(dimLess, dim, 0); m_coverPoints[3].p = PVRTVec3(dim, dim, 0); m_coverPoints[4].p = PVRTVec3(-dim, dimLess, 0); m_coverPoints[5].p = PVRTVec3(-dimLess, dimLess, 0); m_coverPoints[6].p = PVRTVec3(dimLess, dimLess, 0); m_coverPoints[7].p = PVRTVec3(dim, -dimLess, 0); m_coverPoints[8].p = PVRTVec3(-dim, -dimLess, 0); m_coverPoints[9].p = PVRTVec3(-dimLess, -dimLess, 0); m_coverPoints[10].p = PVRTVec3(dimLess, -dimLess, 0); m_coverPoints[11].p = PVRTVec3(dim, -dimLess, 0); m_coverPoints[12].p = PVRTVec3(-dim, -dim, 0); m_coverPoints[13].p = PVRTVec3(-dimLess, -dim, 0); m_coverPoints[14].p = PVRTVec3(dimLess, -dim, 0); m_coverPoints[15].p = PVRTVec3(dim, -dim, 0); for(i = 0; i < 16; ++i) { m_coverPoints[i].n = normal; m_coverPoints[i].c = PVRTVec4(1.0f, 1.0f, 1.0f, 0.0f); //the uvs are matched to the positions (+0.5 for range 0-1) m_coverPoints[i].t.x = m_coverPoints[i].p.x + 0.5f; m_coverPoints[i].t.y = m_coverPoints[i].p.y + 0.5f; //scale up to desired size m_coverPoints[i].p.x = m_coverPoints[i].p.x * width; m_coverPoints[i].p.y = m_coverPoints[i].p.y * height; } //only the center 4 vertices have are fully opaque all the rest around the edge are tranparent m_coverPoints[5].c.w = 1.0f; m_coverPoints[6].c.w = 1.0f; m_coverPoints[9].c.w = 1.0f; m_coverPoints[10].c.w = 1.0f; //create indioes for the 2 triangles for every square int i32NumOpaque = 0; int i32NumBlend = 0; for(row = 0; row < 3; ++row) { for(col = 0; col < 3; ++col) { unsigned short start = (row*4)+col; //the centre indices are kept in a separate buffer to the border ones as they arew going //to be drawn in 2 separate passes. if(row == 1 && col == 1) { m_indicesOpaque[i32NumOpaque++] = start+1; m_indicesOpaque[i32NumOpaque++] = start; m_indicesOpaque[i32NumOpaque++] = start+4; m_indicesOpaque[i32NumOpaque++] = start+1; m_indicesOpaque[i32NumOpaque++] = start+4; m_indicesOpaque[i32NumOpaque++] = start+5; } else { m_indicesBlend[i32NumBlend++] = start+1; m_indicesBlend[i32NumBlend++] = start; m_indicesBlend[i32NumBlend++] = start+4; m_indicesBlend[i32NumBlend++] = start+1; m_indicesBlend[i32NumBlend++] = start+4; m_indicesBlend[i32NumBlend++] = start+5; } } } //adjusted the triangle alignment for two of the corners so that the transparency //falls off in the same direction as the other two corners (comment out to see what i mean!) //top left m_indicesBlend[0] = 1; m_indicesBlend[1] = 0; m_indicesBlend[2] = 5; m_indicesBlend[3] = 0; m_indicesBlend[4] = 4; m_indicesBlend[5] = 5; //bottom right m_indicesBlend[42] = 11; m_indicesBlend[43] = 10; m_indicesBlend[44] = 15; m_indicesBlend[45] = 10; m_indicesBlend[46] = 14; m_indicesBlend[47] = 15; //copy the indices for the mirrored versions for(i = 0; i < 48; ++i) { if(i < 6) { m_indicesOpaque[i+6] = m_indicesOpaque[i] + 16; } m_indicesBlend[i+48] = m_indicesBlend[i] + 16; } i32NumBlend *= 2; i32NumOpaque *= 2; //create the vertex points for the mirrored cover. for(row = 0; row < 4; ++row) { //the colours on the flip vertices are going to fade out the further away from the mirror they are // using the y coordinate of the coverpoints float dark = 1 - ((m_coverPoints[(row*4)].p.y/height)+ 0.5f); dark -= 0.5f; //made a little darker in the reflection to mimic properties of dull mirror for(col = 0; col < 4; ++col) { //copy the vertices with y values reversed for the mirrored equivalents m_coverPoints[((row*4)+col) + 16] = m_coverPoints[((row*4)+col)]; m_coverPoints[((row*4)+col) + 16].p.y = m_coverPoints[((row*4)+col) + 16].p.y * -1.0f; m_coverPoints[((row*4)+col) + 16].p.y -= height + heightFromMirror; m_coverPoints[((row*4)+col) + 16].c.x = dark; m_coverPoints[((row*4)+col) + 16].c.y = dark; m_coverPoints[((row*4)+col) + 16].c.z = dark; } } for(i = 0; i < 96; ++i) { m_indicesAll[i] = m_indicesBlend[i]; } for(i = 0; i < 12; ++i) { m_indicesAll[i+96] = m_indicesOpaque[i]; } glGenBuffers(1, &m_uiVbo); glBindBuffer(GL_ARRAY_BUFFER, m_uiVbo); glBufferData(GL_ARRAY_BUFFER, 32 * sizeof(SVertex), m_coverPoints, GL_STATIC_DRAW); glGenBuffers(1, &m_uiBlendIndexVbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiBlendIndexVbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, i32NumBlend*2, m_indicesBlend, GL_STATIC_DRAW); glGenBuffers(1, &m_uiOpaqueIndexVbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiOpaqueIndexVbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, i32NumOpaque*2, m_indicesOpaque, GL_STATIC_DRAW); glGenBuffers(1, &m_uiAllIndexVbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiAllIndexVbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 108*2, m_indicesAll, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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 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 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 OGLES2LevelOfDetail::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, mRotY, mTrans; float fDistance = 1400.0f * cos(m_fPositionZ) - 1350.0f; mTrans = PVRTMat4::Translation(0.0, 0.0, fDistance); mRotY = PVRTMat4::RotationY(m_fAngleY); mModel = mTrans * mRotY; m_fAngleY += PVRT_PI / 210; m_fPositionZ += 2 * PVRT_PI * 0.0008f; // 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 model matrix PVRTMat3 Model3x3 = PVRTMat3(mModel); glUniformMatrix3fv(m_ShaderProgram.auiLoc[eModelWorld], 1, GL_FALSE, Model3x3.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); // Calculate the square of the pixel area that the mesh takes up on screen // This is done by projecting the vertices of the bounding box to screen space // then taking the axis aligned 2D bounding box of the projected vertices. // This is a very conservative estimate float fMinX, fMaxX, fMinY, fMaxY, fX, fY; ProjectVertex(m_avBoundingBox[0], mMVP, fX, fY); fMinX = fMaxX = fX; fMinY = fMaxY = fY; for (int i = 1; i < 8; ++i) { ProjectVertex(m_avBoundingBox[i], mMVP, fX, fY); fMinX = PVRT_MIN(fMinX, fX); fMinY = PVRT_MIN(fMinY, fY); fMaxX = PVRT_MAX(fMaxX, fX); fMaxY = PVRT_MAX(fMaxY, fY); } // Choose high detail if the mesh bounding box covers more than 2% of the screen m_bHighDetail = ((fMaxX - fMinX) * (fMaxY - fMinY) > 0.02); glUniform1i(m_ShaderProgram.auiLoc[eHighDetail], m_bHighDetail); /* Now that the uniforms are set, call another function to actually draw the mesh. */ DrawMesh(m_bHighDetail ? 0 : 1); // Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools m_Print3D.DisplayDefaultTitle("Level of detail", (m_bHighDetail) ? "Detail: high" : "Detail: low", ePVRTPrint3DLogoIMG); m_Print3D.Flush(); return true; }
/*!**************************************************************************** @Function UpdateFurShells @Description Update the fur shells. This is only called when the number of shells change. ******************************************************************************/ void OGLESFur::UpdateFurShells() { PVRTVec3 *pvSrcN, *pvSrcV; PVRTVec3 vTransNorm; PVRTVec4 vTransPos; SVertex *pvData; int i; unsigned int j; float fDepth, *pUV; int i32MeshIndex = m_Scene.pNode[eDuckBody].nIdx; SPODMesh* pMesh = &m_Scene.pMesh[i32MeshIndex]; PVRTMat4 mModel; PVRTMat3 mModel3; m_Scene.GetWorldMatrix(mModel, m_Scene.pNode[eDuckBody]); mModel3 = PVRTMat3(mModel); pvData = new SVertex[pMesh->nNumVertex]; if(!pvData) return; for(i = 0; i < m_i32FurShellNo; ++i) { fDepth = (c_fFurDepth * (float)(i+1) / (float)m_i32FurShellNo); for(j = 0; j < pMesh->nNumVertex; ++j) { pvSrcN = (PVRTVec3*) (pMesh->pInterleaved + (size_t) pMesh->sNormals.pData + (j * pMesh->sNormals.nStride)); pvSrcV = (PVRTVec3*) (pMesh->pInterleaved + (size_t) pMesh->sVertex.pData + (j * pMesh->sVertex.nStride)); pUV = (float*) (pMesh->pInterleaved + (size_t) pMesh->psUVW[0].pData + (j * pMesh->psUVW[0].nStride)); // Transform the vertex position so it is in world space PVRTVec4 vPos4 = PVRTVec4(*pvSrcV, 1.0f); PVRTTransform(&vTransPos, &vPos4, &mModel); // Transform the vertex normal so it is in world space vTransNorm.x = mModel.f[0] * pvSrcN->x + mModel.f[4] * pvSrcN->y + mModel.f[8] * pvSrcN->z; vTransNorm.y = mModel.f[1] * pvSrcN->x + mModel.f[5] * pvSrcN->y + mModel.f[9] * pvSrcN->z; vTransNorm.z = mModel.f[2] * pvSrcN->x + mModel.f[6] * pvSrcN->y + mModel.f[10]* pvSrcN->z; vTransNorm.normalize(); pvData[j].x = vTransPos.x + (vTransNorm.x * fDepth); pvData[j].y = vTransPos.y + (vTransNorm.y * fDepth); pvData[j].z = vTransPos.z + (vTransNorm.z * fDepth); pvData[j].nx = vTransNorm.x; pvData[j].ny = vTransNorm.y; pvData[j].nz = vTransNorm.z; pvData[j].tu = pUV[0]; pvData[j].tv = pUV[1]; } glBindBuffer(GL_ARRAY_BUFFER, m_uiShellVbo[i]); unsigned int uiSize = pMesh->nNumVertex * sizeof(SVertex); glBufferData(GL_ARRAY_BUFFER, uiSize, pvData, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } delete[] pvData; }
/******************************************************************************* * 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; }
void UniformHandler::CalculateMeshUniform(const Uniform& sUniform, SPODMesh *pMesh, SPODNode *pNode) { switch(sUniform.getSemantic()) { case eUsPosition: { glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsNormal: { glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsTangent: { glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sTangents.nStride, pMesh->sTangents.pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsBinormal: { glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->sBinormals.nStride, pMesh->sBinormals.pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsUV: { glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsBoneIndex: { glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneIdx.n, GL_UNSIGNED_BYTE, GL_FALSE, pMesh->sBoneIdx.nStride, pMesh->sBoneIdx.pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsBoneWeight: { glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneWeight.n, GL_FLOAT, GL_FALSE, pMesh->sBoneWeight.nStride, pMesh->sBoneWeight.pData); glEnableVertexAttribArray(sUniform.getLocation()); } break; case eUsWORLD: { glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorld.f); } break; case eUsWORLDI: { PVRTMat4 mWorldI; mWorldI = m_mWorld.inverse(); glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldI.f); } break; case eUsWORLDIT: { PVRTMat3 mWorldIT; mWorldIT = m_mWorld.inverse().transpose(); glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldIT.f); } break; case eUsWORLDVIEW: { glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldView.f); } break; case eUsWORLDVIEWI: { PVRTMat4 mWorldViewI; mWorldViewI = m_mWorldView.inverse(); glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewI.f); } break; case eUsWORLDVIEWIT: { PVRTMat3 mWorldViewIT; mWorldViewIT = m_mWorldView.inverse().transpose(); glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewIT.f); } break; case eUsWORLDVIEWPROJECTION: { glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldViewProjection.f); } break; case eUsWORLDVIEWPROJECTIONI: { PVRTMat4 mWorldViewProjectionI = (m_mProjection * m_mWorldView ).inverse(); glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionI.f); } break; case eUsWORLDVIEWPROJECTIONIT: { PVRTMat3 mWorldViewProjectionIT = (m_mProjection * m_mWorldView).inverse().transpose(); glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionIT.f); } break; case eUsLIGHTPOSMODEL: { // Passes the light position in eye space to the shader Light* pLight = m_pLightManager->get(sUniform.getIdx()); switch(pLight->getType()) { case eLightTypePoint: { PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPoint*)pLight)->getPositionPVRTVec4() ; glUniform3f(sUniform.getLocation(), vLightPosModel.x, vLightPosModel.y, vLightPosModel.z); } break; case eLightTypePODPoint: { PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPODPoint*)pLight)->getPositionPVRTVec4() ; glUniform3f(sUniform.getLocation(), vLightPosModel.x, vLightPosModel.y, vLightPosModel.z); } break; default: { // hack for directional lights // take the light direction and multiply it by a really big negative number // if you hit this code then the types of your lights do not match the types expected by your shaders PVRTVec4 vLightPosModel = (((LightDirectional*)pLight)->getDirectionPVRTVec4()*c_fFarDistance) ; vLightPosModel.w = f2vt(1.0f); vLightPosModel = m_mWorld * vLightPosModel; glUniform3f(sUniform.getLocation(), vLightPosModel.x, vLightPosModel.y, vLightPosModel.z); } } } break; case eUsOBJECT: { // Scale PVRTMat4 mObject = m_psScene->GetScalingMatrix(*pNode); // Rotation mObject = m_psScene->GetRotationMatrix(*pNode) * mObject; // Translation mObject = m_psScene->GetTranslationMatrix(*pNode) * mObject; glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mObject.f); } break; case eUsOBJECTI: { if(!getFlag(eUsOBJECT)) { // Scale m_mObject = m_psScene->GetScalingMatrix(*pNode); // Rotation m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject; // Translation m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject); setFlag(eUsOBJECT); } m_mObjectI = m_mObject.inverse(); glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectI.f); } break; case eUsOBJECTIT: { if(!getFlag(eUsOBJECTI)) { if(!getFlag(eUsOBJECT)) { // Scale m_mObject = m_psScene->GetScalingMatrix(*pNode); // Rotation m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject; // Translation m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject); setFlag(eUsOBJECT); } m_mObjectI = m_mObject.inverse(); setFlag(eUsOBJECTI); } m_mObjectIT = PVRTMat3(m_mObjectI).transpose(); glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectIT.f); } break; case eUsLIGHTDIRMODEL: { Light* pLight = m_pLightManager->get(sUniform.getIdx()); switch(pLight->getType()) { case eLightTypeDirectional: { // Passes the light direction in model space to the shader PVRTVec4 vLightDirectionModel, vLightDirection =((LightDirectional*)pLight)->getDirectionPVRTVec4(); vLightDirectionModel = m_mWorld.inverse() * vLightDirection ; glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z); } case eLightTypePODDirectional: { // Passes the light direction in model space to the shader PVRTVec4 vLightDirectionModel, vLightDirection =((LightPODDirectional*)pLight)->getDirectionPVRTVec4(); vLightDirectionModel = m_mWorld.inverse() * vLightDirection ; glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z); } default: { // could mimic point lights // calculate vector between light position and mesh // implemented by getting hold of the nice centre point I calculated for all these meshes and using this point } } } break; case eUsEYEPOSMODEL: { m_vEyePositionModel = m_mWorld.inverse() * PVRTVec4(m_vEyePositionWorld,VERTTYPE(1.0f)); glUniform3f(sUniform.getLocation(), m_vEyePositionModel.x, m_vEyePositionModel.y, m_vEyePositionModel.z); } break; default: { // something went wrong ConsoleLog::inst().log("Error: non-mesh uniform being interpreted as mesh uniform\n"); return; } } }