/*!**************************************************************************** @Function Clamp @Input X number to Clamp @Return VERTTYPE Clamped number @Description Clamps the argument to 0-255. ******************************************************************************/ VERTTYPE OGLESParticles::Clamp(VERTTYPE X) { if(X < f2vt(0.0f)) X = f2vt(0.0f); else if(X > f2vt(255.0f)) X = f2vt(255.0f); return X; }
PVRTVec3 SimpleCamera::getUp() const { PVRTVec3 vUp(f2vt(0.0f),f2vt(1.0f),f2vt(0.0f)); PVRTMat3 mRotY = PVRTMat3::RotationY(m_fHeading); PVRTMat3 mRotX = PVRTMat3::RotationX(m_fElevation); vUp = (vUp*mRotX)*mRotY; return vUp; }
PVRTVec3 SimpleCamera::getTo() const { PVRTVec3 vTo(f2vt(0.0f),f2vt(0.0f),f2vt(1.0f)); PVRTMat3 mRotY = PVRTMat3::RotationY(m_fHeading); PVRTMat3 mRotX = PVRTMat3::RotationX(m_fElevation); vTo = (vTo*mRotX)*mRotY; return vTo; }
/*!*************************************************************************** @Function Rotate @Description Rotates vertices in model space. *****************************************************************************/ void CPVRTPrint3D::Rotate(SPVRTPrint3DAPIVertex * const pv, const unsigned int nCnt) { unsigned int i; VERTTYPE x, y; for(i = 0; i < nCnt; ++i) { x = VERTTYPEDIV((VERTTYPE&)pv[i].sx, f2vt(640.0f * m_fScreenScale[0])); y = VERTTYPEDIV((VERTTYPE&)pv[i].sy, f2vt(480.0f * m_fScreenScale[1])); (VERTTYPE&)pv[i].sx = VERTTYPEMUL(y, f2vt(640.0f * m_fScreenScale[0])); (VERTTYPE&)pv[i].sy = VERTTYPEMUL(f2vt(1.0f) - x, f2vt(480.0f * m_fScreenScale[1])); } }
/*!**************************************************************************** @Function DrawReflectiveMesh @Input ui32MeshID ID of mesh to draw @Input pNormalTx Rotation matrix @Description Draws a mesh with the reflection ******************************************************************************/ void OGLESVase::DrawReflectiveMesh(unsigned int ui32MeshID, PVRTMat4 *pNormalTx) { SPODMesh& Mesh = m_Scene.pMesh[ui32MeshID]; VERTTYPE *pUVs = new VERTTYPE[2 * Mesh.nNumVertex]; PVRTMat4 EnvMapMatrix; unsigned int i; // Calculate matrix for environment mapping: simple multiply by 0.5 for(i = 0; i < 16; ++i) EnvMapMatrix.f[i] = VERTTYPEMUL(pNormalTx->f[i], f2vt(0.5f)); unsigned char* pNormals = Mesh.pInterleaved + (size_t) Mesh.sNormals.pData; /* Calculate UVs for environment mapping */ for(i = 0; i < Mesh.nNumVertex; ++i) { VERTTYPE *pVTNormals = (VERTTYPE*) pNormals; pUVs[2*i] = VERTTYPEMUL(pVTNormals[0], EnvMapMatrix.f[0]) + VERTTYPEMUL(pVTNormals[1], EnvMapMatrix.f[4]) + VERTTYPEMUL(pVTNormals[2], EnvMapMatrix.f[8]) + f2vt(0.5f); pUVs[2*i+1] = VERTTYPEMUL(pVTNormals[0], EnvMapMatrix.f[1]) + VERTTYPEMUL(pVTNormals[1], EnvMapMatrix.f[5]) + VERTTYPEMUL(pVTNormals[2], EnvMapMatrix.f[9]) + f2vt(0.5f); pNormals += Mesh.sNormals.nStride; } // Bind the vertex buffers glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[ui32MeshID]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[ui32MeshID]); // Setup pointers glVertexPointer(3, VERTTYPEENUM, Mesh.sVertex.nStride, Mesh.sVertex.pData); // unbind the vertex buffer as we don't need them bound anymore glBindBuffer(GL_ARRAY_BUFFER, 0); glTexCoordPointer(2, VERTTYPEENUM, 0, pUVs); glDrawElements(GL_TRIANGLES, Mesh.nNumFaces * 3, GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); delete[] pUVs; }
void SimpleCamera::PitchDown() { if(m_bInverted) { m_fElevation-=m_fRotSpeed; if(m_fElevation<=-PVRT_PI_OVER_TWO) m_fElevation=-PVRT_PI_OVER_TWO + f2vt(0.001f); } else { m_fElevation+=m_fRotSpeed; if(m_fElevation>=PVRT_PI_OVER_TWO) m_fElevation=PVRT_PI_OVER_TWO - f2vt(0.001f); } }
void SimpleCamera::setTo(const PVRTVec3& vec) { // find angle from horizontal m_fElevation = f2vt((float) atan(VERTTYPEDIV(vec.y,f2vt(sqrt(vt2f(vec.z*vec.z+vec.x*vec.x)))))); // find principle angle from straight ahead m_fHeading = f2vt((float) atan2(vt2f(vec.x),vt2f(vec.z))); m_fHeading -= PVRT_PI; while(m_fHeading < 0.0f) m_fHeading+=PVRT_TWO_PI; }
/*!*************************************************************************** @Function inverse @Returns inverse mat4 @Description Calculates multiplicative inverse of this matrix The matrix must be of the form : A 0 C 1 Where A is a 3x3 matrix and C is a 1x3 matrix. *****************************************************************************/ PVRTMat4 PVRTMat4::inverse() const { PVRTMat4 out; VERTTYPE det_1; VERTTYPE pos, neg, temp; /* Calculate the determinant of submatrix A and determine if the the matrix is singular as limited by the double precision floating-point data representation. */ pos = neg = f2vt(0.0); temp = VERTTYPEMUL(VERTTYPEMUL(f[ 0], f[ 5]), f[10]); if (temp >= 0) pos += temp; else neg += temp; temp = VERTTYPEMUL(VERTTYPEMUL(f[ 4], f[ 9]), f[ 2]); if (temp >= 0) pos += temp; else neg += temp; temp = VERTTYPEMUL(VERTTYPEMUL(f[ 8], f[ 1]), f[ 6]); if (temp >= 0) pos += temp; else neg += temp; temp = VERTTYPEMUL(VERTTYPEMUL(-f[ 8], f[ 5]), f[ 2]); if (temp >= 0) pos += temp; else neg += temp; temp = VERTTYPEMUL(VERTTYPEMUL(-f[ 4], f[ 1]), f[10]); if (temp >= 0) pos += temp; else neg += temp; temp = VERTTYPEMUL(VERTTYPEMUL(-f[ 0], f[ 9]), f[ 6]); if (temp >= 0) pos += temp; else neg += temp; det_1 = pos + neg; /* Is the submatrix A singular? */ if (det_1 == f2vt(0.0)) //|| (VERTTYPEABS(det_1 / (pos - neg)) < 1.0e-15) { /* Matrix M has no inverse */ _RPT0(_CRT_WARN, "Matrix has no inverse : singular matrix\n"); } else { /* Calculate inverse(A) = adj(A) / det(A) */ //det_1 = 1.0 / det_1; det_1 = VERTTYPEDIV(f2vt(1.0f), det_1); out.f[ 0] = VERTTYPEMUL(( VERTTYPEMUL(f[ 5], f[10]) - VERTTYPEMUL(f[ 9], f[ 6]) ), det_1); out.f[ 1] = - VERTTYPEMUL(( VERTTYPEMUL(f[ 1], f[10]) - VERTTYPEMUL(f[ 9], f[ 2]) ), det_1); out.f[ 2] = VERTTYPEMUL(( VERTTYPEMUL(f[ 1], f[ 6]) - VERTTYPEMUL(f[ 5], f[ 2]) ), det_1); out.f[ 4] = - VERTTYPEMUL(( VERTTYPEMUL(f[ 4], f[10]) - VERTTYPEMUL(f[ 8], f[ 6]) ), det_1); out.f[ 5] = VERTTYPEMUL(( VERTTYPEMUL(f[ 0], f[10]) - VERTTYPEMUL(f[ 8], f[ 2]) ), det_1); out.f[ 6] = - VERTTYPEMUL(( VERTTYPEMUL(f[ 0], f[ 6]) - VERTTYPEMUL(f[ 4], f[ 2]) ), det_1); out.f[ 8] = VERTTYPEMUL(( VERTTYPEMUL(f[ 4], f[ 9]) - VERTTYPEMUL(f[ 8], f[ 5]) ), det_1); out.f[ 9] = - VERTTYPEMUL(( VERTTYPEMUL(f[ 0], f[ 9]) - VERTTYPEMUL(f[ 8], f[ 1]) ), det_1); out.f[10] = VERTTYPEMUL(( VERTTYPEMUL(f[ 0], f[ 5]) - VERTTYPEMUL(f[ 4], f[ 1]) ), det_1); /* Calculate -C * inverse(A) */ out.f[12] = - ( VERTTYPEMUL(f[12], out.f[ 0]) + VERTTYPEMUL(f[13], out.f[ 4]) + VERTTYPEMUL(f[14], out.f[ 8]) ); out.f[13] = - ( VERTTYPEMUL(f[12], out.f[ 1]) + VERTTYPEMUL(f[13], out.f[ 5]) + VERTTYPEMUL(f[14], out.f[ 9]) ); out.f[14] = - ( VERTTYPEMUL(f[12], out.f[ 2]) + VERTTYPEMUL(f[13], out.f[ 6]) + VERTTYPEMUL(f[14], out.f[10]) ); /* Fill in last row */ out.f[ 3] = f2vt(0.0f); out.f[ 7] = f2vt(0.0f); out.f[11] = f2vt(0.0f); out.f[15] = f2vt(1.0f); } return out; }
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; }
void SimpleCamera::updatePosition() { // Most of this stuff is to try and smooth movement when controlled by the primitive keyboard input available PVRTVec3 vDec = m_vVelocity * f2vt(TimeController::inst().getDeltaTime()) * m_fMoveSpeed * f2vt(0.1f); while(vDec.lenSqr()>m_vVelocity.lenSqr()) { vDec /= f2vt(2.0f); } m_vVelocity -= vDec; if(m_vVelocity.lenSqr()>m_fMoveSpeed*m_fMoveSpeed) { m_vVelocity = m_vVelocity.normalized()*m_fMoveSpeed; } m_vPosition += m_vVelocity * f2vt((float)TimeController::inst().getDeltaTime()); }
SimpleCamera::SimpleCamera() { m_vPosition.x = m_vVelocity.x = f2vt(0.0f); m_vPosition.y = m_vVelocity.y = f2vt(0.0f); m_vPosition.z = m_vVelocity.z = f2vt(0.0f); m_fHeading = f2vt(0.0f); m_fElevation = f2vt(0.0f); m_fMoveSpeed = f2vt(5.0f); m_fRotSpeed = f2vt(0.01f); m_fFOV = f2vt(0.7f); m_bInverted = false; }
OGLESParticles() : m_fFrom(f2vt(0.0f), f2vt(45.0f), f2vt(120.0f)), m_fTo(f2vt(0.0f), f2vt(20.0f), f2vt(-1.0f)), m_i32NumParticles(0), m_fRot(0), m_fRot2(0) { }
/*!**************************************************************************** @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 OGLES2Coverflow::InitView() { CPVRTString ErrorStr; // Get and set the read path for content files CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath)); // Get and set the load/release functions for loading external files. // In the majority of cases the PVRShell will return NULL function pointers implying that // nothing special is required to load external files. CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc)); if (!LoadTextures(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } if (!LoadShaders(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } 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; } PVRTVECTOR3 vFrom = {0.0f, 0.0f, 15.0f }, vTo = { 0, 0, 0 }, vUp = { 0, 1, 0 }; PVRTMatrixPerspectiveFovRH(m_mProjection, g_FOV, f2vt((float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight)), f2vt(g_fCameraNear), f2vt(g_fCameraFar), bRotate); PVRTMatrixLookAtRH(m_mView, vFrom, vTo, vUp); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //this must be called after InitApplication CreateCover(); // Enable culling glEnable(GL_CULL_FACE); return true; }
/*!**************************************************************************** @Function RenderParticle @Input NmbrOfParticles number of particles to initialize @Input bReflect should we use the reflection colour ? @Description Renders the specified set of particles, optionally using the reflection colour. ******************************************************************************/ void OGLESParticles::RenderParticle(int i32ParticleNo, bool bReflect) { // If point sprites are availables, use them to draw the particles. glBindBuffer(GL_ARRAY_BUFFER, m_i32VertVboID); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,VERTTYPEENUM, sizeof(SVtxPointSprite), 0); myglTexEnv( GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE ); glEnableClientState(GL_POINT_SIZE_ARRAY_OES); glPointSizePointerOES(VERTTYPEENUM, sizeof(SVtxPointSprite),(GLvoid*) (sizeof(VERTTYPE)*3)); #ifndef PVRT_FIXED_POINT_ENABLE float fCoefs[4] = { 0, 0, m_fPointAttenuationCoef, 0 }; #else // Note: m_fPointAttenuationCoef will be too small to represent as a fixed point number, // So use an approximation to the attenuation (fixed attenuation of 0.01) instead. VERTTYPE fCoefs[4] = { f2vt(0.01f), f2vt(0.0f), f2vt(0.0f), f2vt(0.0f) }; #endif myglPointParameterv(GL_POINT_DISTANCE_ATTENUATION, fCoefs); glEnableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, bReflect ? m_i32ColBVboID : m_i32ColAVboID); glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); glDrawArrays(GL_POINTS, 0, i32ParticleNo); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_POINT_SIZE_ARRAY_OES); glDisableClientState(GL_COLOR_ARRAY); }
void SimpleCamera::getToAndUp(PVRTVec3& vTo, PVRTVec3& vUp) const { vTo = PVRTVec3(f2vt(0.0f),f2vt(0.0f),f2vt(1.0f)); vUp = PVRTVec3(f2vt(0.0f),f2vt(1.0f),f2vt(0.0f)); PVRTMat3 mRotY = PVRTMat3::RotationY(m_fHeading); PVRTMat3 mRotX = PVRTMat3::RotationX(m_fElevation); vTo = (vTo*mRotX)*mRotY; vUp = (vUp*mRotX)*mRotY; }
void SimpleCamera::getTargetAndUp(PVRTVec3& vTarget, PVRTVec3& vUp) const { vTarget = PVRTVec3(f2vt(0.0f),f2vt(0.0f),f2vt(1.0f)); vUp = PVRTVec3(f2vt(0.0f),f2vt(1.0f),f2vt(0.0f)); PVRTMat3 mRotY = PVRTMat3::RotationY(m_fHeading); PVRTMat3 mRotX = PVRTMat3::RotationX(m_fElevation); vTarget = (vTarget*mRotX)*mRotY; vUp = (vUp*mRotX)*mRotY; vTarget +=m_vPosition; }
/******************************************************************************* * Function Name : DrawQuad * Input : Size, (x,y,z) and texture pntr * Description : Basic Draw Quad with Size in Location X, Y, Z. *******************************************************************************/ void OGLESEvilSkull::DrawQuad(float x, float y, float z, float Size, GLuint ui32Texture) { // Bind correct texture glBindTexture(GL_TEXTURE_2D, ui32Texture); // Vertex Data VERTTYPE verts[] = { f2vt(x+Size), f2vt(y-Size), f2vt(z), f2vt(x+Size), f2vt(y+Size), f2vt(z), f2vt(x-Size), f2vt(y-Size), f2vt(z), f2vt(x-Size), f2vt(y+Size), f2vt(z) }; VERTTYPE texcoords[] = { f2vt(0.0f), f2vt(1.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(0.0f) }; // Set Arrays - Only need Vertex Array and Tex Coord Array glVertexPointer(3,VERTTYPEENUM,0,verts); glTexCoordPointer(2,VERTTYPEENUM,0,texcoords); // Draw Strip glDrawArrays(GL_TRIANGLE_STRIP,0,4); }
/*!**************************************************************************** @Function SpawnParticle @Output pParticle particle to initialize @Description initializes the specified particle with randomly chosen parameters. ******************************************************************************/ void OGLESParticles::SpawnParticle(CParticle *pParticle) { PVRTVec3 fParticleSource(f2vt(0), f2vt(0), f2vt(0)); PVRTVec3 fParticleSourceVariability(f2vt(1), f2vt(0), f2vt(1)); PVRTVec3 fParticleVelocity(f2vt(0), f2vt(30), f2vt(0)); PVRTVec3 fParticleVelocityVariability(f2vt(4), f2vt(15), f2vt(4)); VERTTYPE fParticleLifeTime = f2vt(8); VERTTYPE fParticleLifeTimeVariability = f2vt(1.0); float fParticleMass = 100; float fParticleMassVariability = 0; float fRndFloat; // Creates the particle position. PVRTVec3 fPos; fRndFloat = RandFloat(); fPos.x = fParticleSource.x + VERTTYPEMUL(f2vt(fRndFloat),fParticleSourceVariability.x); fRndFloat = RandFloat(); fPos.y = fParticleSource.y + VERTTYPEMUL(f2vt(fRndFloat),fParticleSourceVariability.y); fRndFloat = RandFloat(); fPos.z = fParticleSource.z + VERTTYPEMUL(f2vt(fRndFloat),fParticleSourceVariability.z); // Creates the particle velocity. PVRTVec3 fVel; fRndFloat = RandFloat(); fVel.x = fParticleVelocity.x + VERTTYPEMUL(f2vt(fRndFloat),fParticleVelocityVariability.x); fRndFloat = RandFloat(); fVel.y = fParticleVelocity.y + VERTTYPEMUL(f2vt(fRndFloat),fParticleVelocityVariability.y); fRndFloat = RandFloat(); fVel.z = fParticleVelocity.z + VERTTYPEMUL(f2vt(fRndFloat),fParticleVelocityVariability.z); // Creates the particle lifetime and fMass. VERTTYPE fLife = fParticleLifeTime + VERTTYPEMUL(f2vt(RandFloat()), fParticleLifeTimeVariability); float fMass = fParticleMass + RandFloat() * fParticleMassVariability; // Creates the particle from these characteristics. *pParticle = CParticle(fPos,fVel,fMass,fLife); // Creates the particle colors. PVRTVec3 fParticleInitialColour(f2vt(0.6f*255.0f), f2vt(0.5f*255.0f), f2vt(0.5f*255.0f)); PVRTVec3 fParticleInitialColourVariability(f2vt(0.2f*255.0f), f2vt(0.2f*255.0f), f2vt(0.2f*255.0f)); PVRTVec3 fParticleHalfwayColour(f2vt(1.0f*255.0f), f2vt(0.0f), f2vt(0.0f)); PVRTVec3 fParticleHalfwayColourVariability(f2vt(0.8f*255.0f), f2vt(0.0f), f2vt(0.3f*255.0f)); PVRTVec3 fParticleEndColour(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f)); PVRTVec3 fParticleEndColourVariability(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f)); VERTTYPE fRndValue = f2vt(RandFloat()); pParticle->m_fColour.x = pParticle->m_fInitialColour.x = Clamp(fParticleInitialColour.x + VERTTYPEMUL(fParticleInitialColourVariability.x,fRndValue)); pParticle->m_fColour.y = pParticle->m_fInitialColour.y = Clamp(fParticleInitialColour.y + VERTTYPEMUL(fParticleInitialColourVariability.y,fRndValue)); pParticle->m_fColour.z = pParticle->m_fInitialColour.z = Clamp(fParticleInitialColour.z + VERTTYPEMUL(fParticleInitialColourVariability.z,fRndValue)); fRndFloat = RandFloat(); pParticle->m_fHalfwayColour.x = Clamp(fParticleHalfwayColour.x + VERTTYPEMUL(f2vt(fRndFloat), fParticleHalfwayColourVariability.x)); fRndFloat = RandFloat(); pParticle->m_fHalfwayColour.y = Clamp(fParticleHalfwayColour.y + VERTTYPEMUL(f2vt(fRndFloat), fParticleHalfwayColourVariability.y)); fRndFloat = RandFloat(); pParticle->m_fHalfwayColour.z = Clamp(fParticleHalfwayColour.z + VERTTYPEMUL(f2vt(fRndFloat), fParticleHalfwayColourVariability.z)); fRndFloat = RandFloat(); pParticle->m_fEndColor.x = Clamp(fParticleEndColour.x + VERTTYPEMUL(f2vt(fRndFloat), fParticleEndColourVariability.x)); fRndFloat = RandFloat(); pParticle->m_fEndColor.y = Clamp(fParticleEndColour.y + VERTTYPEMUL(f2vt(fRndFloat), fParticleEndColourVariability.y)); fRndFloat = RandFloat(); pParticle->m_fEndColor.z = Clamp(fParticleEndColour.z + VERTTYPEMUL(f2vt(fRndFloat), fParticleEndColourVariability.z)); // Creates the particle size using a perturbation. VERTTYPE fParticleSize = f2vt(2.0f); VERTTYPE fParticleSizeVariation = f2vt(1.5f); fRndFloat = RandFloat(); pParticle->m_fSize = fParticleSize + VERTTYPEMUL(f2vt(fRndFloat), fParticleSizeVariation); }
/******************************************************************************* * 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 OGLESVase::InitView() { CPVRTString ErrorStr; SPVRTContext Context; // Is the screen rotated? bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); // Initialize Print3D textures if(m_Print3D.SetTextures(&Context, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n"); return false; } // Load textures if(!LoadTextures(&ErrorStr)) { PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } // Initialize VBO data LoadVbos(); // Initialize Background if(m_Background.Init(0, bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Background\n"); return false; } /* Build an array to map the textures within the pod file to the textures we loaded earlier. */ m_pui32Textures = new GLuint[m_Scene.nNumMaterial]; for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i) { m_pui32Textures[i] = 0; SPODMaterial* pMaterial = &m_Scene.pMaterial[i]; if(!strcmp(pMaterial->pszName, "Flora")) m_pui32Textures[i] = m_uiFloraTex; else if(!strcmp(pMaterial->pszName, "Reflection")) m_pui32Textures[i] = m_uiReflectTex; } // Calculates the projection matrix m_mProjection = PVRTMat4::PerspectiveFovRH(f2vt(35.0f*(3.14f/180.0f)), f2vt((float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight)), f2vt(g_fCameraNear), f2vt(g_fCameraFar), PVRTMat4::OGL, bRotate); // Loads the projection matrix glMatrixMode(GL_PROJECTION); myglLoadMatrix(m_mProjection.f); // Enable texturing glEnable(GL_TEXTURE_2D); // Setup clear colour myglClearColor(f2vt(1.0f),f2vt(1.0f),f2vt(1.0f),f2vt(1.0f)); // Set blend mode glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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 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; }
#include "Particle.h" /****************************************************************************** Content file names ******************************************************************************/ // PVR texture files const char c_szLightTexFile[] = "LightTex.pvr"; const char c_szFloorTexFile[] = "FloorTex8.pvr"; /****************************************************************************** Defines ******************************************************************************/ const unsigned int g_ui32MaxParticles = 600; // Maximum number of m_Particles const VERTTYPE g_fFactor = f2vt(0.25f); // Brightness of the reflected m_Particles const PVRTVec3 g_fUp(f2vt(0.0f), f2vt(1.0f), f2vt(0.0f)); // Up direction. Used for creating the camera /****************************************************************************** Structure definitions ******************************************************************************/ struct SVtx { VERTTYPE x, y, z; // Position unsigned char u, v; // TexCoord }; struct SVtxPointSprite { VERTTYPE x, y, z, fSize;
/*!*************************************************************************** @Function PVRTCreateSkybox @Input scale Scale the skybox @Input adjustUV Adjust or not UVs for PVRT compression @Input textureSize Texture size in pixels @Output Vertices Array of vertices @Output UVs Array of UVs @Description Creates the vertices and texture coordinates for a skybox *****************************************************************************/ void PVRTCreateSkybox(float scale, bool adjustUV, int textureSize, VERTTYPE** Vertices, VERTTYPE** UVs) { *Vertices = new VERTTYPE[24*3]; *UVs = new VERTTYPE[24*2]; VERTTYPE unit = f2vt(1); VERTTYPE a0 = 0, a1 = unit; if (adjustUV) { VERTTYPE oneover = f2vt(1.0f / textureSize); a0 = VERTTYPEMUL(f2vt(4.0f), oneover); a1 = unit - a0; } // Front SetVertex(Vertices, 0, -unit, +unit, -unit); SetVertex(Vertices, 1, +unit, +unit, -unit); SetVertex(Vertices, 2, -unit, -unit, -unit); SetVertex(Vertices, 3, +unit, -unit, -unit); SetUV(UVs, 0, a0, a1); SetUV(UVs, 1, a1, a1); SetUV(UVs, 2, a0, a0); SetUV(UVs, 3, a1, a0); // Right SetVertex(Vertices, 4, +unit, +unit, -unit); SetVertex(Vertices, 5, +unit, +unit, +unit); SetVertex(Vertices, 6, +unit, -unit, -unit); SetVertex(Vertices, 7, +unit, -unit, +unit); SetUV(UVs, 4, a0, a1); SetUV(UVs, 5, a1, a1); SetUV(UVs, 6, a0, a0); SetUV(UVs, 7, a1, a0); // Back SetVertex(Vertices, 8 , +unit, +unit, +unit); SetVertex(Vertices, 9 , -unit, +unit, +unit); SetVertex(Vertices, 10, +unit, -unit, +unit); SetVertex(Vertices, 11, -unit, -unit, +unit); SetUV(UVs, 8 , a0, a1); SetUV(UVs, 9 , a1, a1); SetUV(UVs, 10, a0, a0); SetUV(UVs, 11, a1, a0); // Left SetVertex(Vertices, 12, -unit, +unit, +unit); SetVertex(Vertices, 13, -unit, +unit, -unit); SetVertex(Vertices, 14, -unit, -unit, +unit); SetVertex(Vertices, 15, -unit, -unit, -unit); SetUV(UVs, 12, a0, a1); SetUV(UVs, 13, a1, a1); SetUV(UVs, 14, a0, a0); SetUV(UVs, 15, a1, a0); // Top SetVertex(Vertices, 16, -unit, +unit, +unit); SetVertex(Vertices, 17, +unit, +unit, +unit); SetVertex(Vertices, 18, -unit, +unit, -unit); SetVertex(Vertices, 19, +unit, +unit, -unit); SetUV(UVs, 16, a0, a1); SetUV(UVs, 17, a1, a1); SetUV(UVs, 18, a0, a0); SetUV(UVs, 19, a1, a0); // Bottom SetVertex(Vertices, 20, -unit, -unit, -unit); SetVertex(Vertices, 21, +unit, -unit, -unit); SetVertex(Vertices, 22, -unit, -unit, +unit); SetVertex(Vertices, 23, +unit, -unit, +unit); SetUV(UVs, 20, a0, a1); SetUV(UVs, 21, a1, a1); SetUV(UVs, 22, a0, a0); SetUV(UVs, 23, a1, a0); for (int i=0; i<24*3; i++) (*Vertices)[i] = VERTTYPEMUL((*Vertices)[i], f2vt(scale)); }
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; } } }
/*!*************************************************************************** @Function PVRTLinearEqSolve @Input pSrc 2D array of floats. 4 Eq linear problem is 5x4 matrix, constants in first column @Input nCnt Number of equations to solve @Output pRes Result @Description Solves 'nCnt' simultaneous equations of 'nCnt' variables. pRes should be an array large enough to contain the results: the values of the 'nCnt' variables. This fn recursively uses Gaussian Elimination. *****************************************************************************/ void PVRTLinearEqSolve(VERTTYPE * const pRes, VERTTYPE ** const pSrc, const int nCnt) { int i, j, k; VERTTYPE f; if (nCnt == 1) { _ASSERT(pSrc[0][1] != 0); pRes[0] = VERTTYPEDIV(pSrc[0][0], pSrc[0][1]); return; } // Loop backwards in an attempt avoid the need to swap rows i = nCnt; while(i) { --i; if(pSrc[i][nCnt] != f2vt(0.0f)) { // Row i can be used to zero the other rows; let's move it to the bottom if(i != (nCnt-1)) { for(j = 0; j <= nCnt; ++j) { // Swap the two values f = pSrc[nCnt-1][j]; pSrc[nCnt-1][j] = pSrc[i][j]; pSrc[i][j] = f; } } // Now zero the last columns of the top rows for(j = 0; j < (nCnt-1); ++j) { _ASSERT(pSrc[nCnt-1][nCnt] != f2vt(0.0f)); f = VERTTYPEDIV(pSrc[j][nCnt], pSrc[nCnt-1][nCnt]); // No need to actually calculate a zero for the final column for(k = 0; k < nCnt; ++k) { pSrc[j][k] -= VERTTYPEMUL(f, pSrc[nCnt-1][k]); } } break; } } // Solve the top-left sub matrix PVRTLinearEqSolve(pRes, pSrc, nCnt - 1); // Now calc the solution for the bottom row f = pSrc[nCnt-1][0]; for(k = 1; k < nCnt; ++k) { f -= VERTTYPEMUL(pSrc[nCnt-1][k], pRes[k-1]); } _ASSERT(pSrc[nCnt-1][nCnt] != f2vt(0)); f = VERTTYPEDIV(f, pSrc[nCnt-1][nCnt]); pRes[nCnt-1] = f; }
/******************************************************************************* * Function Name : DrawDualTexQuad * Input : Size, (x,y,z) and texture pntr * Description : Basic Draw Dual Textured Quad with Size in Location X, Y, Z. *******************************************************************************/ void OGLESEvilSkull::DrawDualTexQuad(float x, float y, float z, float Size, GLuint ui32Texture1, GLuint ui32Texture2) { // Set Texture and Texture Options glBindTexture(GL_TEXTURE_2D, ui32Texture1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, ui32Texture2); glEnable(GL_TEXTURE_2D); // Vertex Data VERTTYPE verts[] = { f2vt(x+Size), f2vt(y-Size), f2vt(z), f2vt(x+Size), f2vt(y+Size), f2vt(z), f2vt(x-Size), f2vt(y-Size), f2vt(z), f2vt(x-Size), f2vt(y+Size), f2vt(z) }; VERTTYPE texcoords[] = { f2vt(0.0f), f2vt(1.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(0.0f) }; // Set Arrays - Only need Vertex Array and Tex Coord Arrays glVertexPointer(3,VERTTYPEENUM,0,verts); glClientActiveTexture(GL_TEXTURE0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,VERTTYPEENUM,0,texcoords); glClientActiveTexture(GL_TEXTURE1); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,VERTTYPEENUM,0,texcoords); // Draw Strip glDrawArrays(GL_TRIANGLE_STRIP,0,4); // Disable Arrays glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); }
/******************************************************************************* * 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 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 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; }
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; }