PVRTBackground.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /******************************************************************************
  2. @File PVRTBackground.cpp
  3. @Title PVRTBackground
  4. @Version
  5. @Copyright Copyright (C) Imagination Technologies Limited.
  6. @Platform ANSI compatible
  7. @Description Function to draw a background texture.
  8. ******************************************************************************/
  9. #include "PVRTShader.h"
  10. #include "PVRTBackground.h"
  11. // The header that contains the shaders
  12. #include "PVRTBackgroundShaders.h"
  13. #include "PVRTgles2Ext.h"
  14. // Index to bind the attributes to vertex shaders
  15. const int VERTEX_ARRAY = 0;
  16. const int TEXCOORD_ARRAY = 1;
  17. /****************************************************************************
  18. ** Structures
  19. ****************************************************************************/
  20. // The struct to include various API variables
  21. struct SPVRTBackgroundAPI
  22. {
  23. GLuint m_ui32VertexShader;
  24. GLuint m_ui32FragShader;
  25. GLuint m_ui32ProgramObject;
  26. GLuint m_ui32VertexBufferObject;
  27. };
  28. /****************************************************************************
  29. ** Class: CPVRTBackground
  30. ****************************************************************************/
  31. /*****************************************************************************
  32. @Function Background
  33. @Description Init some values.
  34. *****************************************************************************/
  35. CPVRTBackground::CPVRTBackground(void)
  36. {
  37. m_bInit = false;
  38. m_pAPI = 0;
  39. }
  40. /*****************************************************************************
  41. @Function ~Background
  42. @Description Calls Destroy()
  43. *****************************************************************************/
  44. CPVRTBackground::~CPVRTBackground(void)
  45. {
  46. Destroy();
  47. }
  48. /*!***************************************************************************
  49. @Function Destroy
  50. @Description Destroys the background. It's called by the destructor.
  51. *****************************************************************************/
  52. void CPVRTBackground::Destroy()
  53. {
  54. if(m_bInit)
  55. {
  56. // Delete shaders
  57. glDeleteProgram(m_pAPI->m_ui32ProgramObject);
  58. glDeleteShader(m_pAPI->m_ui32VertexShader);
  59. glDeleteShader(m_pAPI->m_ui32FragShader);
  60. // Delete buffer objects
  61. glDeleteBuffers(1, &m_pAPI->m_ui32VertexBufferObject);
  62. m_bInit = false;
  63. }
  64. delete m_pAPI;
  65. m_pAPI = 0;
  66. }
  67. /*!***************************************************************************
  68. @Function Init
  69. @Input pContext A pointer to a PVRTContext
  70. @Input bRotate true to rotate texture 90 degrees.
  71. @Input pszError An option string for returning errors
  72. @Return PVR_SUCCESS on success
  73. @Description Initialises the background
  74. *****************************************************************************/
  75. EPVRTError CPVRTBackground::Init(const SPVRTContext * const pContext, bool bRotate, CPVRTString *pszError)
  76. {
  77. PVRT_UNREFERENCED_PARAMETER(pContext);
  78. Destroy();
  79. m_pAPI = new SPVRTBackgroundAPI;
  80. if(!m_pAPI)
  81. {
  82. if(pszError)
  83. *pszError = "Error: Insufficient memory to allocate SCPVRTBackgroundAPI.";
  84. return PVR_FAIL;
  85. }
  86. m_pAPI->m_ui32VertexShader = 0;
  87. m_pAPI->m_ui32FragShader = 0;
  88. m_pAPI->m_ui32ProgramObject = 0;
  89. m_pAPI->m_ui32VertexBufferObject = 0;
  90. bool bResult;
  91. CPVRTString sTmpErrStr;
  92. // The shader loading code doesn't expect a null pointer for the error string
  93. if(!pszError)
  94. pszError = &sTmpErrStr;
  95. /* Compiles the shaders. For a more detailed explanation, see IntroducingPVRTools */
  96. // Try binary shaders first
  97. bResult = (PVRTShaderLoadBinaryFromMemory(_BackgroundFragShader_fsc, _BackgroundFragShader_fsc_size,
  98. GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_pAPI->m_ui32FragShader, pszError) == PVR_SUCCESS)
  99. && (PVRTShaderLoadBinaryFromMemory(_BackgroundVertShader_vsc, _BackgroundVertShader_vsc_size,
  100. GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_pAPI->m_ui32VertexShader, pszError) == PVR_SUCCESS);
  101. if(!bResult)
  102. {
  103. // if binary shaders don't work, try source shaders
  104. bResult = (PVRTShaderLoadSourceFromMemory(_BackgroundFragShader_fsh, GL_FRAGMENT_SHADER, &m_pAPI->m_ui32FragShader, pszError) == PVR_SUCCESS) &&
  105. (PVRTShaderLoadSourceFromMemory(_BackgroundVertShader_vsh, GL_VERTEX_SHADER, &m_pAPI->m_ui32VertexShader, pszError) == PVR_SUCCESS);
  106. }
  107. _ASSERT(bResult);
  108. if(!bResult)
  109. return PVR_FAIL;
  110. // Reset the error string
  111. if(pszError)
  112. *pszError = "";
  113. // Create the shader program
  114. m_pAPI->m_ui32ProgramObject = glCreateProgram();
  115. // Attach the fragment and vertex shaders to it
  116. glAttachShader(m_pAPI->m_ui32ProgramObject, m_pAPI->m_ui32FragShader);
  117. glAttachShader(m_pAPI->m_ui32ProgramObject, m_pAPI->m_ui32VertexShader);
  118. // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY
  119. glBindAttribLocation(m_pAPI->m_ui32ProgramObject, VERTEX_ARRAY, "myVertex");
  120. // Bind the custom vertex attribute "myUV" to location TEXCOORD_ARRAY
  121. glBindAttribLocation(m_pAPI->m_ui32ProgramObject, TEXCOORD_ARRAY, "myUV");
  122. // Link the program
  123. glLinkProgram(m_pAPI->m_ui32ProgramObject);
  124. GLint Linked;
  125. glGetProgramiv(m_pAPI->m_ui32ProgramObject, GL_LINK_STATUS, &Linked);
  126. if (!Linked)
  127. {
  128. int i32InfoLogLength, i32CharsWritten;
  129. glGetProgramiv(m_pAPI->m_ui32ProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
  130. char* pszInfoLog = new char[i32InfoLogLength];
  131. glGetProgramInfoLog(m_pAPI->m_ui32ProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  132. *pszError = CPVRTString("Failed to link: ") + pszInfoLog + "\n";
  133. delete [] pszInfoLog;
  134. bResult = false;
  135. }
  136. _ASSERT(bResult);
  137. if(!bResult)
  138. return PVR_FAIL;
  139. // Use the loaded shader program
  140. glUseProgram(m_pAPI->m_ui32ProgramObject);
  141. // Set the sampler2D variable to the first texture unit
  142. glUniform1i(glGetUniformLocation(m_pAPI->m_ui32ProgramObject, "sampler2d"), 0);
  143. // Create the vertex buffer object
  144. GLfloat *pVertexData = 0;
  145. // The vertex data for non-rotated
  146. GLfloat afVertexData[16] = { -1, -1, 1, -1, -1, 1, 1, 1,
  147. 0, 0, 1, 0, 0, 1, 1, 1};
  148. // The vertex data for rotated
  149. GLfloat afVertexDataRotated[16] = {-1, 1, -1, -1, 1, 1, 1, -1,
  150. 1, 1, 0, 1, 1, 0, 0, 0};
  151. if(!bRotate)
  152. pVertexData = &afVertexData[0];
  153. else
  154. pVertexData = &afVertexDataRotated[0];
  155. glGenBuffers(1, &m_pAPI->m_ui32VertexBufferObject);
  156. glBindBuffer(GL_ARRAY_BUFFER, m_pAPI->m_ui32VertexBufferObject);
  157. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, pVertexData, GL_STATIC_DRAW);
  158. glBindBuffer(GL_ARRAY_BUFFER, 0);
  159. m_bInit = true;
  160. return PVR_SUCCESS;
  161. }
  162. /*!***************************************************************************
  163. @Function Draw
  164. @Input ui32Texture Texture to use
  165. @Return PVR_SUCCESS on success
  166. @Description Draws a texture on a quad covering the whole screen.
  167. *****************************************************************************/
  168. EPVRTError CPVRTBackground::Draw(const GLuint ui32Texture)
  169. {
  170. if(!m_bInit)
  171. return PVR_FAIL;
  172. glActiveTexture(GL_TEXTURE0);
  173. glBindTexture(GL_TEXTURE_2D, ui32Texture);
  174. glDisable(GL_DEPTH_TEST);
  175. glDisable(GL_CULL_FACE);
  176. // Use the loaded shader program
  177. glUseProgram(m_pAPI->m_ui32ProgramObject);
  178. // Set vertex data
  179. glBindBuffer(GL_ARRAY_BUFFER, m_pAPI->m_ui32VertexBufferObject);
  180. glEnableVertexAttribArray(VERTEX_ARRAY);
  181. glVertexAttribPointer(VERTEX_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*) 0);
  182. // Set texture coordinates
  183. glEnableVertexAttribArray(TEXCOORD_ARRAY);
  184. glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*) (8 * sizeof(float)));
  185. // Render geometry
  186. glDrawArrays(GL_TRIANGLE_STRIP,0,4);
  187. glDisableVertexAttribArray(VERTEX_ARRAY);
  188. glDisableVertexAttribArray(TEXCOORD_ARRAY);
  189. glBindBuffer(GL_ARRAY_BUFFER, 0);
  190. glUseProgram(0);
  191. return PVR_SUCCESS;
  192. }
  193. /*****************************************************************************
  194. End of file (CPVRTBackground.cpp)
  195. *****************************************************************************/