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
51 const GLenum c_eMagTable[] =
52 {
53 GL_NEAREST,
54 GL_LINEAR,
55 };
56
57 const 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 ****************************************************************************/
70 enum eFunction
71 {
72 eFunc_DelProg,
73 eFunc_DelShader,
74 eFunc_DelTex
75 };
76
77 /****************************************************************************
78 ** Auxiliary functions
79 ****************************************************************************/
DeleteResource(eFunction eType,GLuint & handle)80 static 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 ****************************************************************************/
98 struct 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
SInstanceDataSPVRTPrint3DAPI::SInstanceData118 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
ReleaseSPVRTPrint3DAPI::SInstanceData131 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
SPVRTPrint3DAPISPVRTPrint3DAPI162 SPVRTPrint3DAPI() : m_pInstanceData(NULL) {}
~SPVRTPrint3DAPISPVRTPrint3DAPI163 ~SPVRTPrint3DAPI()
164 {
165 if(m_pInstanceData)
166 {
167 delete m_pInstanceData;
168 m_pInstanceData = NULL;
169 }
170 }
171 };
172
173 int SPVRTPrint3DAPI::s_iRefCount = 0;
174 SPVRTPrint3DAPI::SInstanceData SPVRTPrint3DAPI::s_InstanceData;
175
176 /****************************************************************************
177 ** Class: CPVRTPrint3D
178 ****************************************************************************/
179
180 /*!***************************************************************************
181 @Function ReleaseTextures
182 @Description Deallocate the memory allocated in SetTextures(...)
183 *****************************************************************************/
ReleaseTextures()184 void 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 *****************************************************************************/
Flush()232 int 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 *****************************************************************************/
APIInit(const SPVRTContext * const pContext,bool bMakeCopy)354 bool 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 *****************************************************************************/
APIRelease()430 void 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 *****************************************************************************/
APIUpLoadIcons(const PVRTuint8 * const pIMG,const PVRTuint8 * const pPowerVR)441 bool 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 *****************************************************************************/
APIUpLoadTexture(const PVRTuint8 * pSource,const PVRTextureHeaderV3 * header,CPVRTMap<PVRTuint32,CPVRTMap<PVRTuint32,MetaDataBlock>> & MetaDataMap)465 bool 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 *****************************************************************************/
APIRenderStates(int nAction)478 void 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 *****************************************************************************/
APIDrawLogo(const EPVRTPrint3DLogo uLogoToDisplay,const int ePos)541 void 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