OGLES2BasicTnL.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /******************************************************************************
  2. @File OGLES2BasicTnL.cpp
  3. @Title Shows basic transformations and lighting
  4. @Version
  5. @Copyright Copyright (C) Imagination Technologies Limited.
  6. @Platform Independant
  7. @Description Shows basic transformations and lighting
  8. ******************************************************************************/
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #if defined(__APPLE__)
  13. #import <OpenGLES/ES2/gl.h>
  14. #import <OpenGLES/ES2/glext.h>
  15. #else
  16. #if defined(__BADA__)
  17. #include <FGraphicsOpengl2.h>
  18. using namespace Osp::Graphics::Opengl;
  19. #else
  20. #include <GLES2/gl2.h>
  21. #endif
  22. #endif
  23. #include "PVRShell.h"
  24. /******************************************************************************
  25. Defines
  26. ******************************************************************************/
  27. // Index to bind the attributes to vertex shaders
  28. #define VERTEX_ARRAY 0
  29. #define TEXCOORD_ARRAY 1
  30. #define NORMAL_ARRAY 2
  31. // Size of the texture we create
  32. #define TEX_SIZE 128
  33. /*!****************************************************************************
  34. Class implementing the PVRShell functions.
  35. ******************************************************************************/
  36. class OGLESBasicTnL : public PVRShell
  37. {
  38. // The vertex and fragment shader OpenGL handles
  39. GLuint m_uiVertexShader, m_uiFragShader;
  40. // The program object containing the 2 shader objects
  41. GLuint m_uiProgramObject;
  42. // Texture handle
  43. GLuint m_uiTexture;
  44. // VBO handle
  45. GLuint m_ui32Vbo;
  46. //
  47. unsigned int m_ui32VertexStride;
  48. // Angle to rotate the triangle
  49. float m_fAngle;
  50. public:
  51. virtual bool InitApplication();
  52. virtual bool InitView();
  53. virtual bool ReleaseView();
  54. virtual bool QuitApplication();
  55. virtual bool RenderScene();
  56. };
  57. /*!****************************************************************************
  58. @Function InitApplication
  59. @Return bool true if no error occured
  60. @Description Code in InitApplication() will be called by PVRShell once per
  61. run, before the rendering context is created.
  62. Used to initialize variables that are not dependant on it
  63. (e.g. external modules, loading meshes, etc.)
  64. If the rendering context is lost, InitApplication() will
  65. not be called again.
  66. ******************************************************************************/
  67. bool OGLESBasicTnL::InitApplication()
  68. {
  69. m_fAngle = 0;
  70. return true;
  71. }
  72. /*!****************************************************************************
  73. @Function QuitApplication
  74. @Return bool true if no error occured
  75. @Description Code in QuitApplication() will be called by PVRShell once per
  76. run, just before exiting the program.
  77. If the rendering context is lost, QuitApplication() will
  78. not be called.
  79. ******************************************************************************/
  80. bool OGLESBasicTnL::QuitApplication()
  81. {
  82. return true;
  83. }
  84. /*!****************************************************************************
  85. @Function InitView
  86. @Return bool true if no error occured
  87. @Description Code in InitView() will be called by PVRShell upon
  88. initialization or after a change in the rendering context.
  89. Used to initialize variables that are dependant on the rendering
  90. context (e.g. textures, vertex buffers, etc.)
  91. ******************************************************************************/
  92. bool OGLESBasicTnL::InitView()
  93. {
  94. // Fragment and vertex shaders code
  95. const char* pszFragShader = "\
  96. uniform sampler2D sampler2d;\
  97. varying mediump float varDot;\
  98. varying mediump vec2 varCoord;\
  99. void main (void)\
  100. {\
  101. gl_FragColor = texture2D(sampler2d,varCoord) * varDot;\
  102. }";
  103. const char* pszVertShader = "\
  104. attribute highp vec4 myVertex;\
  105. attribute mediump vec3 myNormal;\
  106. attribute mediump vec4 myUV;\
  107. uniform mediump mat4 myPMVMatrix;\
  108. uniform mediump mat3 myModelViewIT;\
  109. uniform mediump vec3 myLightDirection;\
  110. varying mediump float varDot;\
  111. varying mediump vec2 varCoord;\
  112. void main(void)\
  113. {\
  114. gl_Position = myPMVMatrix * myVertex;\
  115. varCoord = myUV.st;\
  116. mediump vec3 transNormal = myModelViewIT * myNormal;\
  117. varDot = max( dot(transNormal, myLightDirection), 0.0 );\
  118. }";
  119. // Create the fragment shader object
  120. m_uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);
  121. // Load the source code into it
  122. glShaderSource(m_uiFragShader, 1, (const char**)&pszFragShader, NULL);
  123. // Compile the source code
  124. glCompileShader(m_uiFragShader);
  125. // Check if compilation succeeded
  126. GLint bShaderCompiled;
  127. glGetShaderiv(m_uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled);
  128. if (!bShaderCompiled)
  129. {
  130. // An error happened, first retrieve the length of the log message
  131. int i32InfoLogLength, i32CharsWritten;
  132. glGetShaderiv(m_uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
  133. // Allocate enough space for the message and retrieve it
  134. char* pszInfoLog = new char[i32InfoLogLength];
  135. glGetShaderInfoLog(m_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  136. /*
  137. Displays the message in a dialog box when the application quits
  138. using the shell PVRShellSet function with first parameter prefExitMessage.
  139. */
  140. char* pszMsg = new char[i32InfoLogLength+256];
  141. strcpy(pszMsg, "Failed to compile fragment shader: ");
  142. strcat(pszMsg, pszInfoLog);
  143. PVRShellSet(prefExitMessage, pszMsg);
  144. delete [] pszMsg;
  145. delete [] pszInfoLog;
  146. return false;
  147. }
  148. // Loads the vertex shader in the same way
  149. m_uiVertexShader = glCreateShader(GL_VERTEX_SHADER);
  150. glShaderSource(m_uiVertexShader, 1, (const char**)&pszVertShader, NULL);
  151. glCompileShader(m_uiVertexShader);
  152. glGetShaderiv(m_uiVertexShader, GL_COMPILE_STATUS, &bShaderCompiled);
  153. if (!bShaderCompiled)
  154. {
  155. int i32InfoLogLength, i32CharsWritten;
  156. glGetShaderiv(m_uiVertexShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
  157. char* pszInfoLog = new char[i32InfoLogLength];
  158. glGetShaderInfoLog(m_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  159. char* pszMsg = new char[i32InfoLogLength+256];
  160. strcpy(pszMsg, "Failed to compile vertex shader: ");
  161. strcat(pszMsg, pszInfoLog);
  162. PVRShellSet(prefExitMessage, pszMsg);
  163. delete [] pszMsg;
  164. delete [] pszInfoLog;
  165. return false;
  166. }
  167. // Create the shader program
  168. m_uiProgramObject = glCreateProgram();
  169. // Attach the fragment and vertex shaders to it
  170. glAttachShader(m_uiProgramObject, m_uiFragShader);
  171. glAttachShader(m_uiProgramObject, m_uiVertexShader);
  172. // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY
  173. glBindAttribLocation(m_uiProgramObject, VERTEX_ARRAY, "myVertex");
  174. // Bind the custom vertex attribute "myUV" to location TEXCOORD_ARRAY
  175. glBindAttribLocation(m_uiProgramObject, TEXCOORD_ARRAY, "myUV");
  176. // Link the program
  177. glLinkProgram(m_uiProgramObject);
  178. // Check if linking succeeded in the same way we checked for compilation success
  179. GLint bLinked;
  180. glGetProgramiv(m_uiProgramObject, GL_LINK_STATUS, &bLinked);
  181. if (!bLinked)
  182. {
  183. int i32InfoLogLength, i32CharsWritten;
  184. glGetProgramiv(m_uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
  185. char* pszInfoLog = new char[i32InfoLogLength];
  186. glGetProgramInfoLog(m_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  187. char* pszMsg = new char[i32InfoLogLength+256];
  188. strcpy(pszMsg, "Failed to link program: ");
  189. strcat(pszMsg, pszInfoLog);
  190. PVRShellSet(prefExitMessage, pszMsg);
  191. delete [] pszMsg;
  192. delete [] pszInfoLog;
  193. return false;
  194. }
  195. // Actually use the created program
  196. glUseProgram(m_uiProgramObject);
  197. // Sets the sampler2D variable to the first texture unit
  198. glUniform1i(glGetUniformLocation(m_uiProgramObject, "sampler2d"), 0);
  199. // Sets the clear color
  200. glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
  201. /*
  202. Creates the texture.
  203. Please refer to the training course "Texturing" for a detailed explanation.
  204. */
  205. glGenTextures(1, &m_uiTexture);
  206. glBindTexture(GL_TEXTURE_2D, m_uiTexture);
  207. GLuint* pTexData = new GLuint[TEX_SIZE*TEX_SIZE];
  208. for (int i=0; i<TEX_SIZE; i++)
  209. for (int j=0; j<TEX_SIZE; j++)
  210. {
  211. GLuint col = (255L<<24) + ((255L-j*2)<<16) + ((255L-i)<<8) + (255L-i*2);
  212. if ( ((i*j)/8) % 2 ) col = (GLuint) (255L<<24) + (255L<<16) + (0L<<8) + (255L);
  213. pTexData[j*TEX_SIZE+i] = col;
  214. }
  215. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData);
  216. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  217. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  218. delete [] pTexData;
  219. // Create VBO for the triangle from our data
  220. // Interleaved vertex data
  221. GLfloat afVertices[] = {-0.4f,-0.4f,0.0f, // Pos
  222. 0.0f,0.0f , // UVs
  223. 0.0f,0.0f,1.0f, // Normals
  224. 0.4f,-0.4f,0.0f,
  225. 1.0f,0.0f ,
  226. 0.0f,0.0f,1.0f,
  227. 0.0f,0.4f ,0.0f,
  228. 0.5f,1.0f,
  229. 0.0f,0.0f,1.0f};
  230. glGenBuffers(1, &m_ui32Vbo);
  231. m_ui32VertexStride = 8 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs, 3 for normals
  232. // Bind the VBO
  233. glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);
  234. // Set the buffer's data
  235. glBufferData(GL_ARRAY_BUFFER, 3 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
  236. // Unbind the VBO
  237. glBindBuffer(GL_ARRAY_BUFFER, 0);
  238. return true;
  239. }
  240. /*!****************************************************************************
  241. @Function ReleaseView
  242. @Return bool true if no error occured
  243. @Description Code in ReleaseView() will be called by PVRShell when the
  244. application quits or before a change in the rendering context.
  245. ******************************************************************************/
  246. bool OGLESBasicTnL::ReleaseView()
  247. {
  248. // Frees the texture
  249. glDeleteTextures(1, &m_uiTexture);
  250. // Release Vertex buffer object.
  251. glDeleteBuffers(1, &m_ui32Vbo);
  252. // Frees the OpenGL handles for the program and the 2 shaders
  253. glDeleteProgram(m_uiProgramObject);
  254. glDeleteShader(m_uiVertexShader);
  255. glDeleteShader(m_uiFragShader);
  256. return true;
  257. }
  258. /*!****************************************************************************
  259. @Function RenderScene
  260. @Return bool true if no error occured
  261. @Description Main rendering loop function of the program. The shell will
  262. call this function every frame.
  263. eglSwapBuffers() will be performed by PVRShell automatically.
  264. PVRShell will also manage important OS events.
  265. Will also manage relevent OS events. The user has access to
  266. these events through an abstraction layer provided by PVRShell.
  267. ******************************************************************************/
  268. bool OGLESBasicTnL::RenderScene()
  269. {
  270. float aModelViewIT[] =
  271. {
  272. cos(m_fAngle), 0, sin(m_fAngle),
  273. 0, 1, 0,
  274. -sin(m_fAngle), 0, cos(m_fAngle)
  275. };
  276. // Clears the color and depth buffer
  277. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  278. /*
  279. Bind the projection model view matrix (PMVMatrix) to the
  280. corresponding uniform variable in the shader.
  281. This matrix is used in the vertex shader to transform the vertices.
  282. */
  283. float aPMVMatrix[] =
  284. {
  285. cos(m_fAngle), 0, sin(m_fAngle), 0,
  286. 0, 1, 0, 0,
  287. -sin(m_fAngle), 0, cos(m_fAngle), 0,
  288. 0, 0, 0, 1
  289. };
  290. int i32Location = glGetUniformLocation(m_uiProgramObject, "myPMVMatrix");
  291. glUniformMatrix4fv( i32Location, 1, GL_FALSE, aPMVMatrix);
  292. /*
  293. Bind the Model View Inverse Transpose matrix to the shader.
  294. This matrix is used in the vertex shader to transform the normals.
  295. */
  296. i32Location = glGetUniformLocation(m_uiProgramObject, "myModelViewIT");
  297. glUniformMatrix3fv( i32Location, 1, GL_FALSE, aModelViewIT);
  298. // Bind the Light Direction vector to the shader
  299. i32Location = glGetUniformLocation(m_uiProgramObject, "myLightDirection");
  300. glUniform3f( i32Location, 0, 0, 1);
  301. // Increments the angle of the view
  302. m_fAngle += .02f;
  303. /*
  304. Draw a triangle.
  305. Please refer to the training course IntroducingPVRShell for a detailed explanation.
  306. */
  307. // Bind the VBO
  308. glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);
  309. // Pass the vertex data
  310. glEnableVertexAttribArray(VERTEX_ARRAY);
  311. glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
  312. // Pass the texture coordinates data
  313. glEnableVertexAttribArray(TEXCOORD_ARRAY);
  314. glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (3 * sizeof(GLfloat)) /* Uvs start after the vertex position */);
  315. // Pass the normals data
  316. glEnableVertexAttribArray(NORMAL_ARRAY);
  317. glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (5 * sizeof(GLfloat)) /* Normals start after the position and uvs */);
  318. // Draws a non-indexed triangle array
  319. glDrawArrays(GL_TRIANGLES, 0, 3);
  320. // Unbind the VBO
  321. glBindBuffer(GL_ARRAY_BUFFER, 0);
  322. return true;
  323. }
  324. /*!****************************************************************************
  325. @Function NewDemo
  326. @Return PVRShell* The demo supplied by the user
  327. @Description This function must be implemented by the user of the shell.
  328. The user should return its PVRShell object defining the
  329. behaviour of the application.
  330. ******************************************************************************/
  331. PVRShell* NewDemo()
  332. {
  333. return new OGLESBasicTnL();
  334. }
  335. /******************************************************************************
  336. End of file (OGLESBasicTnL.cpp)
  337. ******************************************************************************/