/*!***************************************************************************
 @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
}
Example #2
0
/*!***************************************************************************
 @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;
}