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; }
/*!*************************************************************************** @Function PVRTMiscCalculateIntersectionLinePlane @Input pfPlane Length 4 [A,B,C,D], values for plane equation @Input pv0 A point on the line @Input pv1 Another point on the line @Output pvIntersection The point of intersection @Description Calculates coords of the intersection of a line and an infinite plane *****************************************************************************/ void PVRTMiscCalculateIntersectionLinePlane( PVRTVECTOR3 * const pvIntersection, const VERTTYPE pfPlane[4], const PVRTVECTOR3 * const pv0, const PVRTVECTOR3 * const pv1) { PVRTVECTOR3 vD; VERTTYPE fN, fD, fT; /* Calculate vector from point0 to point1 */ vD.x = pv1->x - pv0->x; vD.y = pv1->y - pv0->y; vD.z = pv1->z - pv0->z; /* Denominator */ fD = VERTTYPEMUL(pfPlane[0], vD.x) + VERTTYPEMUL(pfPlane[1], vD.y) + VERTTYPEMUL(pfPlane[2], vD.z); /* Numerator */ fN = VERTTYPEMUL(pfPlane[0], pv0->x) + VERTTYPEMUL(pfPlane[1], pv0->y) + VERTTYPEMUL(pfPlane[2], pv0->z) + pfPlane[3]; fT = VERTTYPEDIV(-fN, fD); /* And for a finale, calculate the intersection coordinate */ pvIntersection->x = pv0->x + VERTTYPEMUL(fT, vD.x); pvIntersection->y = pv0->y + VERTTYPEMUL(fT, vD.y); pvIntersection->z = pv0->z + VERTTYPEMUL(fT, vD.z); }
/*!*************************************************************************** @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 * @Input rhs a PVRTMat3 @Returns result of multiplication @Description matrix multiplication operator PVRTVec3 and PVRTMat3 ****************************************************************************/ PVRTVec3 PVRTVec3::operator*(const PVRTMat3& rhs) const { PVRTVec3 out; out.x = VERTTYPEMUL(x,rhs.f[0])+VERTTYPEMUL(y,rhs.f[1])+VERTTYPEMUL(z,rhs.f[2]); out.y = VERTTYPEMUL(x,rhs.f[3])+VERTTYPEMUL(y,rhs.f[4])+VERTTYPEMUL(z,rhs.f[5]); out.z = VERTTYPEMUL(x,rhs.f[6])+VERTTYPEMUL(y,rhs.f[7])+VERTTYPEMUL(z,rhs.f[8]); return out; }
/*!*************************************************************************** @Function *= @Input rhs a PVRTMat3 @Returns result of multiplication and assignment @Description matrix multiplication and assignment operator for PVRTVec3 and PVRTMat3 ****************************************************************************/ PVRTVec3& PVRTVec3::operator*=(const PVRTMat3& rhs) { VERTTYPE tx = VERTTYPEMUL(x,rhs.f[0])+VERTTYPEMUL(y,rhs.f[1])+VERTTYPEMUL(z,rhs.f[2]); VERTTYPE ty = VERTTYPEMUL(x,rhs.f[3])+VERTTYPEMUL(y,rhs.f[4])+VERTTYPEMUL(z,rhs.f[5]); z = VERTTYPEMUL(x,rhs.f[6])+VERTTYPEMUL(y,rhs.f[7])+VERTTYPEMUL(z,rhs.f[8]); x = tx; y = ty; return *this; }
/*!**************************************************************************** @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; }
/*!*************************************************************************** @Function PVRTTransform @Output pOut @Input pV @Input pM @Description Transform vertex pV by pMatrix and store in pOut. *****************************************************************************/ void PVRTTransform( PVRTVECTOR4 * const pOut, const PVRTVECTOR4 * const pV, const PVRTMATRIX * const pM) { pOut->x = VERTTYPEMUL(pM->f[0], pV->x) + VERTTYPEMUL(pM->f[4], pV->y) + VERTTYPEMUL(pM->f[8], pV->z) + VERTTYPEMUL(pM->f[12], pV->w); pOut->y = VERTTYPEMUL(pM->f[1], pV->x) + VERTTYPEMUL(pM->f[5], pV->y) + VERTTYPEMUL(pM->f[9], pV->z) + VERTTYPEMUL(pM->f[13], pV->w); pOut->z = VERTTYPEMUL(pM->f[2], pV->x) + VERTTYPEMUL(pM->f[6], pV->y) + VERTTYPEMUL(pM->f[10], pV->z) + VERTTYPEMUL(pM->f[14], pV->w); pOut->w = VERTTYPEMUL(pM->f[3], pV->x) + VERTTYPEMUL(pM->f[7], pV->y) + VERTTYPEMUL(pM->f[11], pV->z) + VERTTYPEMUL(pM->f[15], pV->w); }
/*!*************************************************************************** @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 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; }
/*!*************************************************************************** @Function * @Input rhs another PVRTMat4 @Returns result of multiplication @Description Matrix multiplication of two 4x4 matrices. *****************************************************************************/ PVRTMat4 PVRTMat4::operator*(const PVRTMat4& rhs) const { PVRTMat4 out; // col 1 out.f[0] = VERTTYPEMUL(f[0],rhs.f[0])+VERTTYPEMUL(f[4],rhs.f[1])+VERTTYPEMUL(f[8],rhs.f[2])+VERTTYPEMUL(f[12],rhs.f[3]); out.f[1] = VERTTYPEMUL(f[1],rhs.f[0])+VERTTYPEMUL(f[5],rhs.f[1])+VERTTYPEMUL(f[9],rhs.f[2])+VERTTYPEMUL(f[13],rhs.f[3]); out.f[2] = VERTTYPEMUL(f[2],rhs.f[0])+VERTTYPEMUL(f[6],rhs.f[1])+VERTTYPEMUL(f[10],rhs.f[2])+VERTTYPEMUL(f[14],rhs.f[3]); out.f[3] = VERTTYPEMUL(f[3],rhs.f[0])+VERTTYPEMUL(f[7],rhs.f[1])+VERTTYPEMUL(f[11],rhs.f[2])+VERTTYPEMUL(f[15],rhs.f[3]); // col 2 out.f[4] = VERTTYPEMUL(f[0],rhs.f[4])+VERTTYPEMUL(f[4],rhs.f[5])+VERTTYPEMUL(f[8],rhs.f[6])+VERTTYPEMUL(f[12],rhs.f[7]); out.f[5] = VERTTYPEMUL(f[1],rhs.f[4])+VERTTYPEMUL(f[5],rhs.f[5])+VERTTYPEMUL(f[9],rhs.f[6])+VERTTYPEMUL(f[13],rhs.f[7]); out.f[6] = VERTTYPEMUL(f[2],rhs.f[4])+VERTTYPEMUL(f[6],rhs.f[5])+VERTTYPEMUL(f[10],rhs.f[6])+VERTTYPEMUL(f[14],rhs.f[7]); out.f[7] = VERTTYPEMUL(f[3],rhs.f[4])+VERTTYPEMUL(f[7],rhs.f[5])+VERTTYPEMUL(f[11],rhs.f[6])+VERTTYPEMUL(f[15],rhs.f[7]); // col3 out.f[8] = VERTTYPEMUL(f[0],rhs.f[8])+VERTTYPEMUL(f[4],rhs.f[9])+VERTTYPEMUL(f[8],rhs.f[10])+VERTTYPEMUL(f[12],rhs.f[11]); out.f[9] = VERTTYPEMUL(f[1],rhs.f[8])+VERTTYPEMUL(f[5],rhs.f[9])+VERTTYPEMUL(f[9],rhs.f[10])+VERTTYPEMUL(f[13],rhs.f[11]); out.f[10] = VERTTYPEMUL(f[2],rhs.f[8])+VERTTYPEMUL(f[6],rhs.f[9])+VERTTYPEMUL(f[10],rhs.f[10])+VERTTYPEMUL(f[14],rhs.f[11]); out.f[11] = VERTTYPEMUL(f[3],rhs.f[8])+VERTTYPEMUL(f[7],rhs.f[9])+VERTTYPEMUL(f[11],rhs.f[10])+VERTTYPEMUL(f[15],rhs.f[11]); // col3 out.f[12] = VERTTYPEMUL(f[0],rhs.f[12])+VERTTYPEMUL(f[4],rhs.f[13])+VERTTYPEMUL(f[8],rhs.f[14])+VERTTYPEMUL(f[12],rhs.f[15]); out.f[13] = VERTTYPEMUL(f[1],rhs.f[12])+VERTTYPEMUL(f[5],rhs.f[13])+VERTTYPEMUL(f[9],rhs.f[14])+VERTTYPEMUL(f[13],rhs.f[15]); out.f[14] = VERTTYPEMUL(f[2],rhs.f[12])+VERTTYPEMUL(f[6],rhs.f[13])+VERTTYPEMUL(f[10],rhs.f[14])+VERTTYPEMUL(f[14],rhs.f[15]); out.f[15] = VERTTYPEMUL(f[3],rhs.f[12])+VERTTYPEMUL(f[7],rhs.f[13])+VERTTYPEMUL(f[11],rhs.f[14])+VERTTYPEMUL(f[15],rhs.f[15]); return out; }
/*!*************************************************************************** @Function *= @Input rhs a PVRTMat4 @Returns result of multiplication and assignment @Description matrix multiplication and assignment operator for PVRTVec4 and PVRTMat4 ****************************************************************************/ PVRTVec4& PVRTVec4::operator*=(const PVRTMat4& rhs) { VERTTYPE tx = VERTTYPEMUL(x,rhs.f[0])+VERTTYPEMUL(y,rhs.f[1])+VERTTYPEMUL(z,rhs.f[2])+VERTTYPEMUL(w,rhs.f[3]); VERTTYPE ty = VERTTYPEMUL(x,rhs.f[4])+VERTTYPEMUL(y,rhs.f[5])+VERTTYPEMUL(z,rhs.f[6])+VERTTYPEMUL(w,rhs.f[7]); VERTTYPE tz = VERTTYPEMUL(x,rhs.f[8])+VERTTYPEMUL(y,rhs.f[9])+VERTTYPEMUL(z,rhs.f[10])+VERTTYPEMUL(w,rhs.f[11]); w = VERTTYPEMUL(x,rhs.f[12])+VERTTYPEMUL(y,rhs.f[13])+VERTTYPEMUL(z,rhs.f[14])+VERTTYPEMUL(w,rhs.f[15]); x = tx; y = ty; z = tz; return *this; }
/*!*************************************************************************** @Function PVRTMiscCalculateInfinitePlane @Input nStride Size of each vertex structure containing pfVtx @Input pvPlane Length 4 [A,B,C,D], values for plane equation @Input pmViewProjInv The inverse of the View Projection matrix @Input pFrom Position of the camera @Input fFar Far clipping distance @Output pfVtx Position of the first of 3 floats to receive the position of vertex 0; up to 5 vertex positions will be written (5 is the maximum number of vertices required to draw an infinite polygon clipped to screen and far clip plane). @Returns Number of vertices in the polygon fan (Can be 0, 3, 4 or 5) @Description Calculates world-space coords of a screen-filling representation of an infinite plane The resulting vertices run counter-clockwise around the screen, and can be simply drawn using non-indexed TRIANGLEFAN *****************************************************************************/ int PVRTMiscCalculateInfinitePlane( VERTTYPE * const pfVtx, const int nStride, const PVRTVECTOR4 * const pvPlane, const PVRTMATRIX * const pmViewProjInv, const PVRTVECTOR3 * const pFrom, const VERTTYPE fFar) { PVRTVECTOR3 pvWorld[5]; PVRTVECTOR3 *pvPolyPtr; unsigned int dwCount; bool bClip; int nVert; VERTTYPE fDotProduct; /* Check whether the plane faces the camera */ fDotProduct = VERTTYPEMUL((pFrom->x + VERTTYPEMUL(pvPlane->x, pvPlane->w)), pvPlane->x) + VERTTYPEMUL((pFrom->y + VERTTYPEMUL(pvPlane->y, pvPlane->w)), pvPlane->y) + VERTTYPEMUL((pFrom->z + VERTTYPEMUL(pvPlane->z, pvPlane->w)), pvPlane->z); if(fDotProduct < 0) { /* Camera is behind plane, hence it's not visible */ return 0; } /* Back transform front clipping plane into world space, to give us a point on the line through each corner of the screen (from the camera). */ /* x = -1.0f; y = -1.0f; z = 1.0f; w = 1.0f */ pvWorld[0].x = VERTTYPEMUL((-pmViewProjInv->f[ 0] - pmViewProjInv->f[ 4] + pmViewProjInv->f[ 8] + pmViewProjInv->f[12]), fFar); pvWorld[0].y = VERTTYPEMUL((-pmViewProjInv->f[ 1] - pmViewProjInv->f[ 5] + pmViewProjInv->f[ 9] + pmViewProjInv->f[13]), fFar); pvWorld[0].z = VERTTYPEMUL((-pmViewProjInv->f[ 2] - pmViewProjInv->f[ 6] + pmViewProjInv->f[10] + pmViewProjInv->f[14]), fFar); /* x = 1.0f, y = -1.0f, z = 1.0f; w = 1.0f */ pvWorld[1].x = VERTTYPEMUL(( pmViewProjInv->f[ 0] - pmViewProjInv->f[ 4] + pmViewProjInv->f[ 8] + pmViewProjInv->f[12]), fFar); pvWorld[1].y = VERTTYPEMUL(( pmViewProjInv->f[ 1] - pmViewProjInv->f[ 5] + pmViewProjInv->f[ 9] + pmViewProjInv->f[13]), fFar); pvWorld[1].z = VERTTYPEMUL(( pmViewProjInv->f[ 2] - pmViewProjInv->f[ 6] + pmViewProjInv->f[10] + pmViewProjInv->f[14]), fFar); /* x = 1.0f, y = 1.0f, z = 1.0f; w = 1.0f */ pvWorld[2].x = VERTTYPEMUL(( pmViewProjInv->f[ 0] + pmViewProjInv->f[ 4] + pmViewProjInv->f[ 8] + pmViewProjInv->f[12]), fFar); pvWorld[2].y = VERTTYPEMUL(( pmViewProjInv->f[ 1] + pmViewProjInv->f[ 5] + pmViewProjInv->f[ 9] + pmViewProjInv->f[13]), fFar); pvWorld[2].z = VERTTYPEMUL(( pmViewProjInv->f[ 2] + pmViewProjInv->f[ 6] + pmViewProjInv->f[10] + pmViewProjInv->f[14]), fFar); /* x = -1.0f, y = 1.0f, z = 1.0f; w = 1.0f */ pvWorld[3].x = VERTTYPEMUL((-pmViewProjInv->f[ 0] + pmViewProjInv->f[ 4] + pmViewProjInv->f[ 8] + pmViewProjInv->f[12]), fFar); pvWorld[3].y = VERTTYPEMUL((-pmViewProjInv->f[ 1] + pmViewProjInv->f[ 5] + pmViewProjInv->f[ 9] + pmViewProjInv->f[13]), fFar); pvWorld[3].z = VERTTYPEMUL((-pmViewProjInv->f[ 2] + pmViewProjInv->f[ 6] + pmViewProjInv->f[10] + pmViewProjInv->f[14]), fFar); /* We need to do a closed loop of the screen vertices, so copy the first vertex into the last */ pvWorld[4] = pvWorld[0]; /* Now build a pre-clipped polygon */ /* Lets get ready to loop */ dwCount = 0; bClip = false; pvPolyPtr = (PVRTVECTOR3*)pfVtx; nVert = 5; while(nVert) { nVert--; /* Check which side of the Plane this corner of the far clipping plane is on. [A,B,C] of plane equation is the plane normal, D is distance from origin; hence [pvPlane->x * -pvPlane->w, pvPlane->y * -pvPlane->w, pvPlane->z * -pvPlane->w] is a point on the plane */ fDotProduct = VERTTYPEMUL((pvWorld[nVert].x + VERTTYPEMUL(pvPlane->x, pvPlane->w)), pvPlane->x) + VERTTYPEMUL((pvWorld[nVert].y + VERTTYPEMUL(pvPlane->y, pvPlane->w)), pvPlane->y) + VERTTYPEMUL((pvWorld[nVert].z + VERTTYPEMUL(pvPlane->z, pvPlane->w)), pvPlane->z); if(fDotProduct < 0) { /* Behind plane; Vertex does NOT need clipping */ if(bClip == true) { /* Clipping finished */ bClip = false; /* We've been clipping, so we need to add an additional point on the line to this point, where clipping was stopped. */ PVRTMiscCalculateIntersectionLinePlane(pvPolyPtr, &pvPlane->x, &pvWorld[nVert+1], &pvWorld[nVert]); pvPolyPtr = (PVRTVECTOR3*)((char*)pvPolyPtr + nStride); dwCount++; } if(!nVert) { /* Abort, abort: we've closed the loop with the clipped point */ break; } /* Add the current point */ PVRTMiscCalculateIntersectionLinePlane(pvPolyPtr, &pvPlane->x, pFrom, &pvWorld[nVert]); pvPolyPtr = (PVRTVECTOR3*)((char*)pvPolyPtr + nStride); dwCount++; } else { /* Before plane; Vertex DOES need clipping */ if(bClip == true) { /* Already in clipping, skip point */ continue; } /* Clipping initiated */ bClip = true; /* Don't bother with entry point on first vertex; will take care of it on last vertex (which is a repeat of first vertex) */ if(nVert != 4) { /* We need to add an additional point on the line to this point, where clipping was started */ PVRTMiscCalculateIntersectionLinePlane(pvPolyPtr, &pvPlane->x, &pvWorld[nVert+1], &pvWorld[nVert]); pvPolyPtr = (PVRTVECTOR3*)((char*)pvPolyPtr + nStride); dwCount++; } } } /* Valid vertex counts are 0, 3, 4, 5 */ _ASSERT(dwCount <= 5); _ASSERT(dwCount != 1); _ASSERT(dwCount != 2); return dwCount; }
/******************************************************************************* * 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 OGLESOptimizeMesh::RenderScene() { unsigned long ui32Time; // Clear the depth and frame buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #ifdef ENABLE_LOAD_TIME_STRIP /* Show a message on-screen then generate the necessary data on the second frame. */ if(m_i32Init) { --m_i32Init; if(m_i32Init) { m_Print3D.DisplayDefaultTitle("OptimizeMesh", "Generating data...", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; } StripMesh(); LoadVbos(); } #endif // Time ui32Time = PVRShellGetTime(); m_ui32TimeDiff = ui32Time - m_ui32LastTime; m_ui32LastTime = ui32Time; // FPS ++m_ui32FPSFrameCnt; m_ui32FPSTimeDiff += m_ui32TimeDiff; if(m_ui32FPSTimeDiff >= g_ui32TimeFPSUpdate) { m_fFPS = m_ui32FPSFrameCnt * 1000.0f / (float) m_ui32FPSTimeDiff; m_ui32FPSFrameCnt = 0; m_ui32FPSTimeDiff = 0; } // Change mode when necessary m_ui32SwitchTimeDiff += m_ui32TimeDiff; if((m_ui32SwitchTimeDiff > g_ui32TimeAutoSwitch)) // if((m_ui32SwitchTimeDiff > g_ui32TimeAutoSwitch) || PVRShellIsKeyPressed(PVRShellKeyNameACTION1)) { m_ui32SwitchTimeDiff = 0; ++m_i32Page; if(m_i32Page >= (int) m_ui32PageNo) m_i32Page = 0; } PVRTVec3 From; VERTTYPE fFactor; From.x = VERTTYPEMUL(g_fViewDistance, PVRTCOS(m_fViewAngle)); From.y = f2vt(0.0f); From.z = VERTTYPEMUL(g_fViewDistance, PVRTSIN(m_fViewAngle)); // Increase the rotation fFactor = f2vt(0.005f * (float) m_ui32TimeDiff); m_fViewAngle += fFactor; // Ensure it doesn't grow huge and lose accuracy over time if(m_fViewAngle > PVRT_PI) m_fViewAngle -= PVRT_TWO_PI; // Compute and set the matrix m_mView = PVRTMat4::LookAtRH(From, PVRTVec3(0,0,0), PVRTVec3(0,f2vt(1),0)); glMatrixMode(GL_MODELVIEW); myglLoadMatrix(m_mView.f); // Draw the model DrawModel(m_i32Page); // Display the frame rate char pTitle[512]; const char * pDesc; sprintf(pTitle, "Optimize Mesh %.1ffps", m_fFPS); // Print text on screen switch(m_i32Page) { default: pDesc = "Indexed Triangle List: Unoptimized"; break; case 1: pDesc = "Indexed Triangle List: Optimized (at export time)"; break; #ifdef ENABLE_LOAD_TIME_STRIP case 2: pDesc = "Indexed Triangle List: Optimized (at load time)"; break; #endif } m_Print3D.DisplayDefaultTitle(pTitle, pDesc, ePVRTPrint3DSDKLogo); // Flush all Print3D commands 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 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 PVRTTransformArray @Output pTransformedVertex Destination for transformed vectors @Input pV Input vector array @Input nNumberOfVertices Number of vectors to transform @Input pMatrix Matrix to transform the vectors @Input fW W coordinate of input vector (e.g. use 1 for position, 0 for normal) @Description Transform all vertices in pVertex by pMatrix and store them in pTransformedVertex - pTransformedVertex is the pointer that will receive transformed vertices. - pVertex is the pointer to untransformed object vertices. - nNumberOfVertices is the number of vertices of the object. - pMatrix is the matrix used to transform the object. *****************************************************************************/ void PVRTTransformArray( PVRTVECTOR3 * const pTransformedVertex, const PVRTVECTOR3 * const pV, const int nNumberOfVertices, const PVRTMATRIX * const pMatrix, const VERTTYPE fW) { int i; /* Transform all vertices with *pMatrix */ for (i=0; i<nNumberOfVertices; ++i) { pTransformedVertex[i].x = VERTTYPEMUL(pMatrix->f[ 0], pV[i].x) + VERTTYPEMUL(pMatrix->f[ 4], pV[i].y) + VERTTYPEMUL(pMatrix->f[ 8], pV[i].z) + VERTTYPEMUL(pMatrix->f[12], fW); pTransformedVertex[i].y = VERTTYPEMUL(pMatrix->f[ 1], pV[i].x) + VERTTYPEMUL(pMatrix->f[ 5], pV[i].y) + VERTTYPEMUL(pMatrix->f[ 9], pV[i].z) + VERTTYPEMUL(pMatrix->f[13], fW); pTransformedVertex[i].z = VERTTYPEMUL(pMatrix->f[ 2], pV[i].x) + VERTTYPEMUL(pMatrix->f[ 6], pV[i].y) + VERTTYPEMUL(pMatrix->f[10], pV[i].z) + VERTTYPEMUL(pMatrix->f[14], fW); } }
/*!*************************************************************************** @Function Name PVRTTransformVec3Array @Output pOut Destination for transformed vectors @Input nOutStride Stride between vectors in pOut array @Input pV Input vector array @Input nInStride Stride between vectors in pV array @Input pMatrix Matrix to transform the vectors @Input nNumberOfVertices Number of vectors to transform @Description Transform all vertices [X Y Z 1] in pV by pMatrix and store them in pOut. *****************************************************************************/ void PVRTTransformVec3Array( PVRTVECTOR4 * const pOut, const int nOutStride, const PVRTVECTOR3 * const pV, const int nInStride, const PVRTMATRIX * const pMatrix, const int nNumberOfVertices) { const PVRTVECTOR3 *pSrc; PVRTVECTOR4 *pDst; int i; pSrc = pV; pDst = pOut; /* Transform all vertices with *pMatrix */ for (i=0; i<nNumberOfVertices; ++i) { pDst->x = VERTTYPEMUL(pMatrix->f[ 0], pSrc->x) + VERTTYPEMUL(pMatrix->f[ 4], pSrc->y) + VERTTYPEMUL(pMatrix->f[ 8], pSrc->z) + pMatrix->f[12]; pDst->y = VERTTYPEMUL(pMatrix->f[ 1], pSrc->x) + VERTTYPEMUL(pMatrix->f[ 5], pSrc->y) + VERTTYPEMUL(pMatrix->f[ 9], pSrc->z) + pMatrix->f[13]; pDst->z = VERTTYPEMUL(pMatrix->f[ 2], pSrc->x) + VERTTYPEMUL(pMatrix->f[ 6], pSrc->y) + VERTTYPEMUL(pMatrix->f[10], pSrc->z) + pMatrix->f[14]; pDst->w = VERTTYPEMUL(pMatrix->f[ 3], pSrc->x) + VERTTYPEMUL(pMatrix->f[ 7], pSrc->y) + VERTTYPEMUL(pMatrix->f[11], pSrc->z) + pMatrix->f[15]; pDst = (PVRTVECTOR4*)((char*)pDst + nOutStride); pSrc = (PVRTVECTOR3*)((char*)pSrc + nInStride); } }
/*!**************************************************************************** @Function DoAnimation @Description Calculate the duck and camera animation as well as the cloud and water. ******************************************************************************/ void OGLESFur::DoAnimation() { PVRTMat4 mCamera, mTmp; PVRTVec3 pvPlane[5]; unsigned long ui32Time; float fDeltaTime; int i; if(!m_bPause) { ui32Time = PVRShellGetTime(); fDeltaTime = (float) (ui32Time < m_ui32PrevTime ? m_ui32PrevTime - ui32Time : ui32Time - m_ui32PrevTime) + 0.1f; if(fDeltaTime > 50.0f) // Cap delta time fDeltaTime = 50.0f; m_ui32PrevTime = ui32Time; m_fCameraRot += 0.00006f * fDeltaTime; fDeltaTime = fDeltaTime * 0.001f; } else fDeltaTime = 0.0f; if(m_bViewMode) { // Viewing duck alone mCamera = PVRTMat4::Translation(0, 0, f2vt(160.0f)); mTmp = PVRTMat4::RotationX(f2vt(0.35f * (float) sin(0.0003f * m_ui32PrevTime) + 0.2f)); mCamera = mTmp * mCamera; mTmp = PVRTMat4::RotationY(f2vt(m_fCameraRot)); mCamera = mTmp * mCamera; mTmp = PVRTMat4::Translation(m_mDuckWorld.f[12], m_mDuckWorld.f[13], m_mDuckWorld.f[14]); mCamera = mTmp * mCamera; m_vCamFrom.x += VERTTYPEMUL(f2vt(fDeltaTime), mCamera.f[12] - m_vCamFrom.x); m_vCamFrom.y += VERTTYPEMUL(f2vt(fDeltaTime), mCamera.f[13] - m_vCamFrom.y); m_vCamFrom.z += VERTTYPEMUL(f2vt(fDeltaTime), mCamera.f[14] - m_vCamFrom.z); m_vCamTo.x += VERTTYPEMUL(f2vt(fDeltaTime), m_mDuckWorld.f[12] - m_vCamTo.x); m_vCamTo.y += VERTTYPEMUL(f2vt(fDeltaTime), (m_mDuckWorld.f[13]+ f2vt(25.0f)) - m_vCamTo.y); m_vCamTo.z += VERTTYPEMUL(f2vt(fDeltaTime), m_mDuckWorld.f[14] - m_vCamTo.z); // Build view matrix m_mView = PVRTMat4::LookAtRH(m_vCamFrom, m_vCamTo, c_vUp); } else { // Viewing duck in a wee river m_fDuckRot -= 0.1f * fDeltaTime; // Duck world transform m_mDuckWorld = PVRTMat4::Translation(f2vt(140.0f), 0, 0); mTmp = PVRTMat4::RotationY(f2vt(m_fDuckRot)); m_mDuckWorld = mTmp * m_mDuckWorld; PVRTVec3 vFrom, vTo; // We can get the camera position, target with GetCameraPos() m_Scene.GetCameraPos(vFrom, vTo, 0); // Position camera mCamera = PVRTMat4::Translation(vFrom.x, vFrom.y, vFrom.z); mTmp = PVRTMat4::RotationY(f2vt(m_fCameraRot)); mCamera = mTmp * mCamera; m_vCamFrom.x += VERTTYPEMUL(f2vt(fDeltaTime), mCamera.f[12] - m_vCamFrom.x); m_vCamFrom.y += VERTTYPEMUL(f2vt(fDeltaTime), mCamera.f[13] - m_vCamFrom.y); m_vCamFrom.z += VERTTYPEMUL(f2vt(fDeltaTime), mCamera.f[14] - m_vCamFrom.z); m_vCamTo.x += VERTTYPEMUL(f2vt(fDeltaTime), VERTTYPEMUL(2.0f, m_mDuckWorld.f[12] - m_vCamTo.x)); m_vCamTo.y += VERTTYPEMUL(f2vt(fDeltaTime), VERTTYPEMUL(2.0f, (m_mDuckWorld.f[13] + f2vt(25.0f)) - m_vCamTo.y)); m_vCamTo.z += VERTTYPEMUL(f2vt(fDeltaTime), VERTTYPEMUL(2.0f, m_mDuckWorld.f[14] - m_vCamTo.z)); // Build view matrix m_mView = PVRTMat4::LookAtRH(m_vCamFrom, m_vCamTo, c_vUp); // Calc ViewProjInv matrix mTmp = m_mProj * m_mView; mTmp = mTmp.inverseEx(); // Calculate the ground plane m_i32WaterPlaneNo = PVRTMiscCalculateInfinitePlane(&pvPlane->x, sizeof(*pvPlane), &c_vPlaneWater, &mTmp, &m_vCamFrom, g_fFar); for(i = 0; i < m_i32WaterPlaneNo; ++i) { m_pvPlaneWater[i].x = pvPlane[i].x; m_pvPlaneWater[i].y = pvPlane[i].y; m_pvPlaneWater[i].z = pvPlane[i].z; m_pvPlaneWater[i].nx = c_vPlaneWater.x; m_pvPlaneWater[i].ny = c_vPlaneWater.y; m_pvPlaneWater[i].nz = c_vPlaneWater.z; m_pvPlaneWater[i].tu = VERTTYPEMUL(pvPlane[i].x, f2vt(0.005f)); m_pvPlaneWater[i].tv = VERTTYPEMUL(pvPlane[i].z, f2vt(0.005f)); } // Calculate the Cloud plane m_i32CloudPlaneNo = PVRTMiscCalculateInfinitePlane(&pvPlane->x, sizeof(*pvPlane), &c_vPlaneCloud, &mTmp, &m_vCamFrom, g_fFar); for(i = 0; i < m_i32CloudPlaneNo; ++i) { m_pvPlaneCloud[i].x = pvPlane[i].x; m_pvPlaneCloud[i].y = pvPlane[i].y; m_pvPlaneCloud[i].z = pvPlane[i].z; m_pvPlaneCloud[i].nx = c_vPlaneCloud.x; m_pvPlaneCloud[i].ny = c_vPlaneCloud.y; m_pvPlaneCloud[i].nz = c_vPlaneCloud.z; m_pvPlaneCloud[i].tu = VERTTYPEMUL(pvPlane[i].x, f2vt((1.0f / 100.0f) + m_ui32PrevTime * 0.0002f)); m_pvPlaneCloud[i].tv = VERTTYPEMUL(pvPlane[i].z, f2vt(1.0f / 100.0f)); } } }
/*!**************************************************************************** @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; VERTTYPE 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 = f2vt((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 = (VERTTYPE*) (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, f2vt(1.0f)); PVRTTransform(&vTransPos, &vPos4, &mModel); // Transform the vertex normal so it is in world space vTransNorm.x = VERTTYPEMUL(mModel.f[0], pvSrcN->x) + VERTTYPEMUL(mModel.f[4], pvSrcN->y) + VERTTYPEMUL(mModel.f[8], pvSrcN->z); vTransNorm.y = VERTTYPEMUL(mModel.f[1], pvSrcN->x) + VERTTYPEMUL(mModel.f[5], pvSrcN->y) + VERTTYPEMUL(mModel.f[9], pvSrcN->z); vTransNorm.z = VERTTYPEMUL(mModel.f[2], pvSrcN->x) + VERTTYPEMUL(mModel.f[6], pvSrcN->y) + VERTTYPEMUL(mModel.f[10], pvSrcN->z); vTransNorm.normalize(); pvData[j].x = vTransPos.x + (VERTTYPEMUL(vTransNorm.x, fDepth)); pvData[j].y = vTransPos.y + (VERTTYPEMUL(vTransNorm.y, fDepth)); pvData[j].z = vTransPos.z + (VERTTYPEMUL(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 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 OGLESAntialiasedLines::InitView() { bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); m_iWidth = PVRShellGet(prefWidth); m_iHeight = PVRShellGet(prefHeight); myglClearColor(f2vt(0.6f), f2vt(0.8f), f2vt(1.0f), f2vt(1.0f)); // Initialise Print3D if(m_Print3D.SetTextures(0, m_iWidth, m_iHeight, bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D.\n"); return false; } // Initialise the texture if (PVRTTextureLoadFromPVR("LineRound.pvr", &m_uiTexture) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Failed to load texture.\n"); return false; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Initialise geometry SVertex *paVertices = new SVertex[c_iNumLines * 2]; // 2 vertices per GL_LINE STexVertex *paTexVertices = new STexVertex[c_iNumLines * 8]; // 8 vertices per AA line (includes caps) GLushort *paui16Indices = new GLushort[c_iNumLines * 18]; // 18 indices per AA line (6 triangles) if(!paVertices || !paTexVertices || !paui16Indices) { delete[] paVertices; delete[] paTexVertices; delete[] paui16Indices; PVRShellSet(prefExitMessage, "ERROR: Failed to allocate line vertices and indices.\n"); return false; } srand(0); float fAngleStep = PVRT_TWO_PI / c_iNumLines; VERTTYPE fSize = f2vt(PVRT_MIN(m_iWidth, m_iHeight) * 0.4f); for (int i = 0; i < c_iNumLines; ++i) { // Place the line vertices on a circle paVertices[i*2].vPosition.x = VERTTYPEMUL(fSize, PVRTSIN(fAngleStep * (i + c_fLineArc))); paVertices[i*2].vPosition.y = VERTTYPEMUL(fSize, PVRTCOS(fAngleStep * (i + c_fLineArc))); paVertices[i*2+1].vPosition.x = VERTTYPEMUL(fSize, PVRTSIN(fAngleStep * i)); paVertices[i*2+1].vPosition.y = VERTTYPEMUL(fSize, PVRTCOS(fAngleStep * i)); // Pick a random RGB color paVertices[i*2].uiColor = (0xFF << 24) + ((rand() & 0xFF) << 16) + ((rand() & 0xFF) << 8) + (rand() & 0xFF); paVertices[i*2+1].uiColor = paVertices[i*2].uiColor; // Tessellate the antialiased line TessellateLine(paVertices[i*2].vPosition, paVertices[i*2+1].vPosition, c_fLineWidth, paVertices[i*2].uiColor, &paTexVertices[i * 8], i * 8, &paui16Indices[i * 18]); } // We use 3 VBOs for clarity: // 0: AA line vertex data // 1: AA line index data // 2: GL_LINES vertex data glGenBuffers(3, m_uiVbos); // Bind the VBOs and fill them with data glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(*paTexVertices) * c_iNumLines * 8, paTexVertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiVbos[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*paui16Indices) * c_iNumLines * 18, paui16Indices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[2]); glBufferData(GL_ARRAY_BUFFER, sizeof(*paVertices) * c_iNumLines * 2, paVertices, GL_STATIC_DRAW); // Unbind buffers glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Set projection to use pixel coordinates glMatrixMode(GL_PROJECTION); glLoadIdentity(); myglOrtho(0, f2vt((float)PVRShellGet(prefWidth)), f2vt((float)PVRShellGet(prefHeight)), 0, 0, 1); delete[] paVertices; delete[] paTexVertices; delete[] paui16Indices; 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; }
/*!*************************************************************************** @Function * @Input rhs a PVRTMat4 @Returns result of multiplication @Description matrix multiplication operator PVRTVec4 and PVRTMat4 ****************************************************************************/ PVRTVec4 PVRTVec4::operator*(const PVRTMat4& rhs) const { PVRTVec4 out; out.x = VERTTYPEMUL(x,rhs.f[0])+VERTTYPEMUL(y,rhs.f[1])+VERTTYPEMUL(z,rhs.f[2])+VERTTYPEMUL(w,rhs.f[3]); out.y = VERTTYPEMUL(x,rhs.f[4])+VERTTYPEMUL(y,rhs.f[5])+VERTTYPEMUL(z,rhs.f[6])+VERTTYPEMUL(w,rhs.f[7]); out.z = VERTTYPEMUL(x,rhs.f[8])+VERTTYPEMUL(y,rhs.f[9])+VERTTYPEMUL(z,rhs.f[10])+VERTTYPEMUL(w,rhs.f[11]); out.w = VERTTYPEMUL(x,rhs.f[12])+VERTTYPEMUL(y,rhs.f[13])+VERTTYPEMUL(z,rhs.f[14])+VERTTYPEMUL(w,rhs.f[15]); return out; }
/*!*************************************************************************** @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)); }
/*!**************************************************************************** @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 * Inputs : * 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 OGLESOptimizeMesh::InitView() { SPVRTContext sContext; bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); // Init Print3D to display text on screen if(m_Print3D.SetTextures(&sContext, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D.\n"); return false; } /****************************** ** Create Textures ** *******************************/ if(PVRTTextureLoadFromPVR(c_szModelTexFile, &m_Texture) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Failed to load texture for model.\n"); return false; } /********************************* ** View and Projection Matrices ** *********************************/ // Get Camera info from POD file PVRTVec3 From, To; VERTTYPE fFOV; if(m_Model.nNumCamera) { // Get Camera data from POD Geometry File fFOV = m_Model.GetCameraPos(From, To, 0); fFOV = VERTTYPEMUL(fFOV, f2vt(0.75f)); // Convert from horizontal FOV to vertical FOV (0.75 assumes a 4:3 aspect ratio) } else { fFOV = f2vt(PVRT_PIf / 6); } // View m_mView = PVRTMat4::LookAtRH(From, To, PVRTVec3(f2vt(0.0f), f2vt(1.0f), f2vt(0.0f))); // Projection m_mProj = PVRTMat4::PerspectiveFovRH(fFOV, f2vt((float) PVRShellGet(prefWidth) / (float) PVRShellGet(prefHeight)), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate); glMatrixMode(GL_PROJECTION); myglLoadMatrix(m_mProj.f); /****************************** ** 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); // Define front faces glFrontFace(GL_CW); // Sets the clear colour myglClearColor(f2vt(0.6f), f2vt(0.8f), f2vt(1.0f), f2vt(1.0f)); // Reset the model view matrix to position the light glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Setup timing variables m_ui32LastTime = PVRShellGetTime(); m_ui32FPSFrameCnt = 0; m_fFPS = 0; m_fViewAngle = 0; m_ui32SwitchTimeDiff = 0; #ifndef ENABLE_LOAD_TIME_STRIP LoadVbos(); #endif return true; }