1/****************************************************************************** 2 3 @File OGLES2/PVRTPrint3DAPI.cpp 4 5 @Title OGLES2/PVRTPrint3DAPI 6 7 @Version 8 9 @Copyright Copyright (c) Imagination Technologies Limited. 10 11 @Platform ANSI compatible 12 13 @Description Displays a text string using 3D polygons. Can be done in two ways: 14 using a window defined by the user or writing straight on the 15 screen. 16 17******************************************************************************/ 18 19/**************************************************************************** 20** Includes 21****************************************************************************/ 22#include <stdarg.h> 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26 27#include "PVRTContext.h" 28#include "PVRTFixedPoint.h" 29#include "PVRTMatrix.h" 30#include "PVRTTexture.h" 31#include "PVRTTextureAPI.h" 32#include "PVRTPrint3D.h" 33#include "PVRTString.h" 34#include "PVRTShader.h" 35#include "PVRTMap.h" 36 37#include "PVRTPrint3DShaders.h" 38 39/**************************************************************************** 40** Defines 41****************************************************************************/ 42#define VERTEX_ARRAY 0 43#define UV_ARRAY 1 44#define COLOR_ARRAY 2 45 46#define INIT_PRINT3D_STATE 0 47#define DEINIT_PRINT3D_STATE 1 48 49#define UNDEFINED_HANDLE 0xFAFAFAFA 50 51const GLenum c_eMagTable[] = 52{ 53 GL_NEAREST, 54 GL_LINEAR, 55}; 56 57const GLenum c_eMinTable[] = 58{ 59 GL_NEAREST_MIPMAP_NEAREST, 60 GL_LINEAR_MIPMAP_NEAREST, 61 GL_NEAREST_MIPMAP_LINEAR, 62 GL_LINEAR_MIPMAP_LINEAR, 63 GL_NEAREST, 64 GL_LINEAR, 65}; 66 67/**************************************************************************** 68** Enums 69****************************************************************************/ 70enum eFunction 71{ 72 eFunc_DelProg, 73 eFunc_DelShader, 74 eFunc_DelTex 75}; 76 77/**************************************************************************** 78** Auxiliary functions 79****************************************************************************/ 80static void DeleteResource(eFunction eType, GLuint& handle) 81{ 82 if(handle == UNDEFINED_HANDLE) 83 return; 84 85 switch(eType) 86 { 87 case eFunc_DelProg: glDeleteProgram(handle); break; 88 case eFunc_DelShader: glDeleteShader(handle); break; 89 case eFunc_DelTex: glDeleteTextures(1, &handle); break; 90 } 91 92 handle = UNDEFINED_HANDLE; 93} 94 95/**************************************************************************** 96** Structures 97****************************************************************************/ 98struct SPVRTPrint3DAPI 99{ 100 GLuint m_uTextureFont; 101 static int s_iRefCount; 102 103 struct SInstanceData 104 { 105 GLuint uTextureIMGLogo; 106 GLuint uTexturePowerVRLogo; 107 108 GLuint uVertexShaderLogo; 109 GLuint uFragmentShaderLogo; 110 GLuint uProgramLogo; 111 GLint mvpLocationLogo; 112 113 GLuint uVertexShaderFont; 114 GLuint uFragmentShaderFont; 115 GLuint uProgramFont; 116 GLint mvpLocationFont; 117 118 SInstanceData() : uTextureIMGLogo(UNDEFINED_HANDLE), 119 uTexturePowerVRLogo(UNDEFINED_HANDLE), 120 uVertexShaderLogo(UNDEFINED_HANDLE), 121 uFragmentShaderLogo(UNDEFINED_HANDLE), 122 uProgramLogo(UNDEFINED_HANDLE), 123 mvpLocationLogo(-1), 124 uVertexShaderFont(UNDEFINED_HANDLE), 125 uFragmentShaderFont(UNDEFINED_HANDLE), 126 uProgramFont(UNDEFINED_HANDLE), 127 mvpLocationFont(-1) 128 { 129 } 130 131 void Release() 132 { 133 DeleteResource(eFunc_DelProg, uProgramLogo); 134 DeleteResource(eFunc_DelShader, uFragmentShaderLogo); 135 DeleteResource(eFunc_DelShader, uVertexShaderLogo); 136 137 DeleteResource(eFunc_DelProg, uProgramLogo); 138 DeleteResource(eFunc_DelShader, uFragmentShaderLogo); 139 DeleteResource(eFunc_DelShader, uVertexShaderLogo); 140 141 DeleteResource(eFunc_DelTex, uTextureIMGLogo); 142 DeleteResource(eFunc_DelTex, uTexturePowerVRLogo); 143 } 144 }; 145 146 // Optional per-instance data 147 SInstanceData* m_pInstanceData; 148 149 // Shared data across all Print3D instances 150 static SInstanceData s_InstanceData; 151 152 // Used to save the OpenGL state to restore them after drawing */ 153 GLboolean isCullFaceEnabled; 154 GLboolean isBlendEnabled; 155 GLboolean isDepthTestEnabled; 156 GLint nArrayBufferBinding; 157 GLint nCurrentProgram; 158 GLint nTextureBinding2D; 159 GLint eFrontFace; 160 GLint eCullFaceMode; 161 162 SPVRTPrint3DAPI() : m_pInstanceData(NULL) {} 163 ~SPVRTPrint3DAPI() 164 { 165 if(m_pInstanceData) 166 { 167 delete m_pInstanceData; 168 m_pInstanceData = NULL; 169 } 170 } 171}; 172 173int SPVRTPrint3DAPI::s_iRefCount = 0; 174SPVRTPrint3DAPI::SInstanceData SPVRTPrint3DAPI::s_InstanceData; 175 176/**************************************************************************** 177** Class: CPVRTPrint3D 178****************************************************************************/ 179 180/*!*************************************************************************** 181 @Function ReleaseTextures 182 @Description Deallocate the memory allocated in SetTextures(...) 183*****************************************************************************/ 184void CPVRTPrint3D::ReleaseTextures() 185{ 186#if !defined (DISABLE_PRINT3D) 187 188 if(m_pAPI) 189 { 190 // Has local copy 191 if(m_pAPI->m_pInstanceData) 192 { 193 m_pAPI->m_pInstanceData->Release(); 194 } 195 else 196 { 197 if(SPVRTPrint3DAPI::s_iRefCount != 0) 198 { 199 // Just decrease the reference count 200 --SPVRTPrint3DAPI::s_iRefCount; 201 } 202 else 203 { 204 m_pAPI->s_InstanceData.Release(); 205 } 206 } 207 } 208 209 // Only release textures if they've been allocated 210 if (!m_bTexturesSet) return; 211 212 // Release IndexBuffer 213 FREE(m_pwFacesFont); 214 FREE(m_pPrint3dVtx); 215 216 // Delete textures 217 glDeleteTextures(1, &m_pAPI->m_uTextureFont); 218 219 m_bTexturesSet = false; 220 221 FREE(m_pVtxCache); 222 223 APIRelease(); 224 225#endif 226} 227 228/*!*************************************************************************** 229 @Function Flush 230 @Description Flushes all the print text commands 231*****************************************************************************/ 232int CPVRTPrint3D::Flush() 233{ 234#if !defined (DISABLE_PRINT3D) 235 236 int nTris, nVtx, nVtxBase, nTrisTot = 0; 237 238 _ASSERT((m_nVtxCache % 4) == 0); 239 _ASSERT(m_nVtxCache <= m_nVtxCacheMax); 240 241 // Save render states 242 APIRenderStates(INIT_PRINT3D_STATE); 243 244 // Draw font 245 if(m_nVtxCache) 246 { 247 SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); 248 249 float fW = m_fScreenScale[0] * 640.0f; 250 float fH = m_fScreenScale[1] * 480.0f; 251 252 PVRTMat4 mxOrtho = PVRTMat4::Ortho(0.0f, 0.0f, fW, -fH, -1.0f, 1.0f, PVRTMat4::OGL, m_bRotate); 253 if(m_bRotate) 254 { 255 PVRTMat4 mxTrans = PVRTMat4::Translation(-fH,fW,0.0f); 256 mxOrtho = mxOrtho * mxTrans; 257 } 258 259 // Use the shader 260 _ASSERT(Data.uProgramFont != UNDEFINED_HANDLE); 261 glUseProgram(Data.uProgramFont); 262 263 // Bind the projection and modelview matrices to the shader 264 PVRTMat4& mProj = (m_bUsingProjection ? m_mProj : mxOrtho); 265 PVRTMat4 mMVP = mProj * m_mModelView; 266 glUniformMatrix4fv(Data.mvpLocationFont, 1, GL_FALSE, mMVP.f); 267 268 // Reset 269 m_bUsingProjection = false; 270 PVRTMatrixIdentity(m_mModelView); 271 272 // Set client states 273 glEnableVertexAttribArray(VERTEX_ARRAY); 274 glEnableVertexAttribArray(COLOR_ARRAY); 275 glEnableVertexAttribArray(UV_ARRAY); 276 277 // texture 278 glBindTexture(GL_TEXTURE_2D, m_pAPI->m_uTextureFont); 279 280 unsigned int uiIndex = m_eFilterMethod[eFilterProc_Min] + (m_eFilterMethod[eFilterProc_Mip]*2); 281 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, c_eMagTable[m_eFilterMethod[eFilterProc_Mag]]); 282 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_eMinTable[uiIndex]); 283 284 nTrisTot = m_nVtxCache >> 1; 285 286 // Render the text then. Might need several submissions. 287 nVtxBase = 0; 288 while(m_nVtxCache) 289 { 290 nVtx = PVRT_MIN(m_nVtxCache, 0xFFFC); 291 nTris = nVtx >> 1; 292 293 _ASSERT(nTris <= (PVRTPRINT3D_MAX_RENDERABLE_LETTERS*2)); 294 _ASSERT((nVtx % 4) == 0); 295 296 // Draw triangles 297 glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(SPVRTPrint3DAPIVertex), (const void*)&m_pVtxCache[nVtxBase].sx); 298 glVertexAttribPointer(COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SPVRTPrint3DAPIVertex), (const void*)&m_pVtxCache[nVtxBase].color); 299 glVertexAttribPointer(UV_ARRAY, 2, GL_FLOAT, GL_FALSE, sizeof(SPVRTPrint3DAPIVertex), (const void*)&m_pVtxCache[nVtxBase].tu); 300 301 glDrawElements(GL_TRIANGLES, nTris * 3, GL_UNSIGNED_SHORT, m_pwFacesFont); 302 303 if(glGetError()) 304 { 305 PVRTERROR_OUTPUT_DEBUG("glDrawElements(GL_TRIANGLES, (VertexCount/2)*3, GL_UNSIGNED_SHORT, m_pFacesFont); failed\n"); 306 } 307 308 nVtxBase += nVtx; 309 m_nVtxCache -= nVtx; 310 } 311 312 // Restore render states 313 glDisableVertexAttribArray(VERTEX_ARRAY); 314 glDisableVertexAttribArray(COLOR_ARRAY); 315 glDisableVertexAttribArray(UV_ARRAY); 316 } 317 // Draw a logo if requested 318#if !defined(FORCE_NO_LOGO) 319 // User selected logos 320 if(m_uLogoToDisplay & ePVRTPrint3DLogoPowerVR && m_uLogoToDisplay & ePVRTPrint3DLogoIMG) 321 { 322 APIDrawLogo(ePVRTPrint3DLogoIMG, eBottom | eRight); // IMG to the right 323 APIDrawLogo(ePVRTPrint3DLogoPowerVR, eBottom | eLeft); // PVR to the left 324 } 325 else if(m_uLogoToDisplay & ePVRTPrint3DLogoPowerVR) 326 { 327 APIDrawLogo(ePVRTPrint3DLogoPowerVR, eBottom | eRight); // logo to the right 328 } 329 else if(m_uLogoToDisplay & ePVRTPrint3DLogoIMG) 330 { 331 APIDrawLogo(ePVRTPrint3DLogoIMG, eBottom | eRight); // logo to the right 332 } 333#endif 334 335 // Restore render states 336 APIRenderStates(DEINIT_PRINT3D_STATE); 337 338 return nTrisTot; 339 340#else 341 return 0; 342#endif 343} 344 345/************************************************************* 346* PRIVATE FUNCTIONS * 347**************************************************************/ 348 349/*!*************************************************************************** 350 @Function APIInit 351 @Description Initialisation and texture upload. Should be called only once 352 for a given context. 353*****************************************************************************/ 354bool CPVRTPrint3D::APIInit(const SPVRTContext * const pContext, bool bMakeCopy) 355{ 356 PVRT_UNREFERENCED_PARAMETER(pContext); 357 358 m_pAPI = new SPVRTPrint3DAPI; 359 if(!m_pAPI) 360 return false; 361 362 if(bMakeCopy) 363 m_pAPI->m_pInstanceData = new SPVRTPrint3DAPI::SInstanceData(); 364 365 SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); 366 367 // 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! 368 if( Data.uFragmentShaderLogo != UNDEFINED_HANDLE && Data.uVertexShaderLogo != UNDEFINED_HANDLE && Data.uProgramLogo != UNDEFINED_HANDLE && 369 Data.uFragmentShaderFont != UNDEFINED_HANDLE && Data.uVertexShaderFont != UNDEFINED_HANDLE && Data.uProgramFont != UNDEFINED_HANDLE 370 ) 371 { 372 ++SPVRTPrint3DAPI::s_iRefCount; 373 return true; 374 } 375 376 // Compiles the shaders. For a more detailed explanation, see IntroducingPVRTools 377 CPVRTString error; 378 GLint Linked; 379 bool bRes = true; 380 381 bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DFragShaderLogo_fsh, GL_FRAGMENT_SHADER, &Data.uFragmentShaderLogo, &error) == PVR_SUCCESS); 382 bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DVertShaderLogo_vsh, GL_VERTEX_SHADER, &Data.uVertexShaderLogo, &error) == PVR_SUCCESS); 383 384 _ASSERT(bRes); 385 386 // Create the 'text' program 387 Data.uProgramLogo = glCreateProgram(); 388 glAttachShader(Data.uProgramLogo, Data.uVertexShaderLogo); 389 glAttachShader(Data.uProgramLogo, Data.uFragmentShaderLogo); 390 glBindAttribLocation(Data.uProgramLogo, VERTEX_ARRAY, "myVertex"); 391 glBindAttribLocation(Data.uProgramLogo, UV_ARRAY, "myUV"); 392 393 glLinkProgram(Data.uProgramLogo); 394 glGetProgramiv(Data.uProgramLogo, GL_LINK_STATUS, &Linked); 395 396 if (!Linked) 397 bRes = false; 398 399 bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DFragShader_fsh, GL_FRAGMENT_SHADER, &Data.uFragmentShaderFont, &error) == PVR_SUCCESS); 400 bRes &= (PVRTShaderLoadSourceFromMemory(_Print3DVertShader_vsh, GL_VERTEX_SHADER, &Data.uVertexShaderFont, &error) == PVR_SUCCESS); 401 402 _ASSERT(bRes); 403 404 // Create the 'text' program 405 Data.uProgramFont = glCreateProgram(); 406 glAttachShader(Data.uProgramFont, Data.uVertexShaderFont); 407 glAttachShader(Data.uProgramFont, Data.uFragmentShaderFont); 408 glBindAttribLocation(Data.uProgramFont, VERTEX_ARRAY, "myVertex"); 409 glBindAttribLocation(Data.uProgramFont, UV_ARRAY, "myUV"); 410 glBindAttribLocation(Data.uProgramFont, COLOR_ARRAY, "myColour"); 411 412 glLinkProgram(Data.uProgramFont); 413 glGetProgramiv(Data.uProgramFont, GL_LINK_STATUS, &Linked); 414 415 if (!Linked) 416 bRes = false; 417 418 Data.mvpLocationLogo = glGetUniformLocation(Data.uProgramFont, "myMVPMatrix"); 419 Data.mvpLocationFont = glGetUniformLocation(Data.uProgramLogo, "myMVPMatrix"); 420 421 _ASSERT(bRes && Data.mvpLocationLogo != -1 && Data.mvpLocationFont != -1); 422 423 return bRes; 424} 425 426/*!*************************************************************************** 427 @Function APIRelease 428 @Description Deinitialisation. 429*****************************************************************************/ 430void CPVRTPrint3D::APIRelease() 431{ 432 delete m_pAPI; 433 m_pAPI = 0; 434} 435 436/*!*************************************************************************** 437 @Function APIUpLoadIcons 438 @Description Initialisation and texture upload. Should be called only once 439 for a given context. 440*****************************************************************************/ 441bool CPVRTPrint3D::APIUpLoadIcons(const PVRTuint8 * const pIMG, const PVRTuint8 * const pPowerVR) 442{ 443 SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); 444 445 // Load Icon texture 446 if(Data.uTextureIMGLogo == UNDEFINED_HANDLE) // Static, so might already be initialized. 447 if(PVRTTextureLoadFromPointer((unsigned char*)pIMG, &Data.uTextureIMGLogo) != PVR_SUCCESS) 448 return false; 449 450 if(Data.uTexturePowerVRLogo == UNDEFINED_HANDLE) // Static, so might already be initialized. 451 if(PVRTTextureLoadFromPointer((unsigned char*)pPowerVR, &Data.uTexturePowerVRLogo) != PVR_SUCCESS) 452 return false; 453 454 glBindTexture(GL_TEXTURE_2D, 0); 455 return true; 456} 457 458/*!*************************************************************************** 459@Function APIUpLoadTexture 460@Input pSource 461@Output header 462@Return bool true if successful. 463@Description Loads and uploads the font texture from a PVR file. 464*****************************************************************************/ 465bool CPVRTPrint3D::APIUpLoadTexture(const PVRTuint8* pSource, const PVRTextureHeaderV3* header, CPVRTMap<PVRTuint32, CPVRTMap<PVRTuint32, MetaDataBlock> >& MetaDataMap) 466{ 467 if(PVRTTextureLoadFromPointer(pSource, &m_pAPI->m_uTextureFont, header, true, 0U, NULL, &MetaDataMap) != PVR_SUCCESS) 468 return false; 469 470 glBindTexture(GL_TEXTURE_2D, 0); 471 return true; 472} 473 474/*!*************************************************************************** 475 @Function APIRenderStates 476 @Description Stores, writes and restores Render States 477*****************************************************************************/ 478void CPVRTPrint3D::APIRenderStates(int nAction) 479{ 480 // Saving or restoring states ? 481 switch (nAction) 482 { 483 case INIT_PRINT3D_STATE: 484 { 485 // Get previous render states 486 m_pAPI->isCullFaceEnabled = glIsEnabled(GL_CULL_FACE); 487 m_pAPI->isBlendEnabled = glIsEnabled(GL_BLEND); 488 m_pAPI->isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); 489 490 glGetIntegerv(GL_FRONT_FACE, &m_pAPI->eFrontFace); 491 glGetIntegerv(GL_CULL_FACE_MODE, &m_pAPI->eCullFaceMode); 492 glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&m_pAPI->nArrayBufferBinding); 493 glGetIntegerv(GL_CURRENT_PROGRAM, &m_pAPI->nCurrentProgram); 494 glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_pAPI->nTextureBinding2D); 495 496 /****************************** 497 ** SET PRINT3D RENDER STATES ** 498 ******************************/ 499 500 // Culling 501 glFrontFace(GL_CCW); 502 glCullFace(GL_BACK); 503 glEnable(GL_CULL_FACE); 504 505 // Set blending mode 506 glEnable(GL_BLEND); 507 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 508 509 // Set Z compare properties 510 glDisable(GL_DEPTH_TEST); 511 512 // Set the default GL_ARRAY_BUFFER 513 glBindBuffer(GL_ARRAY_BUFFER, 0); 514 515 // texture 516 glActiveTexture(GL_TEXTURE0); 517 break; 518 } 519 case DEINIT_PRINT3D_STATE: 520 // Restore some values 521 if (!m_pAPI->isCullFaceEnabled) glDisable(GL_CULL_FACE); 522 if (!m_pAPI->isBlendEnabled) glDisable(GL_BLEND); 523 if (m_pAPI->isDepthTestEnabled) glEnable(GL_DEPTH_TEST); 524 glCullFace((GLenum)m_pAPI->eCullFaceMode); 525 glFrontFace((GLenum)m_pAPI->eFrontFace); 526 glBindBuffer(GL_ARRAY_BUFFER,m_pAPI->nArrayBufferBinding); 527 glBindTexture(GL_TEXTURE_2D, m_pAPI->nTextureBinding2D); 528 glUseProgram(m_pAPI->nCurrentProgram); // Unset print3ds program 529 break; 530 } 531} 532 533/**************************************************************************** 534** Local code 535****************************************************************************/ 536 537/*!*************************************************************************** 538 @Function APIDrawLogo 539 @Description 540*****************************************************************************/ 541void CPVRTPrint3D::APIDrawLogo(const EPVRTPrint3DLogo uLogoToDisplay, const int ePos) 542{ 543 GLuint tex = 0; 544 float fScale = 1.0f; 545 if(m_ui32ScreenDim[1] >= 720) 546 fScale = 2.0f; 547 548 SPVRTPrint3DAPI::SInstanceData& Data = (m_pAPI->m_pInstanceData ? *m_pAPI->m_pInstanceData : SPVRTPrint3DAPI::s_InstanceData); 549 550 switch(uLogoToDisplay) 551 { 552 case ePVRTPrint3DLogoIMG: 553 tex = Data.uTextureIMGLogo; 554 break; 555 case ePVRTPrint3DLogoPowerVR: 556 tex = Data.uTexturePowerVRLogo; 557 break; 558 default: 559 return; // Logo not recognised 560 } 561 562 const float fLogoXSizeHalf = (128.0f / m_ui32ScreenDim[0]); 563 const float fLogoYSizeHalf = (64.0f / m_ui32ScreenDim[1]); 564 565 const float fLogoXShift = 0.035f / fScale; 566 const float fLogoYShift = 0.035f / fScale; 567 568 const float fLogoSizeXHalfShifted = fLogoXSizeHalf + fLogoXShift; 569 const float fLogoSizeYHalfShifted = fLogoYSizeHalf + fLogoYShift; 570 571 static float Vertices[] = 572 { 573 -fLogoXSizeHalf, fLogoYSizeHalf , 0.5f, 574 -fLogoXSizeHalf, -fLogoYSizeHalf, 0.5f, 575 fLogoXSizeHalf , fLogoYSizeHalf , 0.5f, 576 fLogoXSizeHalf , -fLogoYSizeHalf, 0.5f 577 }; 578 579 static float UVs[] = { 580 0.0f, 0.0f, 581 0.0f, 1.0f, 582 1.0f, 0.0f, 583 1.0f, 1.0f 584 }; 585 586 float *pVertices = ( (float*)&Vertices ); 587 float *pUV = ( (float*)&UVs ); 588 589 // Matrices 590 PVRTMATRIX matModelView; 591 PVRTMATRIX matTransform; 592 PVRTMatrixIdentity(matModelView); 593 594 PVRTMatrixScaling(matTransform, f2vt(fScale), f2vt(fScale), f2vt(1.0f)); 595 PVRTMatrixMultiply(matModelView, matModelView, matTransform); 596 597 int nXPos = (ePos & eLeft) ? -1 : 1; 598 int nYPos = (ePos & eTop) ? 1 : -1; 599 PVRTMatrixTranslation(matTransform, nXPos - (fLogoSizeXHalfShifted * fScale * nXPos), nYPos - (fLogoSizeYHalfShifted * fScale * nYPos), 0.0f); 600 PVRTMatrixMultiply(matModelView, matModelView, matTransform); 601 602 if(m_bRotate) 603 { 604 PVRTMatrixRotationZ(matTransform, -90.0f*PVRT_PI/180.0f); 605 PVRTMatrixMultiply(matModelView, matModelView, matTransform); 606 } 607 608 _ASSERT(Data.uProgramLogo != UNDEFINED_HANDLE); 609 glUseProgram(Data.uProgramLogo); 610 611 // Bind the model-view-projection to the shader 612 glUniformMatrix4fv(Data.mvpLocationLogo, 1, GL_FALSE, matModelView.f); 613 614 // Render states 615 glActiveTexture(GL_TEXTURE0); 616 617 _ASSERT(tex != UNDEFINED_HANDLE); 618 glBindTexture(GL_TEXTURE_2D, tex); 619 620 // Vertices 621 glEnableVertexAttribArray(VERTEX_ARRAY); 622 glEnableVertexAttribArray(UV_ARRAY); 623 624 glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, (const void*)pVertices); 625 glVertexAttribPointer(UV_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*)pUV); 626 627 glDrawArrays(GL_TRIANGLE_STRIP,0,4); 628 629 glDisableVertexAttribArray(VERTEX_ARRAY); 630 glDisableVertexAttribArray(UV_ARRAY); 631} 632 633/***************************************************************************** 634 End of file (PVRTPrint3DAPI.cpp) 635*****************************************************************************/ 636 637