/*!*************************************************************************** @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 }
/*!*************************************************************************** @Function DisplayWindow @Input dwWin @Return PVR_SUCCESS or PVR_FAIL @Description Display window. This function MUST be called between a BeginScene/EndScene pair as it uses D3D render primitive calls. CPVRTPrint3D::SetTextures(...) must have been called beforehand. *****************************************************************************/ EPVRTError CPVRTPrint3D::DisplayWindow(unsigned int dwWin) { #if !defined (DISABLE_PRINT3D) unsigned int i; float fTitleSize = 0.0f; // No textures! so... no window if (!m_bTexturesSet) { PVRTErrorOutputDebug("DisplayWindow : You must call PVRTPrint3D::SetTextures(...) before using this function.\n"); return PVR_FAIL; } // Update Vertex data only when needed if(m_pWin[dwWin].bNeedUpdated) { // TITLE if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE) { // Set title size if(m_pWin[dwWin].fTitleFontSize < 0.0f) fTitleSize = 8.0f + 16.0f; else fTitleSize = m_pWin[dwWin].fTitleFontSize * 23.5f + 16.0f; // Title UpdateTitleVertexBuffer(dwWin); // Background if (!(m_pWin[dwWin].dwFlags & Print3D_FULL_TRANS)) { // Draw title background UpdateBackgroundWindow( dwWin, m_pWin[dwWin].dwTitleBaseColor, 0.0f, m_pWin[dwWin].fWinPos[0], m_pWin[dwWin].fWinPos[1], m_pWin[dwWin].fWinSize[0], fTitleSize, &m_pWin[dwWin].pWindowVtxTitle); } } // Main text UpdateMainTextVertexBuffer(dwWin); UpdateBackgroundWindow( dwWin, m_pWin[dwWin].dwWinBaseColor, 0.0f, m_pWin[dwWin].fWinPos[0], (m_pWin[dwWin].fWinPos[1] + fTitleSize), m_pWin[dwWin].fWinSize[0], m_pWin[dwWin].fWinSize[1], &m_pWin[dwWin].pWindowVtxText); // Don't update until next change makes it needed m_pWin[dwWin].bNeedUpdated = false; } // Ensure any previously drawn text has been submitted before drawing the window. Flush(); // Save current render states APIRenderStates(0); // DRAW TITLE if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE) { if (!(m_pWin[dwWin].dwFlags & Print3D_FULL_TRANS)) { DrawBackgroundWindowUP(m_pWin[dwWin].pWindowVtxTitle, (m_pWin[dwWin].dwFlags & Print3D_FULL_OPAQUE) ? true : false, (m_pWin[dwWin].dwFlags & Print3D_NO_BORDER) ? false : true); } // Left and Right text DrawLineUP(m_pWin[dwWin].pTitleVtxL, m_pWin[dwWin].nTitleVerticesL); DrawLineUP(m_pWin[dwWin].pTitleVtxR, m_pWin[dwWin].nTitleVerticesR); } // DRAW WINDOW if (m_pWin[dwWin].dwFlags & Print3D_WIN_ACTIVE) { // Background if (!(m_pWin[dwWin].dwFlags & Print3D_FULL_TRANS)) { DrawBackgroundWindowUP(m_pWin[dwWin].pWindowVtxText, (m_pWin[dwWin].dwFlags & Print3D_FULL_OPAQUE) ? true : false, (m_pWin[dwWin].dwFlags & Print3D_NO_BORDER) ? false : true); } // Text, line by line for (i=0; i<m_pWin[dwWin].dwBufferSizeY; i++) { DrawLineUP(m_pWin[dwWin].pLineVtx[i], m_pWin[dwWin].nLineVertices[i]); } } // Restore render states APIRenderStates(1); #endif return PVR_SUCCESS; }