/*!*************************************************************************** @Function UpdateLine @Description *****************************************************************************/ unsigned int CPVRTPrint3D::UpdateLine(const float fZPos, float XPos, float YPos, const float fScale, const unsigned int Colour, const CPVRTArray<PVRTuint32>& Text, SPVRTPrint3DAPIVertex * const pVertices) { /* Nothing to update */ if (Text.GetSize() == 0) return 0; if(!m_bUsingProjection) { XPos *= m_fScreenScale[0]; YPos *= m_fScreenScale[1]; } YPos -= PVRTMakeWhole(m_uiAscent * fScale); float fPreXPos = XPos; // The original offset (after screen scale modification) of the X coordinate. float fKernOffset; float fAOff; float fYOffset; unsigned int VertexCount = 0; PVRTint32 NextChar; unsigned int uiNumCharsInString = Text.GetSize(); for(unsigned int uiIndex = 0; uiIndex < uiNumCharsInString; uiIndex++) { if(uiIndex > MAX_LETTERS) break; // Newline if(Text[uiIndex] == 0x0A) { XPos = fPreXPos; YPos -= PVRTMakeWhole(m_uiNextLineH * fScale); continue; } // Get the character PVRTuint32 uiIdx = FindCharacter(Text[uiIndex]); // Not found. Add a space. if(uiIdx == PVRTPRINT3D_INVALID_CHAR) // No character found. Add a space. { XPos += PVRTMakeWhole(m_uiSpaceWidth * fScale); continue; } fKernOffset = 0; fYOffset = PVRTMakeWhole(m_pYOffsets[uiIdx] * fScale); fAOff = PVRTMakeWhole(m_pCharMatrics[uiIdx].nXOff * fScale); // The A offset. Could include overhang or underhang. if(uiIndex < uiNumCharsInString - 1) { NextChar = Text[uiIndex + 1]; ApplyKerning(Text[uiIndex], NextChar, fKernOffset); } /* Filling vertex data */ pVertices[VertexCount+0].sx = f2vt(XPos + fAOff + 0.0f); pVertices[VertexCount+0].sy = f2vt(YPos + fYOffset + 0.0f); pVertices[VertexCount+0].sz = f2vt(fZPos); pVertices[VertexCount+0].rhw = f2vt(1.0f); pVertices[VertexCount+0].tu = f2vt(m_pUVs[uiIdx].fUL); pVertices[VertexCount+0].tv = f2vt(m_pUVs[uiIdx].fVT); pVertices[VertexCount+1].sx = f2vt(XPos + fAOff + PVRTMakeWhole(m_pRects[uiIdx].nW * fScale)); pVertices[VertexCount+1].sy = f2vt(YPos + fYOffset + 0.0f); pVertices[VertexCount+1].sz = f2vt(fZPos); pVertices[VertexCount+1].rhw = f2vt(1.0f); pVertices[VertexCount+1].tu = f2vt(m_pUVs[uiIdx].fUR); pVertices[VertexCount+1].tv = f2vt(m_pUVs[uiIdx].fVT); pVertices[VertexCount+2].sx = f2vt(XPos + fAOff + 0.0f); pVertices[VertexCount+2].sy = f2vt(YPos + fYOffset - PVRTMakeWhole(m_pRects[uiIdx].nH * fScale)); pVertices[VertexCount+2].sz = f2vt(fZPos); pVertices[VertexCount+2].rhw = f2vt(1.0f); pVertices[VertexCount+2].tu = f2vt(m_pUVs[uiIdx].fUL); pVertices[VertexCount+2].tv = f2vt(m_pUVs[uiIdx].fVB); pVertices[VertexCount+3].sx = f2vt(XPos + fAOff + PVRTMakeWhole(m_pRects[uiIdx].nW * fScale)); pVertices[VertexCount+3].sy = f2vt(YPos + fYOffset - PVRTMakeWhole(m_pRects[uiIdx].nH * fScale)); pVertices[VertexCount+3].sz = f2vt(fZPos); pVertices[VertexCount+3].rhw = f2vt(1.0f); pVertices[VertexCount+3].tu = f2vt(m_pUVs[uiIdx].fUR); pVertices[VertexCount+3].tv = f2vt(m_pUVs[uiIdx].fVB); pVertices[VertexCount+0].color = Colour; pVertices[VertexCount+1].color = Colour; pVertices[VertexCount+2].color = Colour; pVertices[VertexCount+3].color = Colour; XPos = XPos + PVRTMakeWhole((m_pCharMatrics[uiIdx].nAdv + fKernOffset) * fScale); // Add on this characters width VertexCount += 4; } return VertexCount; }
/*!*************************************************************************** @Function RenderText @Description Draws the 3D text and scrolls in to the screen. *****************************************************************************/ void OGLES2IntroducingPrint3D::RenderText() { float fAspect = (float)PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight); bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); // Calculate the frame delta. unsigned long ulNow = PVRShellGetTime(); if(m_ulPrevFrameT == 0) m_ulPrevFrameT = ulNow; float fDT = (ulNow - m_ulPrevFrameT) * 0.001f; m_ulPrevFrameT = ulNow; // Calculate the FPS scale. float fFPSScale = fDT / c_fTargetFPS; // Move the text. Progressively speed up. float fSpeedInc = 0.0f; if(m_fTextOffset > 0.0f) fSpeedInc = m_fTextOffset / TEXT_END_Y; m_fTextOffset += (0.75f + (1.0f * fSpeedInc)) * fFPSScale; if(m_fTextOffset > TEXT_END_Y) m_fTextOffset = TEXT_START_Y; PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(0.7f, fAspect, 1.0f, 2000.0f, PVRTMat4::OGL, bRotate); PVRTMat4 mScale = PVRTMat4::Scale(PVRTVec3(1.0f, -1.0f, 1.0f)); PVRTMat4 mCamera = PVRTMat4::LookAtRH(PVRTVec3(0.0f, -900.0f, 700.0f), PVRTVec3(0.0f,-200.0f,0.0f), PVRTVec3(0.0f,1.0f,0.0f)); PVRTMat4 mTrans = PVRTMat4::Translation(PVRTVec3(0.0f, m_fTextOffset, 0.0f)); PVRTMat4 mModelView = mCamera * mTrans; float fStrWidth = 0.0f; /* Print3D can optionally be provided with user-defined projection and model-view matrices which allow custom layout of text. Here we are proving both a projection and model-view matrix. The projection matrix specified here uses perspective projection which will provide the 3D effect. The model-view matrix positions the the text in world space providing the 'camera' position and the scrolling of the text. */ m_CentralText.SetProjection(mProjection); m_CentralText.SetModelView(mModelView); /* The previous method (RenderTitle()) explains the following functions in more detail however put simply, we are looping the entire array of loaded text which is encoded in UTF-8. Print3D batches this internally and the call to Flush() will render the text to the frame buffer. We are also fading out the text over a certain distance. */ float fPos, fFade; unsigned int uiCol; for(unsigned int uiIndex = 0; uiIndex < m_TextLines.GetSize(); ++uiIndex) { fPos = (m_fTextOffset - (uiIndex * 36.0f)); fFade = 1.0f; if(fPos > TEXT_FADE_START) { fFade = PVRTClamp(1.0f - ((fPos - TEXT_FADE_START) / (TEXT_FADE_END - TEXT_FADE_START)), 0.0f, 1.0f); } uiCol = (((unsigned int)(fFade * 255)) << 24) | 0x00FFFF; m_CentralText.MeasureText(&fStrWidth, NULL, 1.0f, (const char*)m_TextLines[uiIndex]); m_CentralText.Print3D(-(fStrWidth*0.5f), -(uiIndex * 36.0f), 1.0f, uiCol, (const char*)m_TextLines[uiIndex]); } m_CentralText.Flush(); }