/***************************************************************************** @Function CPVRTPrint3D @Description Init some values. *****************************************************************************/ CPVRTPrint3D::CPVRTPrint3D() { #if !defined(DISABLE_PRINT3D) // Initialise all variables memset(this, 0, sizeof(*this)); PVRTMatrixIdentity(m_mModelView); PVRTMatrixIdentity(m_mProj); #endif }
/***************************************************************************** @Function CPVRTPrint3D @Description Init some values. *****************************************************************************/ CPVRTPrint3D::CPVRTPrint3D() : m_pAPI(NULL), m_uLogoToDisplay(ePVRTPrint3DLogoNone), m_pwFacesFont(NULL), m_pPrint3dVtx(NULL), m_bTexturesSet(false), m_pVtxCache(NULL), m_nVtxCache(0), m_nVtxCacheMax(0), m_bRotate(false), m_nCachedNumVerts(0), m_pwzPreviousString(NULL), m_pszPreviousString(NULL), m_fPrevScale(0.0f), m_fPrevX(0.0f), m_fPrevY(0.0f), m_uiPrevCol(0), m_pUVs(NULL), m_pKerningPairs(NULL), m_pCharMatrics(NULL), m_fTexW(0.0f), m_fTexH(0.0f), m_pRects(NULL), m_pYOffsets(NULL), m_uiNextLineH(0), m_uiSpaceWidth(0), m_uiNumCharacters(0), m_uiNumKerningPairs(0), m_uiAscent(0), m_pszCharacterList(NULL), m_bHasMipmaps(false), m_bUsingProjection(false) { memset(m_fScreenScale, 0, sizeof(m_fScreenScale)); memset(m_ui32ScreenDim, 0, sizeof(m_ui32ScreenDim)); PVRTMatrixIdentity(m_mModelView); PVRTMatrixIdentity(m_mProj); m_pwzPreviousString = new wchar_t[MAX_LETTERS + 1]; m_pszPreviousString = new char[MAX_LETTERS + 1]; m_pwzPreviousString[0] = 0; m_pszPreviousString[0] = 0; m_eFilterMethod[eFilterProc_Min] = eFilter_Default; m_eFilterMethod[eFilterProc_Mag] = eFilter_Default; m_eFilterMethod[eFilterProc_Mip] = eFilter_MipDefault; }
/*!*************************************************************************** @Function APIDrawLogo @Description *****************************************************************************/ void CPVRTPrint3D::APIDrawLogo(const EPVRTPrint3DLogo uLogoToDisplay, const int ePos) { GLuint tex = 0; float fScale = 1.0f; if(m_ui32ScreenDim[1] >= 720) fScale = 2.0f; SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); switch(uLogoToDisplay) { case ePVRTPrint3DLogoIMG: tex = Data.uTextureIMGLogo; break; case ePVRTPrint3DLogoPowerVR: tex = Data.uTexturePowerVRLogo; break; default: return; // Logo not recognised } const float fLogoXSizeHalf = (128.0f / m_ui32ScreenDim[0]); const float fLogoYSizeHalf = (64.0f / m_ui32ScreenDim[1]); const float fLogoXShift = 0.035f / fScale; const float fLogoYShift = 0.035f / fScale; const float fLogoSizeXHalfShifted = fLogoXSizeHalf + fLogoXShift; const float fLogoSizeYHalfShifted = fLogoYSizeHalf + fLogoYShift; static float Vertices[] = { -fLogoXSizeHalf, fLogoYSizeHalf , 0.5f, -fLogoXSizeHalf, -fLogoYSizeHalf, 0.5f, fLogoXSizeHalf , fLogoYSizeHalf , 0.5f, fLogoXSizeHalf , -fLogoYSizeHalf, 0.5f }; static float UVs[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; float *pVertices = ( (float*)&Vertices ); float *pUV = ( (float*)&UVs ); // Matrices PVRTMATRIX matModelView; PVRTMATRIX matTransform; PVRTMatrixIdentity(matModelView); PVRTMatrixScaling(matTransform, f2vt(fScale), f2vt(fScale), f2vt(1.0f)); PVRTMatrixMultiply(matModelView, matModelView, matTransform); int nXPos = (ePos & eLeft) ? -1 : 1; int nYPos = (ePos & eTop) ? 1 : -1; PVRTMatrixTranslation(matTransform, nXPos - (fLogoSizeXHalfShifted * fScale * nXPos), nYPos - (fLogoSizeYHalfShifted * fScale * nYPos), 0.0f); PVRTMatrixMultiply(matModelView, matModelView, matTransform); if(m_bRotate) { PVRTMatrixRotationZ(matTransform, -90.0f*PVRT_PI/180.0f); PVRTMatrixMultiply(matModelView, matModelView, matTransform); } _ASSERT(Data.uProgramLogo != UNDEFINED_HANDLE); glUseProgram(Data.uProgramLogo); // Bind the model-view-projection to the shader glUniformMatrix4fv(Data.mvpLocationLogo, 1, GL_FALSE, matModelView.f); // Render states glActiveTexture(GL_TEXTURE0); _ASSERT(tex != UNDEFINED_HANDLE); glBindTexture(GL_TEXTURE_2D, tex); // Vertices glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(UV_ARRAY); glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, (const void*)pVertices); glVertexAttribPointer(UV_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*)pUV); glDrawArrays(GL_TRIANGLE_STRIP,0,4); glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(UV_ARRAY); }
/*!*************************************************************************** @Function Flush @Description Flushes all the print text commands *****************************************************************************/ int CPVRTPrint3D::Flush() { #if !defined (DISABLE_PRINT3D) int nTris, nVtx, nVtxBase, nTrisTot = 0; _ASSERT((m_nVtxCache % 4) == 0); _ASSERT(m_nVtxCache <= m_nVtxCacheMax); // Save render states APIRenderStates(INIT_PRINT3D_STATE); // Draw font if(m_nVtxCache) { SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); float fW = m_fScreenScale[0] * 640.0f; float fH = m_fScreenScale[1] * 480.0f; PVRTMat4 mxOrtho = PVRTMat4::Ortho(0.0f, 0.0f, fW, -fH, -1.0f, 1.0f, PVRTMat4::OGL, m_bRotate); if(m_bRotate) { PVRTMat4 mxTrans = PVRTMat4::Translation(-fH,fW,0.0f); mxOrtho = mxOrtho * mxTrans; } // Use the shader _ASSERT(Data.uProgramFont != UNDEFINED_HANDLE); glUseProgram(Data.uProgramFont); // Bind the projection and modelview matrices to the shader PVRTMat4& mProj = (m_bUsingProjection ? m_mProj : mxOrtho); PVRTMat4 mMVP = mProj * m_mModelView; glUniformMatrix4fv(Data.mvpLocationFont, 1, GL_FALSE, mMVP.f); // Reset m_bUsingProjection = false; PVRTMatrixIdentity(m_mModelView); // Set client states glEnableVertexAttribArray(VERTEX_ARRAY); glEnableVertexAttribArray(COLOR_ARRAY); glEnableVertexAttribArray(UV_ARRAY); // texture glBindTexture(GL_TEXTURE_2D, m_pAPI->m_uTextureFont); unsigned int uiIndex = m_eFilterMethod[eFilterProc_Min] + (m_eFilterMethod[eFilterProc_Mip]*2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, c_eMagTable[m_eFilterMethod[eFilterProc_Mag]]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_eMinTable[uiIndex]); nTrisTot = m_nVtxCache >> 1; // Render the text then. Might need several submissions. nVtxBase = 0; while(m_nVtxCache) { nVtx = PVRT_MIN(m_nVtxCache, 0xFFFC); nTris = nVtx >> 1; _ASSERT(nTris <= (PVRTPRINT3D_MAX_RENDERABLE_LETTERS*2)); _ASSERT((nVtx % 4) == 0); // Draw triangles glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(SPVRTPrint3DAPIVertex), (const void*)&m_pVtxCache[nVtxBase].sx); glVertexAttribPointer(COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SPVRTPrint3DAPIVertex), (const void*)&m_pVtxCache[nVtxBase].color); glVertexAttribPointer(UV_ARRAY, 2, GL_FLOAT, GL_FALSE, sizeof(SPVRTPrint3DAPIVertex), (const void*)&m_pVtxCache[nVtxBase].tu); glDrawElements(GL_TRIANGLES, nTris * 3, GL_UNSIGNED_SHORT, m_pwFacesFont); if(glGetError()) { PVRTERROR_OUTPUT_DEBUG("glDrawElements(GL_TRIANGLES, (VertexCount/2)*3, GL_UNSIGNED_SHORT, m_pFacesFont); failed\n"); } nVtxBase += nVtx; m_nVtxCache -= nVtx; } // Restore render states glDisableVertexAttribArray(VERTEX_ARRAY); glDisableVertexAttribArray(COLOR_ARRAY); glDisableVertexAttribArray(UV_ARRAY); } // Draw a logo if requested #if !defined(FORCE_NO_LOGO) // User selected logos if(m_uLogoToDisplay & ePVRTPrint3DLogoPowerVR && m_uLogoToDisplay & ePVRTPrint3DLogoIMG) { APIDrawLogo(ePVRTPrint3DLogoIMG, eBottom | eRight); // IMG to the right APIDrawLogo(ePVRTPrint3DLogoPowerVR, eBottom | eLeft); // PVR to the left } else if(m_uLogoToDisplay & ePVRTPrint3DLogoPowerVR) { APIDrawLogo(ePVRTPrint3DLogoPowerVR, eBottom | eRight); // logo to the right } else if(m_uLogoToDisplay & ePVRTPrint3DLogoIMG) { APIDrawLogo(ePVRTPrint3DLogoIMG, eBottom | eRight); // logo to the right } #endif // Restore render states APIRenderStates(DEINIT_PRINT3D_STATE); return nTrisTot; #else return 0; #endif }