OGLES2IntroducingPVRTools.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /******************************************************************************
  2. @File OGLES2IntroducingPVRTools.cpp
  3. @Title Introducing the PVRTools
  4. @Version
  5. @Copyright Copyright (C) Imagination Technologies Limited.
  6. @Platform Independent
  7. @Description Shows how to use the tools to load textures, shaders and display
  8. text
  9. ******************************************************************************/
  10. #include "PVRShell.h"
  11. #include "OGLES2Tools.h"
  12. /******************************************************************************
  13. shader attributes and uniforms
  14. ******************************************************************************/
  15. // Vertex attributes
  16. // We define an enum for the attribute position and an array of strings that
  17. // correspond to the attribute names in the shader. These can be used by PVRTools
  18. enum EVertexAttrib {
  19. VERTEX_ARRAY, TEXCOORD_ARRAY, eNumAttribs };
  20. const char* g_aszAttribNames[] = {
  21. "inVertex", "inTexCoord" };
  22. // Shader uniforms
  23. enum EUniform {
  24. eMVPMatrix, eNumUniforms };
  25. const char* g_aszUniformNames[] = {
  26. "MVPMatrix" };
  27. /******************************************************************************
  28. Content file names
  29. ******************************************************************************/
  30. // Source and binary shaders
  31. const char c_szFragShaderSrcFile[] = "FragShader.fsh";
  32. const char c_szFragShaderBinFile[] = "FragShader.fsc";
  33. const char c_szVertShaderSrcFile[] = "VertShader.vsh";
  34. const char c_szVertShaderBinFile[] = "VertShader.vsc";
  35. // PVR texture files
  36. const char c_szTextureFile[] = "Image.pvr";
  37. /*!****************************************************************************
  38. Class implementing the PVRShell functions.
  39. ******************************************************************************/
  40. class OGLESIntroducingPVRTools : public PVRShell
  41. {
  42. // Print3D class used to display text
  43. CPVRTPrint3D m_Print3D;
  44. // Texture handle
  45. GLuint m_uiTexture;
  46. // VBO handle
  47. GLuint m_ui32Vbo;
  48. //
  49. unsigned int m_ui32VertexStride;
  50. // The vertex and fragment shader OpenGL handles
  51. GLuint m_uiVertexShader, m_uiFragShader;
  52. // Group shader programs and their uniform locations together
  53. struct
  54. {
  55. GLuint uiId;
  56. GLuint auiLoc[eNumUniforms];
  57. }
  58. m_ShaderProgram;
  59. public:
  60. virtual bool InitApplication();
  61. virtual bool InitView();
  62. virtual bool ReleaseView();
  63. virtual bool QuitApplication();
  64. virtual bool RenderScene();
  65. };
  66. /*!****************************************************************************
  67. @Function InitApplication
  68. @Return bool true if no error occured
  69. @Description Code in InitApplication() will be called by PVRShell once per
  70. run, before the rendering context is created.
  71. Used to initialize variables that are not dependant on it
  72. (e.g. external modules, loading meshes, etc.)
  73. If the rendering context is lost, InitApplication() will
  74. not be called again.
  75. ******************************************************************************/
  76. bool OGLESIntroducingPVRTools::InitApplication()
  77. {
  78. /*
  79. CPVRTResourceFile is a resource file helper class. Resource files can
  80. be placed on disk next to the executable or in a platform dependent
  81. read path. We need to tell the class where that read path is.
  82. Additionally, it is possible to wrap files into cpp modules and
  83. link them directly into the executable. In this case no path will be
  84. used. Files on disk will override "memory files".
  85. */
  86. // Get and set the read path for content files
  87. CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));
  88. return true;
  89. }
  90. /*!****************************************************************************
  91. @Function QuitApplication
  92. @Return bool true if no error occured
  93. @Description Code in QuitApplication() will be called by PVRShell once per
  94. run, just before exiting the program.
  95. If the rendering context is lost, QuitApplication() will
  96. not be called.
  97. ******************************************************************************/
  98. bool OGLESIntroducingPVRTools::QuitApplication()
  99. {
  100. return true;
  101. }
  102. /*!****************************************************************************
  103. @Function InitView
  104. @Return bool true if no error occured
  105. @Description Code in InitView() will be called by PVRShell upon
  106. initialization or after a change in the rendering context.
  107. Used to initialize variables that are dependant on the rendering
  108. context (e.g. textures, vertex buffers, etc.)
  109. ******************************************************************************/
  110. bool OGLESIntroducingPVRTools::InitView()
  111. {
  112. /*
  113. Initialize the textures used by Print3D.
  114. To properly display text, Print3D needs to know the viewport dimensions
  115. and whether the text should be rotated. We get the dimensions using the
  116. shell function PVRShellGet(prefWidth/prefHeight). We can also get the
  117. rotate parameter by checking prefIsRotated and prefFullScreen.
  118. */
  119. bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
  120. if(m_Print3D.SetTextures(0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
  121. {
  122. PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
  123. return false;
  124. }
  125. // Sets the clear color
  126. glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
  127. /*
  128. Loads the texture using the tool function PVRTTextureLoadFromPVR.
  129. The first parameter is the name of the file and the
  130. second parameter returns the resulting texture handle.
  131. The third parameter is a CPVRTString for error message output.
  132. This function can also be used to conveniently set the filter modes. If
  133. those parameters are not given, OpenGL ES defaults are used.
  134. Setting a mipmap filter on a mipmap-less texture will result in an error.
  135. */
  136. if(PVRTTextureLoadFromPVR(c_szTextureFile, &m_uiTexture) != PVR_SUCCESS)
  137. {
  138. PVRShellSet(prefExitMessage, "ERROR: Cannot load the texture\n");
  139. return false;
  140. }
  141. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  142. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  143. /*
  144. Compiles the shaders.
  145. First we use CPVRTResourceFile to load a file into memory. After construction with a
  146. file name, we just have to check whether the file is open or an error occured.
  147. We load both source and binary shaders, then try the binary shader first.
  148. The data of a CPVRTResourceFile will always be terminated with a 0 byte so it can
  149. safely be used as a C string.
  150. */
  151. CPVRTResourceFile VertexShaderSrcFile(c_szVertShaderSrcFile);
  152. CPVRTResourceFile VertexShaderBinFile(c_szVertShaderBinFile);
  153. CPVRTString ErrorStr;
  154. /*
  155. PVRTShaderLoadBinaryFromMemory takes a pointer to the binary shader and the shader size as
  156. its first arguments. Then follows the shader type and binary format.
  157. On success, the handle to the new shader object is returned in the fifth parameter, while
  158. an error string is returned on failure.
  159. */
  160. if (!VertexShaderBinFile.IsOpen() ||
  161. (PVRTShaderLoadBinaryFromMemory(VertexShaderBinFile.DataPtr(), VertexShaderBinFile.Size(),
  162. GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_uiVertexShader, &ErrorStr) != PVR_SUCCESS))
  163. {
  164. /*
  165. Fallback to source shader
  166. PVRTShaderLoadSourceFromMemory() takes the shader source code as its 1st argument.
  167. The shader type as 2nd argument (for now either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
  168. It returns the shader object in its 3rd argument.
  169. If an error occurs during compilation, the resulting log is returned in the 4th parameter.
  170. We could also use PVRTLoadAndCompileShaderFromFile() to load and
  171. compile a shader from an external text file
  172. */
  173. if (!VertexShaderSrcFile.IsOpen() ||
  174. (PVRTShaderLoadSourceFromMemory(VertexShaderSrcFile.StringPtr(), GL_VERTEX_SHADER, &m_uiVertexShader, &ErrorStr) != PVR_SUCCESS))
  175. {
  176. PVRShellSet(prefExitMessage, ErrorStr.c_str());
  177. return false;
  178. }
  179. }
  180. /*
  181. PVRTShaderLoadFromFile can be used to try compiling/loading shaders from files. In this variant,
  182. two files are tried before failing (usually binary and source files). The type of shader is determined
  183. from the file extension (.fsh and .vsh for source, .fsc and .vsc for SGX binary shaders)
  184. */
  185. if (PVRTShaderLoadFromFile(c_szFragShaderBinFile, c_szFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiFragShader, &ErrorStr) != PVR_SUCCESS)
  186. {
  187. PVRShellSet(prefExitMessage, ErrorStr.c_str());
  188. return false;
  189. }
  190. /*
  191. PVRTCreateProgram creates a new program object, attaches the shaders, binds attributes (given as an array
  192. of strings and the size thereof), and makes the program current - or it returns an error string on failure.
  193. */
  194. if (PVRTCreateProgram(&m_ShaderProgram.uiId, m_uiVertexShader, m_uiFragShader, g_aszAttribNames, eNumAttribs, &ErrorStr) != PVR_SUCCESS)
  195. {
  196. PVRShellSet(prefExitMessage, ErrorStr.c_str());
  197. return false;
  198. }
  199. // Store the location of uniforms for later use
  200. for (int i = 0; i < eNumUniforms; ++i)
  201. {
  202. m_ShaderProgram.auiLoc[i] = glGetUniformLocation(m_ShaderProgram.uiId, g_aszUniformNames[i]);
  203. }
  204. // Create VBO for the triangle from our data
  205. // Interleaved vertex data
  206. GLfloat afVertices[] = {-0.4f,-0.4f,0.0f, // Pos
  207. 0.0f,0.0f , // UVs
  208. 0.4f,-0.4f,0.0f,
  209. 1.0f,0.0f ,
  210. 0.0f,0.4f ,0.0f,
  211. 0.5f,1.0f};
  212. glGenBuffers(1, &m_ui32Vbo);
  213. m_ui32VertexStride = 5 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs
  214. // Bind the VBO
  215. glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);
  216. // Set the buffer's data
  217. glBufferData(GL_ARRAY_BUFFER, 3 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
  218. // Unbind the VBO
  219. glBindBuffer(GL_ARRAY_BUFFER, 0);
  220. return true;
  221. }
  222. /*!****************************************************************************
  223. @Function ReleaseView
  224. @Return bool true if no error occured
  225. @Description Code in ReleaseView() will be called by PVRShell when the
  226. application quits or before a change in the rendering context.
  227. ******************************************************************************/
  228. bool OGLESIntroducingPVRTools::ReleaseView()
  229. {
  230. // Frees the texture
  231. glDeleteTextures(1,&m_uiTexture);
  232. // Release Vertex buffer object.
  233. glDeleteBuffers(1, &m_ui32Vbo);
  234. // Release Print3D Textures
  235. m_Print3D.ReleaseTextures();
  236. // Frees the OpenGL handles for the program and the 2 shaders
  237. glDeleteProgram(m_ShaderProgram.uiId);
  238. glDeleteShader(m_uiVertexShader);
  239. glDeleteShader(m_uiFragShader);
  240. return true;
  241. }
  242. /*!****************************************************************************
  243. @Function RenderScene
  244. @Return bool true if no error occured
  245. @Description Main rendering loop function of the program. The shell will
  246. call this function every frame.
  247. eglSwapBuffers() will be performed by PVRShell automatically.
  248. PVRShell will also manage important OS events.
  249. Will also manage relevent OS events. The user has access to
  250. these events through an abstraction layer provided by PVRShell.
  251. ******************************************************************************/
  252. bool OGLESIntroducingPVRTools::RenderScene()
  253. {
  254. // Clears the color and depth buffer
  255. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  256. // Binds the loaded texture
  257. glBindTexture(GL_TEXTURE_2D, m_uiTexture);
  258. // Use the loaded shader program
  259. glUseProgram(m_ShaderProgram.uiId);
  260. /*
  261. Creates the Model View Projection (MVP) matrix using the PVRTMat4 class from the tools.
  262. The tools contain a complete set of functions to operate on 4x4 matrices.
  263. */
  264. PVRTMat4 mMVP = PVRTMat4::Identity();
  265. if(PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen)) // If the screen is rotated
  266. mMVP = PVRTMat4::RotationZ(-1.57f);
  267. /*
  268. Pass this matrix to the shader.
  269. The .m field of a PVRTMat4 contains the array of float used to
  270. communicate with OpenGL ES.
  271. */
  272. glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());
  273. /*
  274. Draw a triangle.
  275. Please refer to the training course IntroducingPVRShell for a detailed explanation.
  276. */
  277. // Bind the VBO
  278. glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);
  279. // Pass the vertex data
  280. glEnableVertexAttribArray(VERTEX_ARRAY);
  281. glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
  282. // Pass the texture coordinates data
  283. glEnableVertexAttribArray(TEXCOORD_ARRAY);
  284. glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (sizeof(GLfloat) * 3) /* Uvs start after the position */);
  285. // Draws a non-indexed triangle array
  286. glDrawArrays(GL_TRIANGLES, 0, 3);
  287. /*
  288. Display some text.
  289. Print3D() function allows to draw text anywhere on the screen using any color.
  290. Param 1: Position of the text along X (from 0 to 100 scale independent)
  291. Param 2: Position of the text along Y (from 0 to 100 scale independent)
  292. Param 3: Scale of the text
  293. Param 4: Colour of the text (0xAABBGGRR format)
  294. Param 5: Formated string (uses the same sintax as printf)
  295. */
  296. m_Print3D.Print3D(8.0f, 30.0f, 1.5f, 0xFFAA4040, "example");
  297. /*
  298. DisplayDefaultTitle() writes a title and description text on the top left of the screen.
  299. It can also display the PVR logo (ePVRTPrint3DLogoPVR), the IMG logo (ePVRTPrint3DLogoIMG) or both (ePVRTPrint3DLogoPVR | ePVRTPrint3DLogoIMG).
  300. Set this last parameter to NULL not to display the logos.
  301. */
  302. m_Print3D.DisplayDefaultTitle("IntroducingPVRTools", "Description", ePVRTPrint3DLogoIMG);
  303. // Tells Print3D to do all the pending text rendering now
  304. m_Print3D.Flush();
  305. return true;
  306. }
  307. /*!****************************************************************************
  308. @Function NewDemo
  309. @Return PVRShell* The demo supplied by the user
  310. @Description This function must be implemented by the user of the shell.
  311. The user should return its PVRShell object defining the
  312. behaviour of the application.
  313. ******************************************************************************/
  314. PVRShell* NewDemo()
  315. {
  316. return new OGLESIntroducingPVRTools();
  317. }
  318. /******************************************************************************
  319. End of file (OGLESIntroducingPVRTools.cpp)
  320. ******************************************************************************/