|  | /****************************************************************************** | 
|  |  | 
|  | @File         OGLES2/PVRTPrint3DAPI.cpp | 
|  |  | 
|  | @Title        OGLES2/PVRTPrint3DAPI | 
|  |  | 
|  | @Version | 
|  |  | 
|  | @Copyright    Copyright (c) Imagination Technologies Limited. | 
|  |  | 
|  | @Platform     ANSI compatible | 
|  |  | 
|  | @Description  Displays a text string using 3D polygons. Can be done in two ways: | 
|  | using a window defined by the user or writing straight on the | 
|  | screen. | 
|  |  | 
|  | ******************************************************************************/ | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Includes | 
|  | ****************************************************************************/ | 
|  | #include <stdarg.h> | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  |  | 
|  | #include "PVRTContext.h" | 
|  | #include "PVRTFixedPoint.h" | 
|  | #include "PVRTMatrix.h" | 
|  | #include "PVRTTexture.h" | 
|  | #include "PVRTTextureAPI.h" | 
|  | #include "PVRTPrint3D.h" | 
|  | #include "PVRTString.h" | 
|  | #include "PVRTShader.h" | 
|  | #include "PVRTMap.h" | 
|  |  | 
|  | #include "PVRTPrint3DShaders.h" | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Defines | 
|  | ****************************************************************************/ | 
|  | #define VERTEX_ARRAY			0 | 
|  | #define UV_ARRAY				1 | 
|  | #define COLOR_ARRAY				2 | 
|  |  | 
|  | #define INIT_PRINT3D_STATE		0 | 
|  | #define DEINIT_PRINT3D_STATE	1 | 
|  |  | 
|  | #define UNDEFINED_HANDLE 0xFAFAFAFA | 
|  |  | 
|  | const GLenum c_eMagTable[] = | 
|  | { | 
|  | GL_NEAREST, | 
|  | GL_LINEAR, | 
|  | }; | 
|  |  | 
|  | const GLenum c_eMinTable[] = | 
|  | { | 
|  | GL_NEAREST_MIPMAP_NEAREST, | 
|  | GL_LINEAR_MIPMAP_NEAREST, | 
|  | GL_NEAREST_MIPMAP_LINEAR, | 
|  | GL_LINEAR_MIPMAP_LINEAR, | 
|  | GL_NEAREST, | 
|  | GL_LINEAR, | 
|  | }; | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Enums | 
|  | ****************************************************************************/ | 
|  | enum eFunction | 
|  | { | 
|  | eFunc_DelProg, | 
|  | eFunc_DelShader, | 
|  | eFunc_DelTex | 
|  | }; | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Auxiliary functions | 
|  | ****************************************************************************/ | 
|  | static void DeleteResource(eFunction eType, GLuint& handle) | 
|  | { | 
|  | if(handle == UNDEFINED_HANDLE) | 
|  | return; | 
|  |  | 
|  | switch(eType) | 
|  | { | 
|  | case eFunc_DelProg:		glDeleteProgram(handle);		break; | 
|  | case eFunc_DelShader:	glDeleteShader(handle);			break; | 
|  | case eFunc_DelTex:		glDeleteTextures(1, &handle);	break; | 
|  | } | 
|  |  | 
|  | handle = UNDEFINED_HANDLE; | 
|  | } | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Structures | 
|  | ****************************************************************************/ | 
|  | struct SPVRTPrint3DAPI | 
|  | { | 
|  | GLuint						m_uTextureFont; | 
|  | static int					s_iRefCount; | 
|  |  | 
|  | struct SInstanceData | 
|  | { | 
|  | GLuint				uTextureIMGLogo; | 
|  | GLuint				uTexturePowerVRLogo; | 
|  |  | 
|  | GLuint				uVertexShaderLogo; | 
|  | GLuint				uFragmentShaderLogo; | 
|  | GLuint				uProgramLogo; | 
|  | GLint				mvpLocationLogo; | 
|  |  | 
|  | GLuint				uVertexShaderFont; | 
|  | GLuint				uFragmentShaderFont; | 
|  | GLuint				uProgramFont; | 
|  | GLint				mvpLocationFont; | 
|  |  | 
|  | SInstanceData() : uTextureIMGLogo(UNDEFINED_HANDLE), | 
|  | uTexturePowerVRLogo(UNDEFINED_HANDLE), | 
|  | uVertexShaderLogo(UNDEFINED_HANDLE), | 
|  | uFragmentShaderLogo(UNDEFINED_HANDLE), | 
|  | uProgramLogo(UNDEFINED_HANDLE), | 
|  | mvpLocationLogo(-1), | 
|  | uVertexShaderFont(UNDEFINED_HANDLE), | 
|  | uFragmentShaderFont(UNDEFINED_HANDLE), | 
|  | uProgramFont(UNDEFINED_HANDLE), | 
|  | mvpLocationFont(-1) | 
|  | { | 
|  | } | 
|  |  | 
|  | void Release() | 
|  | { | 
|  | DeleteResource(eFunc_DelProg, uProgramLogo); | 
|  | DeleteResource(eFunc_DelShader, uFragmentShaderLogo); | 
|  | DeleteResource(eFunc_DelShader, uVertexShaderLogo); | 
|  |  | 
|  | DeleteResource(eFunc_DelProg, uProgramLogo); | 
|  | DeleteResource(eFunc_DelShader, uFragmentShaderLogo); | 
|  | DeleteResource(eFunc_DelShader, uVertexShaderLogo); | 
|  |  | 
|  | DeleteResource(eFunc_DelTex, uTextureIMGLogo); | 
|  | DeleteResource(eFunc_DelTex, uTexturePowerVRLogo); | 
|  | } | 
|  | }; | 
|  |  | 
|  | // Optional per-instance data | 
|  | SInstanceData*				m_pInstanceData; | 
|  |  | 
|  | // Shared data across all Print3D instances | 
|  | static SInstanceData		s_InstanceData; | 
|  |  | 
|  | // Used to save the OpenGL state to restore them after drawing */ | 
|  | GLboolean					isCullFaceEnabled; | 
|  | GLboolean					isBlendEnabled; | 
|  | GLboolean					isDepthTestEnabled; | 
|  | GLint						nArrayBufferBinding; | 
|  | GLint						nCurrentProgram; | 
|  | GLint						nTextureBinding2D; | 
|  | GLint						eFrontFace; | 
|  | GLint						eCullFaceMode; | 
|  |  | 
|  | SPVRTPrint3DAPI() : m_pInstanceData(NULL) {} | 
|  | ~SPVRTPrint3DAPI() | 
|  | { | 
|  | if(m_pInstanceData) | 
|  | { | 
|  | delete m_pInstanceData; | 
|  | m_pInstanceData = NULL; | 
|  | } | 
|  | } | 
|  | }; | 
|  |  | 
|  | int SPVRTPrint3DAPI::s_iRefCount = 0; | 
|  | SPVRTPrint3DAPI::SInstanceData SPVRTPrint3DAPI::s_InstanceData; | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Class: CPVRTPrint3D | 
|  | ****************************************************************************/ | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			ReleaseTextures | 
|  | @Description		Deallocate the memory allocated in SetTextures(...) | 
|  | *****************************************************************************/ | 
|  | void CPVRTPrint3D::ReleaseTextures() | 
|  | { | 
|  | #if !defined (DISABLE_PRINT3D) | 
|  |  | 
|  | if(m_pAPI) | 
|  | { | 
|  | // Has local copy | 
|  | if(m_pAPI->m_pInstanceData) | 
|  | { | 
|  | m_pAPI->m_pInstanceData->Release(); | 
|  | } | 
|  | else | 
|  | { | 
|  | if(SPVRTPrint3DAPI::s_iRefCount != 0) | 
|  | { | 
|  | // Just decrease the reference count | 
|  | --SPVRTPrint3DAPI::s_iRefCount; | 
|  | } | 
|  | else | 
|  | { | 
|  | m_pAPI->s_InstanceData.Release(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // Only release textures if they've been allocated | 
|  | if (!m_bTexturesSet) return; | 
|  |  | 
|  | // Release IndexBuffer | 
|  | FREE(m_pwFacesFont); | 
|  | FREE(m_pPrint3dVtx); | 
|  |  | 
|  | // Delete textures | 
|  | glDeleteTextures(1, &m_pAPI->m_uTextureFont); | 
|  |  | 
|  | m_bTexturesSet = false; | 
|  |  | 
|  | FREE(m_pVtxCache); | 
|  |  | 
|  | APIRelease(); | 
|  |  | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @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 | 
|  | } | 
|  |  | 
|  | /************************************************************* | 
|  | *					 PRIVATE FUNCTIONS						 * | 
|  | **************************************************************/ | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			APIInit | 
|  | @Description		Initialisation and texture upload. Should be called only once | 
|  | for a given context. | 
|  | *****************************************************************************/ | 
|  | bool CPVRTPrint3D::APIInit(const SPVRTContext	* const pContext, bool bMakeCopy) | 
|  | { | 
|  | PVRT_UNREFERENCED_PARAMETER(pContext); | 
|  |  | 
|  | m_pAPI = new SPVRTPrint3DAPI; | 
|  | if(!m_pAPI) | 
|  | return false; | 
|  |  | 
|  | if(bMakeCopy) | 
|  | m_pAPI->m_pInstanceData = new SPVRTPrint3DAPI::SInstanceData(); | 
|  |  | 
|  | SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); | 
|  |  | 
|  | // Check to see if these shaders have already been loaded previously. Optimisation as we don't want to load many copies of the same shader! | 
|  | if(	Data.uFragmentShaderLogo != UNDEFINED_HANDLE && Data.uVertexShaderLogo != UNDEFINED_HANDLE && Data.uProgramLogo != UNDEFINED_HANDLE && | 
|  | Data.uFragmentShaderFont != UNDEFINED_HANDLE && Data.uVertexShaderFont != UNDEFINED_HANDLE && Data.uProgramFont != UNDEFINED_HANDLE | 
|  | ) | 
|  | { | 
|  | ++SPVRTPrint3DAPI::s_iRefCount; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Compiles the shaders. For a more detailed explanation, see IntroducingPVRTools | 
|  | CPVRTString error; | 
|  | GLint Linked; | 
|  | bool bRes = true; | 
|  |  | 
|  | bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DFragShaderLogo_fsh, GL_FRAGMENT_SHADER, &Data.uFragmentShaderLogo, &error) == PVR_SUCCESS); | 
|  | bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DVertShaderLogo_vsh, GL_VERTEX_SHADER, &Data.uVertexShaderLogo, &error)  == PVR_SUCCESS); | 
|  |  | 
|  | _ASSERT(bRes); | 
|  |  | 
|  | // Create the 'text' program | 
|  | Data.uProgramLogo = glCreateProgram(); | 
|  | glAttachShader(Data.uProgramLogo, Data.uVertexShaderLogo); | 
|  | glAttachShader(Data.uProgramLogo, Data.uFragmentShaderLogo); | 
|  | glBindAttribLocation(Data.uProgramLogo, VERTEX_ARRAY, "myVertex"); | 
|  | glBindAttribLocation(Data.uProgramLogo, UV_ARRAY, "myUV"); | 
|  |  | 
|  | glLinkProgram(Data.uProgramLogo); | 
|  | glGetProgramiv(Data.uProgramLogo, GL_LINK_STATUS, &Linked); | 
|  |  | 
|  | if (!Linked) | 
|  | bRes = false; | 
|  |  | 
|  | bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DFragShader_fsh, GL_FRAGMENT_SHADER, &Data.uFragmentShaderFont, &error) == PVR_SUCCESS); | 
|  | bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DVertShader_vsh, GL_VERTEX_SHADER, &Data.uVertexShaderFont, &error)  == PVR_SUCCESS); | 
|  |  | 
|  | _ASSERT(bRes); | 
|  |  | 
|  | // Create the 'text' program | 
|  | Data.uProgramFont = glCreateProgram(); | 
|  | glAttachShader(Data.uProgramFont, Data.uVertexShaderFont); | 
|  | glAttachShader(Data.uProgramFont, Data.uFragmentShaderFont); | 
|  | glBindAttribLocation(Data.uProgramFont, VERTEX_ARRAY, "myVertex"); | 
|  | glBindAttribLocation(Data.uProgramFont, UV_ARRAY, "myUV"); | 
|  | glBindAttribLocation(Data.uProgramFont, COLOR_ARRAY, "myColour"); | 
|  |  | 
|  | glLinkProgram(Data.uProgramFont); | 
|  | glGetProgramiv(Data.uProgramFont, GL_LINK_STATUS, &Linked); | 
|  |  | 
|  | if (!Linked) | 
|  | bRes = false; | 
|  |  | 
|  | Data.mvpLocationLogo = glGetUniformLocation(Data.uProgramFont, "myMVPMatrix"); | 
|  | Data.mvpLocationFont = glGetUniformLocation(Data.uProgramLogo, "myMVPMatrix"); | 
|  |  | 
|  | _ASSERT(bRes && Data.mvpLocationLogo != -1 && Data.mvpLocationFont != -1); | 
|  |  | 
|  | return bRes; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			APIRelease | 
|  | @Description		Deinitialisation. | 
|  | *****************************************************************************/ | 
|  | void CPVRTPrint3D::APIRelease() | 
|  | { | 
|  | delete m_pAPI; | 
|  | m_pAPI = 0; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			APIUpLoadIcons | 
|  | @Description		Initialisation and texture upload. Should be called only once | 
|  | for a given context. | 
|  | *****************************************************************************/ | 
|  | bool CPVRTPrint3D::APIUpLoadIcons(const PVRTuint8 * const pIMG, const PVRTuint8 * const pPowerVR) | 
|  | { | 
|  | SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); | 
|  |  | 
|  | // Load Icon texture | 
|  | if(Data.uTextureIMGLogo == UNDEFINED_HANDLE)		// Static, so might already be initialized. | 
|  | if(PVRTTextureLoadFromPointer((unsigned char*)pIMG, &Data.uTextureIMGLogo) != PVR_SUCCESS) | 
|  | return false; | 
|  |  | 
|  | if(Data.uTexturePowerVRLogo == UNDEFINED_HANDLE)		// Static, so might already be initialized. | 
|  | if(PVRTTextureLoadFromPointer((unsigned char*)pPowerVR, &Data.uTexturePowerVRLogo) != PVR_SUCCESS) | 
|  | return false; | 
|  |  | 
|  | glBindTexture(GL_TEXTURE_2D, 0); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function		APIUpLoadTexture | 
|  | @Input			pSource | 
|  | @Output			header | 
|  | @Return			bool	true if successful. | 
|  | @Description	Loads and uploads the font texture from a PVR file. | 
|  | *****************************************************************************/ | 
|  | bool CPVRTPrint3D::APIUpLoadTexture(const PVRTuint8* pSource, const PVRTextureHeaderV3* header, CPVRTMap<PVRTuint32, CPVRTMap<PVRTuint32, MetaDataBlock> >& MetaDataMap) | 
|  | { | 
|  | if(PVRTTextureLoadFromPointer(pSource, &m_pAPI->m_uTextureFont, header, true, 0U, NULL, &MetaDataMap) != PVR_SUCCESS) | 
|  | return false; | 
|  |  | 
|  | glBindTexture(GL_TEXTURE_2D, 0); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			APIRenderStates | 
|  | @Description		Stores, writes and restores Render States | 
|  | *****************************************************************************/ | 
|  | void CPVRTPrint3D::APIRenderStates(int nAction) | 
|  | { | 
|  | // Saving or restoring states ? | 
|  | switch (nAction) | 
|  | { | 
|  | case INIT_PRINT3D_STATE: | 
|  | { | 
|  | // Get previous render states | 
|  | m_pAPI->isCullFaceEnabled = glIsEnabled(GL_CULL_FACE); | 
|  | m_pAPI->isBlendEnabled = glIsEnabled(GL_BLEND); | 
|  | m_pAPI->isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); | 
|  |  | 
|  | glGetIntegerv(GL_FRONT_FACE, &m_pAPI->eFrontFace); | 
|  | glGetIntegerv(GL_CULL_FACE_MODE, &m_pAPI->eCullFaceMode); | 
|  | glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&m_pAPI->nArrayBufferBinding); | 
|  | glGetIntegerv(GL_CURRENT_PROGRAM, &m_pAPI->nCurrentProgram); | 
|  | glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_pAPI->nTextureBinding2D); | 
|  |  | 
|  | /****************************** | 
|  | ** SET PRINT3D RENDER STATES ** | 
|  | ******************************/ | 
|  |  | 
|  | // Culling | 
|  | glFrontFace(GL_CCW); | 
|  | glCullFace(GL_BACK); | 
|  | glEnable(GL_CULL_FACE); | 
|  |  | 
|  | // Set blending mode | 
|  | glEnable(GL_BLEND); | 
|  | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 
|  |  | 
|  | // Set Z compare properties | 
|  | glDisable(GL_DEPTH_TEST); | 
|  |  | 
|  | // Set the default GL_ARRAY_BUFFER | 
|  | glBindBuffer(GL_ARRAY_BUFFER, 0); | 
|  |  | 
|  | // texture | 
|  | glActiveTexture(GL_TEXTURE0); | 
|  | break; | 
|  | } | 
|  | case DEINIT_PRINT3D_STATE: | 
|  | // Restore some values | 
|  | if (!m_pAPI->isCullFaceEnabled) glDisable(GL_CULL_FACE); | 
|  | if (!m_pAPI->isBlendEnabled) glDisable(GL_BLEND); | 
|  | if (m_pAPI->isDepthTestEnabled) glEnable(GL_DEPTH_TEST); | 
|  | glCullFace((GLenum)m_pAPI->eCullFaceMode); | 
|  | glFrontFace((GLenum)m_pAPI->eFrontFace); | 
|  | glBindBuffer(GL_ARRAY_BUFFER,m_pAPI->nArrayBufferBinding); | 
|  | glBindTexture(GL_TEXTURE_2D, m_pAPI->nTextureBinding2D); | 
|  | glUseProgram(m_pAPI->nCurrentProgram); // Unset print3ds program | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Local code | 
|  | ****************************************************************************/ | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @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); | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | End of file (PVRTPrint3DAPI.cpp) | 
|  | *****************************************************************************/ | 
|  |  |