/*!**************************************************************************** @Function DrawMesh @Input i32NodeIndex Node index of the mesh to draw @Description Draws a SPODMesh. ******************************************************************************/ void OGLESFur::DrawMesh(int i32NodeIndex) { PVRTMat4 mWorld; glPushMatrix(); // Setup the transformation for this mesh m_Scene.GetWorldMatrix(mWorld, m_Scene.pNode[i32NodeIndex]); myglMultMatrix(mWorld.f); // Get the mesh int ui32MeshID = m_Scene.pNode[i32NodeIndex].nIdx; SPODMesh* pMesh = &m_Scene.pMesh[ui32MeshID]; // bind the VBO for the mesh glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[ui32MeshID]); // bind the index buffer, won't hurt if the handle is 0 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[ui32MeshID]); glVertexPointer(3, VERTTYPEENUM, pMesh->sVertex.nStride, pMesh->sVertex.pData); glNormalPointer(VERTTYPEENUM, pMesh->sNormals.nStride, pMesh->sNormals.pData); // Do we have texture co-ordinates if(pMesh->nNumUVW != 0) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, VERTTYPEENUM, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); }else glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Indexed Triangle list glDrawElements(GL_TRIANGLES, pMesh->nNumFaces * 3, GL_UNSIGNED_SHORT, 0); // unbind the vertex buffers as we don't need them bound anymore glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glPopMatrix(); }
/*!**************************************************************************** @Function DrawDuck @Description Draws duck. ******************************************************************************/ void OGLESFur::DrawDuck() { glPushMatrix(); // Apply the transformation for the duck myglMultMatrix(m_mDuckWorld.f); // Draw the duck body SetMaterial(&c_pMaterial[3], m_aTexIDs[eTexSkin]); DrawMesh(eDuckBody); // Draw the duck's eyes SetMaterial(&c_pMaterial[1], 0); DrawMesh(eDuckEyeL); DrawMesh(eDuckEyeR); // Draw his beak SetMaterial(&c_pMaterial[2], 0); DrawMesh(eDuckBeak); // Draw the fur shells DrawFurShells(); glPopMatrix(); }
/*!**************************************************************************** @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 OGLESParticles::InitView() { PVRTMat4 mProjection; SPVRTContext sContext; bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); // Initialize Print3D textures if(m_Print3D.SetTextures(&sContext, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D.\n"); return false; } // Initialize Extensions m_Extensions.LoadExtensions(); // Load textures. if(PVRTTextureLoadFromPVR(c_szLightTexFile, &m_ui32TexName) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot load light texture.\n"); return false; } myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if(PVRTTextureLoadFromPVR(c_szFloorTexFile, &m_ui32FloorTexName) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot load floor texture.\n"); return false; } myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(bRotate) myglRotate(f2vt(90), f2vt(0), f2vt(0), f2vt(1)); // Creates the projection matrix. mProjection = PVRTMat4::PerspectiveFovRH(f2vt(45.0f*(PVRT_PIf/180.0f)), f2vt((float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight)), f2vt(10.0f), f2vt(1200.0f), PVRTMat4::OGL); myglMultMatrix(mProjection.f); // Calculates the attenuation coefficient for the points drawn. double H = bRotate ? PVRShellGet(prefWidth) : PVRShellGet(prefHeight); double h = 2.0 / mProjection.f[5]; double D0 = sqrt(2.0) * H / h; double k = 1.0/(1.0 + 2.0 * (1 / mProjection.f[5]) * (1 / mProjection.f[5])); m_fPointAttenuationCoef = (float)(1.0 / (D0 * D0) * k); // Creates the model view matrix. m_mView = PVRTMat4::LookAtRH(m_fFrom, m_fTo, g_fUp); glMatrixMode(GL_MODELVIEW); myglLoadMatrix(m_mView.f); /* Pre-Set TexCoords since they never change. Pre-Set the Index Buffer. */ for(unsigned int i = 0; i < g_ui32MaxParticles; ++i) { m_sParticleVTXBuf[i*4+0].u = 0; m_sParticleVTXBuf[i*4+0].v = 0; m_sParticleVTXBuf[i*4+1].u = 1; m_sParticleVTXBuf[i*4+1].v = 0; m_sParticleVTXBuf[i*4+2].u = 0; m_sParticleVTXBuf[i*4+2].v = 1; m_sParticleVTXBuf[i*4+3].u = 1; m_sParticleVTXBuf[i*4+3].v = 1; m_ui16ParticleINDXBuf[i*6+0] = (i*4) + 0; m_ui16ParticleINDXBuf[i*6+1] = (i*4) + 1; m_ui16ParticleINDXBuf[i*6+2] = (i*4) + 2; m_ui16ParticleINDXBuf[i*6+3] = (i*4) + 2; m_ui16ParticleINDXBuf[i*6+4] = (i*4) + 1; m_ui16ParticleINDXBuf[i*6+5] = (i*4) + 3; } // Create vertex buffers. glGenBuffers(1, &m_i32VertVboID); glGenBuffers(1, &m_i32ColAVboID); glGenBuffers(1, &m_i32ColBVboID); glGenBuffers(1, &m_i32QuadVboID); // Preset the floor uvs and vertices as they never change. PVRTVec3 pos(0, 0, 0); float szby2 = 100; m_sQuadVTXBuf[0].x = m_fFloorQuadVerts[0] = pos.x - f2vt(szby2); m_sQuadVTXBuf[0].y = m_fFloorQuadVerts[1] = pos.y; m_sQuadVTXBuf[0].z = m_fFloorQuadVerts[2] = pos.z - f2vt(szby2); m_sQuadVTXBuf[1].x = m_fFloorQuadVerts[3] = pos.x + f2vt(szby2); m_sQuadVTXBuf[1].y = m_fFloorQuadVerts[4] = pos.y; m_sQuadVTXBuf[1].z = m_fFloorQuadVerts[5] = pos.z - f2vt(szby2); m_sQuadVTXBuf[2].x = m_fFloorQuadVerts[6] = pos.x - f2vt(szby2); m_sQuadVTXBuf[2].y = m_fFloorQuadVerts[7] = pos.y; m_sQuadVTXBuf[2].z = m_fFloorQuadVerts[8] = pos.z + f2vt(szby2); m_sQuadVTXBuf[3].x = m_fFloorQuadVerts[9] = pos.x + f2vt(szby2); m_sQuadVTXBuf[3].y = m_fFloorQuadVerts[10] = pos.y; m_sQuadVTXBuf[3].z = m_fFloorQuadVerts[11] = pos.z + f2vt(szby2); m_fFloorQuadUVs[0] = f2vt(0); m_fFloorQuadUVs[1] = f2vt(0); m_sQuadVTXBuf[0].u = 0; m_sQuadVTXBuf[0].v = 0; m_fFloorQuadUVs[2] = f2vt(1); m_fFloorQuadUVs[3] = f2vt(0); m_sQuadVTXBuf[1].u = 255; m_sQuadVTXBuf[1].v = 0; m_fFloorQuadUVs[4] = f2vt(0); m_fFloorQuadUVs[5] = f2vt(1); m_sQuadVTXBuf[2].u = 0; m_sQuadVTXBuf[2].v = 255; m_fFloorQuadUVs[6] = f2vt(1); m_fFloorQuadUVs[7] = f2vt(1); m_sQuadVTXBuf[3].u = 255; m_sQuadVTXBuf[3].v = 255; glBindBuffer(GL_ARRAY_BUFFER, m_i32QuadVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SVtx) * 4, m_sQuadVTXBuf, GL_STATIC_DRAW); return true; }
/*!**************************************************************************** @Function RenderScene @Return bool true if no error occured @Description Main rendering loop function of the program. The shell will call this function every frame. eglSwapBuffers() will be performed by PVRShell automatically. PVRShell will also manage important OS events. Will also manage relevent OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLESEvilSkull::RenderScene() { unsigned int i; float fCurrentfJawRotation, fCurrentfBackRotation; float fFactor, fInvFactor; // Update Skull Weights and Rotations using Animation Info if(m_i32Frame > g_fExprTime) { m_i32Frame = 0; m_i32BaseAnim = m_i32TargetAnim; ++m_i32TargetAnim; if(m_i32TargetAnim > 6) { m_i32TargetAnim = 0; } } fFactor = float(m_i32Frame) / g_fExprTime; fInvFactor = 1.0f - fFactor; m_fSkullWeights[0] = (m_fExprTable[0][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[0][m_i32TargetAnim] * fFactor); m_fSkullWeights[1] = (m_fExprTable[1][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[1][m_i32TargetAnim] * fFactor); m_fSkullWeights[2] = (m_fExprTable[2][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[2][m_i32TargetAnim] * fFactor); m_fSkullWeights[3] = (m_fExprTable[3][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[3][m_i32TargetAnim] * fFactor); fCurrentfJawRotation = m_fJawRotation[m_i32BaseAnim] * fInvFactor + (m_fJawRotation[m_i32TargetAnim] * fFactor); fCurrentfBackRotation = m_fBackRotation[m_i32BaseAnim] * fInvFactor + (m_fBackRotation[m_i32TargetAnim] * fFactor); // Update Base Animation Value - FrameBased Animation for now ++m_i32Frame; // Update Skull Vertex Data using Animation Params for(i = 0; i < m_Scene.pMesh[eSkull].nNumVertex * 3; ++i) { m_pMorphedVertices[i]= f2vt(m_pAVGVertices[i] + (m_pDiffVertices[0][i] * m_fSkullWeights[0]) \ + (m_pDiffVertices[1][i] * m_fSkullWeights[1]) \ + (m_pDiffVertices[2][i] * m_fSkullWeights[2]) \ + (m_pDiffVertices[3][i] * m_fSkullWeights[3])); } // Buffer Clear glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Render Skull and Jaw Opaque with Lighting glDisable(GL_BLEND); // Opaque = No Blending glEnable(GL_LIGHTING); // Lighting On // Set skull and jaw texture glBindTexture(GL_TEXTURE_2D, m_ui32Texture[1]); // Enable and set vertices, normals and index data glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Render Animated Jaw - Rotation Only glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); myglMultMatrix(m_mView.f); myglTranslate(f2vt(0),f2vt(-50.0f),f2vt(-50.0f)); myglRotate(f2vt(-fCurrentfJawRotation), f2vt(1.0f), f2vt(0.0f), f2vt(0.0f)); myglRotate(f2vt(fCurrentfJawRotation) - f2vt(30.0f), f2vt(0), f2vt(1.0f), f2vt(-1.0f)); RenderJaw(); glPopMatrix(); // Render Morphed Skull glPushMatrix(); myglRotate(f2vt(fCurrentfJawRotation) - f2vt(30.0f), f2vt(0), f2vt(1.0f), f2vt(-1.0f)); RenderSkull(); // Render Eyes and Background with Alpha Blending and No Lighting glEnable(GL_BLEND); // Enable Alpha Blending glDisable(GL_LIGHTING); // Disable Lighting // Disable the normals as they aren't needed anymore glDisableClientState(GL_NORMAL_ARRAY); // Render Eyes using Skull Model Matrix DrawQuad(-30.0f ,0.0f ,50.0f ,20.0f , m_ui32Texture[0]); DrawQuad( 33.0f ,0.0f ,50.0f ,20.0f , m_ui32Texture[0]); glPopMatrix(); // Render Dual Texture Background with different base color, rotation, and texture rotation glPushMatrix(); glDisable(GL_BLEND); // Disable Alpha Blending myglColor4(f2vt(0.7f+0.3f*((m_fSkullWeights[0]))), f2vt(0.7f), f2vt(0.7f), f2vt(1.0f)); // Animated Base Color myglTranslate(f2vt(10.0f), f2vt(-50.0f), f2vt(0.0f)); myglRotate(f2vt(fCurrentfBackRotation*4.0f),f2vt(0),f2vt(0),f2vt(-1.0f)); // Rotation of Quad // Animated Texture Matrix glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); myglTranslate(f2vt(-0.5f), f2vt(-0.5f), f2vt(0.0f)); myglRotate(f2vt(fCurrentfBackRotation*-8.0f), f2vt(0), f2vt(0), f2vt(-1.0f)); myglTranslate(f2vt(-0.5f), f2vt(-0.5f), f2vt(0.0f)); // Draw Geometry DrawDualTexQuad (0.0f ,0.0f ,-100.0f ,300.0f, m_ui32Texture[3], m_ui32Texture[2]); // Disable Animated Texture Matrix glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); // Make sure to disable the arrays glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glMatrixMode(GL_MODELVIEW); glPopMatrix(); // Reset Colour myglColor4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f)); // Display info text m_Print3D.DisplayDefaultTitle("EvilSkull", "Morphing.", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }
/******************************************************************************* * Function Name : RenderScene * Returns : true if no error occured * Description : Main rendering loop function of the program. The shell will * call this function every frame. *******************************************************************************/ bool OGLESVase::RenderScene() { PVRTMat4 RotationMatrix, RotateX, RotateY; // Increase rotation angles m_fAngleX += VERTTYPEDIV(PVRT_PI, f2vt(100.0f)); m_fAngleY += VERTTYPEDIV(PVRT_PI, f2vt(150.0f)); if(m_fAngleX >= PVRT_PI) m_fAngleX -= PVRT_TWO_PI; if(m_fAngleY >= PVRT_PI) m_fAngleY -= PVRT_TWO_PI; // Clear the buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Setup the vase rotation // Calculate rotation matrix RotateX = PVRTMat4::RotationX(m_fAngleX); RotateY = PVRTMat4::RotationY(m_fAngleY); RotationMatrix = RotateY * RotateX; // Modelview matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); myglTranslate(f2vt(0.0f), f2vt(0.0f), f2vt(-200.0f)); myglMultMatrix(RotationMatrix.f); // Draw the scene // Use PVRTools to draw a background image m_Background.Draw(m_uiBackTex); // Enable client states glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable depth test glEnable(GL_DEPTH_TEST); // Draw vase outer glBindTexture(GL_TEXTURE_2D, m_pui32Textures[m_Scene.pNode[eVase].nIdxMaterial]); DrawReflectiveMesh(m_Scene.pNode[eVase].nIdx, &RotationMatrix); // Draw glass glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, m_pui32Textures[m_Scene.pNode[eGlass].nIdxMaterial]); // Pass 1: only render back faces (model has reverse winding) glFrontFace(GL_CW); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); DrawMesh(m_Scene.pNode[eGlass].nIdx); // Pass 2: only render front faces (model has reverse winding) glCullFace(GL_FRONT); DrawMesh(m_Scene.pNode[eGlass].nIdx); // Disable blending as it isn't needed glDisable(GL_BLEND); // Disable client states glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Display info text m_Print3D.DisplayDefaultTitle("Vase", "Translucency and reflections.", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }
/******************************************************************************* * Function Name : 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]); myglMultMatrix(worldMatrix.f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, m_Texture); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Enable States glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_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; #ifdef ENABLE_LOAD_TIME_STRIP case 2: pMesh = m_Model.pMesh; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[2]); break; #endif } // Used to display interleaved geometry glVertexPointer(3, VERTTYPEENUM, pMesh->sVertex.nStride, pMesh->sVertex.pData); glTexCoordPointer(2, VERTTYPEENUM, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); // Draw glDrawElements(GL_TRIANGLES, pMesh->nNumFaces * 3, GL_UNSIGNED_SHORT, 0); // Disable States glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_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(); }