/*!**************************************************************************** @Function RenderScene @Return bool true if no error occured @Description Main rendering loop function of the program. The shell will call this function every frame. eglSwapBuffers() will be performed by PVRShell automatically. PVRShell will also manage important OS events. Will also manage relevent OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLESParticles::RenderScene() { int i; PVRTMat4 mRotY; // Clear colour and depth buffers myglClearColor(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enables depth testing glEnable(GL_DEPTH_TEST); // Modify per-frame variables controlling the particle mouvements. float fSpeedCtrl = (float) (PVRTFSIN(m_fRot*0.01f)+1.0f)/2.0f; float fStopNo = 0.8f; float fStep = 0.1f; if(fSpeedCtrl > fStopNo) fStep = 0.0f; // Generate particles as needed. if((m_i32NumParticles < (int) g_ui32MaxParticles) && (fSpeedCtrl <= fStopNo)) { int num_to_gen = (int) (RandPositiveFloat()*(g_ui32MaxParticles/100.0)); if(num_to_gen == 0) num_to_gen = 1; for(i = 0; (i < num_to_gen) && (m_i32NumParticles < (int) g_ui32MaxParticles); ++i) SpawnParticle(&m_Particles[m_i32NumParticles++]); } // Build rotation matrix around axis Y. mRotY = PVRTMat4::RotationY(f2vt((m_fRot2*PVRT_PIf)/180.0f)); for(i = 0; i < m_i32NumParticles; ++i) { // Transform particle with rotation matrix m_sParticleVTXPSBuf[i].x = VERTTYPEMUL(mRotY.f[ 0], m_Particles[i].m_fPosition.x) + VERTTYPEMUL(mRotY.f[ 4], m_Particles[i].m_fPosition.y) + VERTTYPEMUL(mRotY.f[ 8], m_Particles[i].m_fPosition.z) + mRotY.f[12]; m_sParticleVTXPSBuf[i].y = VERTTYPEMUL(mRotY.f[ 1], m_Particles[i].m_fPosition.x) + VERTTYPEMUL(mRotY.f[ 5], m_Particles[i].m_fPosition.y) + VERTTYPEMUL(mRotY.f[ 9], m_Particles[i].m_fPosition.z) + mRotY.f[13]; m_sParticleVTXPSBuf[i].z = VERTTYPEMUL(mRotY.f[ 2], m_Particles[i].m_fPosition.x) + VERTTYPEMUL(mRotY.f[ 6], m_Particles[i].m_fPosition.y) + VERTTYPEMUL(mRotY.f[10], m_Particles[i].m_fPosition.z) + mRotY.f[14]; m_sParticleVTXPSBuf[i].fSize = m_Particles[i].m_fSize; m_sNormalColour[i].r = vt2b(m_Particles[i].m_fColour.x); m_sNormalColour[i].g = vt2b(m_Particles[i].m_fColour.y); m_sNormalColour[i].b = vt2b(m_Particles[i].m_fColour.z); m_sNormalColour[i].a = (unsigned char)255; m_sReflectColour[i].r = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.x, g_fFactor)); m_sReflectColour[i].g = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.y, g_fFactor)); m_sReflectColour[i].b = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.z, g_fFactor)); m_sReflectColour[i].a = (unsigned char)255; } glBindBuffer(GL_ARRAY_BUFFER, m_i32VertVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SVtxPointSprite)*m_i32NumParticles, m_sParticleVTXPSBuf,GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_i32ColAVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sNormalColour,GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_i32ColBVboID); glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sReflectColour,GL_DYNAMIC_DRAW); // clean up render states glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); // Draw floor. // Save modelview matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); myglRotate(f2vt(-m_fRot), f2vt(0.0f), f2vt(1.0f), f2vt(0.0f)); // setup render states glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); // Set texture and texture environment glBindTexture(GL_TEXTURE_2D, m_ui32FloorTexName); glBlendFunc(GL_ONE, GL_ONE); // Render floor RenderFloor(); // clean up render states glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glPopMatrix(); // Render particles reflections. // set up render states glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDepthFunc(GL_ALWAYS); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); myglTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindTexture(GL_TEXTURE_2D, m_ui32TexName); // Set model view matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); myglScale(f2vt(1.0f), f2vt(-1.0f), f2vt(1.0f)); myglTranslate(f2vt(0.0f), f2vt(0.01f), f2vt(0.0f)); glEnable(GL_POINT_SPRITE_OES); if(((int)(m_i32NumParticles * 0.5f)) > 0) RenderParticle(((int)(m_i32NumParticles*0.5f)),true); glPopMatrix(); // Render particles. // Sets the model view matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); if(m_i32NumParticles > 0) RenderParticle(m_i32NumParticles,false); glPopMatrix(); glDisable(GL_POINT_SPRITE_OES); PVRTVec3 Force = PVRTVec3(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f)); Force.x = f2vt(1000.0f*(float)PVRTFSIN(m_fRot*0.01f)); for(i = 0; i < m_i32NumParticles; ++i) { /* Move the particle. If the particle exceeds its lifetime, create a new one in its place. */ if(m_Particles[i].Step(f2vt(fStep), Force)) SpawnParticle(&m_Particles[i]); } // clean up render states glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); // Increase rotation angles m_fRot += 1; m_fRot2 = m_fRot + 36; // Unbinds the vertex buffer if we are using OpenGL ES 1.1 glBindBuffer(GL_ARRAY_BUFFER, 0); // Display info text. m_Print3D.DisplayDefaultTitle("Particles", "Using point sprites", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; }
/*!**************************************************************************** @Function RenderScene @Return bool true if no error 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 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 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 OGLESAntialiasedLines::RenderScene() { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // set up render states glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, m_uiTexture); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); // translate to centre, animate rotation and scale glMatrixMode(GL_MODELVIEW); glLoadIdentity(); myglTranslate(f2vt(m_iWidth * 0.5f), f2vt(m_iHeight * 0.5f), f2vt(0)); unsigned long ulTime = PVRShellGetTime() % 36000; myglRotate(f2vt(ulTime * 0.01f), f2vt(0), f2vt(0), f2vt(1)); float fScale = vt2f(PVRTSIN(VERTTYPEMUL(PVRT_PI, f2vt(ulTime / 9000.f)))) * 0.5f + 0.6f; myglScale(f2vt(fScale), f2vt(fScale), f2vt(1)); if ((ulTime / 2250) & 1) { // render aliased lines glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[2]); glVertexPointer(2, VERTTYPEENUM, sizeof(SVertex), (GLvoid*)offsetof(SVertex, vPosition)); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(SVertex), (GLvoid*)offsetof(SVertex, uiColor)); glLineWidth(c_fLineWidth * fScale); glDrawArrays(GL_LINES, 0, c_iNumLines * 2); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); m_Print3D.DisplayDefaultTitle("Antialiased Lines", "GL_LINES (aliased)", ePVRTPrint3DSDKLogo); } else { // Render antialiased lines with blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiVbos[1]); glVertexPointer(2, VERTTYPEENUM, sizeof(STexVertex), (GLvoid*)offsetof(STexVertex, vPosition)); glTexCoordPointer(2, VERTTYPEENUM, sizeof(STexVertex), (GLvoid*)offsetof(STexVertex, vTexcoord)); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(STexVertex), (GLvoid*)offsetof(STexVertex, uiColor)); glDrawElements(GL_TRIANGLES, c_iNumLines * 18, GL_UNSIGNED_SHORT, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_BLEND); m_Print3D.DisplayDefaultTitle("Antialiased Lines", "Textured rectangles (antialiased)", ePVRTPrint3DSDKLogo); } // Flush all Print3D commands m_Print3D.Flush(); return true; }