Posted By

balajeerc on 03/06/11


Tagged

opengl es GL VBO


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

oppey


Simple OpenGL


 / Published in: C
 

URL: blog.balajeerc.info

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <assert.h>
  4. #include "glew.h"
  5. #include <GLUT/GLUT.h>
  6. #include <cml/cml.h>
  7.  
  8. #define DWASSERT(condition,printstatement) if(!condition){ printf(printstatement); assert(condition); }
  9.  
  10. //We use some ugly globals for the time being
  11.  
  12. //Window Dimensions
  13. int currentWindowWidth = 500;
  14. int currentWindowHeight = 500;
  15.  
  16. cml::matrix44f *g_pModelViewProjMatrix;
  17.  
  18. //Function to assert any OpenGL errors
  19. void DWGLErrorAssert()
  20. {
  21. GLint err = glGetError();
  22. if (err == GL_NO_ERROR)
  23. return;
  24.  
  25. printf("DW_ERROR: OpenGL error encountered!"
  26. "Error Code: %d\n",err);
  27. DWASSERT(false,"");
  28. }
  29.  
  30. /////////////////////////////////////////////////////////////////
  31. // Shaders: Source, Compling and Linking
  32. /////////////////////////////////////////////////////////////////
  33. const char vertexShaderSrc[] =
  34. "uniform mat4 ProjectionModelviewMatrix;\n"
  35. "attribute vec4 InVertex;\n"
  36. "void main()\n"
  37. "{\n"
  38. " gl_Position = ProjectionModelviewMatrix * InVertex;\n"
  39. "}\n"
  40. ;
  41.  
  42. const char fragmentShaderSrc[] =
  43. "void main()\n"
  44. "{\n"
  45. " gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n"
  46. "}\n"
  47. ;
  48.  
  49. struct Shader
  50. {
  51. GLuint vertexShaderId;
  52. GLuint fragmentShaderId;
  53. GLuint shaderProgramId;
  54. };
  55.  
  56. //Global shader pointer
  57. Shader* g_pShader;
  58.  
  59. void GetErrorLog(int shaderId)
  60. {
  61. GLint log_length;
  62. char *log;
  63.  
  64. //glGetShaderiv returns a parameter from a shader object
  65. //We use it to get information regarding the log string
  66. glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length);
  67.  
  68. //Allocate memory for the log error string
  69. log = new char[log_length+1];
  70.  
  71. //Now we get the shader log string itself
  72. glGetShaderInfoLog(shaderId, log_length, NULL, log);
  73.  
  74. //Dump the error to console
  75. printf("%s\n", log);
  76. delete [] log;
  77. }
  78.  
  79. void LoadAndCompileShader(const char* shaderSource, GLuint* shaderId, GLenum shaderType)
  80. {
  81. //Obtain length of source
  82. int shaderSourceLen = strlen(shaderSource);
  83.  
  84. //Create shader
  85. *shaderId = glCreateShader(shaderType);
  86. DWASSERT(shaderId!=0,"Unable to create shader\n");
  87.  
  88. //Specify the shader source
  89. glShaderSource(*shaderId, //Shader Id
  90. 1, //Number of shaders required
  91. &shaderSource, //Shader source
  92. &shaderSourceLen); //Character length of the source
  93. DWGLErrorAssert();
  94.  
  95. //Compile the shader
  96. glCompileShader(*shaderId);
  97.  
  98. //We now check compilation status
  99. GLint shader_ok;
  100. glGetShaderiv(*shaderId, GL_COMPILE_STATUS, &shader_ok);
  101. if (!shader_ok)
  102. {
  103. //Compilation failed
  104. printf("ERROR: Shader failed to compile. Error log follows:\n");
  105. GetErrorLog(*shaderId);
  106. glDeleteShader(*shaderId);
  107. DWASSERT(false,"");
  108. }
  109. DWGLErrorAssert();
  110. }
  111.  
  112. void AttachAndLinkShaders(GLuint vertShaderId, GLuint fragShaderId, GLuint *shaderProgramId)
  113. {
  114. //Create a new program ID
  115. *shaderProgramId = glCreateProgram();
  116.  
  117. glAttachShader(*shaderProgramId, vertShaderId);
  118. glAttachShader(*shaderProgramId, fragShaderId);
  119. DWGLErrorAssert();
  120.  
  121. //We can bind attribute variables here in case we are specifying
  122. //the indices to bind to. Since we don't do that, and let GL implementation
  123. //assign the indices for attribute variables, we can bind buffers *after* linking the shader.
  124. //We query the ids bound during rendering via glGetAttribLocation
  125. glLinkProgram(*shaderProgramId);
  126.  
  127. GLint program_ok;
  128. glGetProgramiv(*shaderProgramId, GL_LINK_STATUS, &program_ok);
  129. if (!program_ok)
  130. {
  131. printf("Failed to link program with vertex and fragment shaders\n");
  132. GLint log_length;
  133. char *log;
  134.  
  135. glGetProgramiv(*shaderProgramId, GL_INFO_LOG_LENGTH, &log_length);
  136. log = new char[log_length+1];
  137.  
  138. glGetProgramInfoLog(*shaderProgramId, log_length, NULL, log);
  139.  
  140. //Dump the error to console
  141. printf("%s\n", log);
  142.  
  143. delete [] log;
  144.  
  145. glDeleteProgram(*shaderProgramId);
  146. DWASSERT(false,"");
  147. }
  148. }
  149.  
  150. /////////////////////////////////////////////////////////////////
  151. // Plane: Geometry to be rendered on Scene using VBO
  152. /////////////////////////////////////////////////////////////////
  153. float planeHeight = 10;
  154. float planeWidth = 10;
  155.  
  156. float planeVertices[] =
  157. {
  158. -planeWidth/2, -planeHeight/2, 0.f,
  159. planeWidth/2, -planeHeight/2, 0.f,
  160. planeWidth/2, planeHeight/2, 0.f,
  161. -planeWidth/2, planeHeight/2, 0.f
  162. };
  163.  
  164. //Draw the rectanglular plane as two triangles
  165. unsigned int planeIndices[] =
  166. {
  167. 0, 3, 1,
  168. 3, 2, 1
  169. };
  170.  
  171. struct Plane
  172. {
  173. GLuint vertexBufferId;
  174. GLuint elementBufferId;
  175. };
  176.  
  177. //Global Plane pointer
  178. Plane* g_pPlane;
  179.  
  180. void GenerateBuffers(Plane* pPlane)
  181. {
  182. //First bind the vertex coordinates
  183. glGenBuffers(1, &(pPlane->vertexBufferId));
  184. glBindBuffer(GL_ARRAY_BUFFER, pPlane->vertexBufferId);
  185. glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float), planeVertices, GL_STATIC_DRAW);
  186. DWGLErrorAssert();
  187.  
  188. //Now bind the indices
  189. glGenBuffers(1,&(pPlane->elementBufferId));
  190. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pPlane->elementBufferId);
  191. glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(unsigned int), planeIndices, GL_STATIC_DRAW);
  192. DWGLErrorAssert();
  193.  
  194. // bind with 0 so that no buffers are left active/selected until necessary
  195. glBindBuffer(GL_ARRAY_BUFFER, 0);
  196. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  197. }
  198.  
  199. void DrawPlane(Plane* pPlane,Shader* pShader,cml::matrix44f *modelViewProjMatrix)
  200. {
  201. int shaderId = pShader->shaderProgramId;
  202. glUseProgram(shaderId);
  203. DWGLErrorAssert();
  204.  
  205. int loc;
  206. loc = glGetUniformLocation(shaderId, "ProjectionModelviewMatrix");
  207. glUniformMatrix4fv(loc, 1, GL_FALSE, modelViewProjMatrix->data());
  208.  
  209. int vertexLoc = glGetAttribLocation(shaderId, "InVertex");
  210.  
  211. //Specify the vertex coordinates
  212. glBindBuffer(GL_ARRAY_BUFFER, pPlane->vertexBufferId);
  213. glVertexAttribPointer(
  214. vertexLoc, //attribute
  215. 3, //size
  216. GL_FLOAT, //type
  217. GL_FALSE, //not normalized
  218. sizeof(GLfloat)*3, //stride
  219. (void*)0 //array buffer offset
  220. );
  221. glEnableVertexAttribArray(vertexLoc);
  222.  
  223. //Bind the index buffer before initiating draw
  224. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pPlane->elementBufferId);
  225. DWGLErrorAssert();
  226.  
  227. // Draw 2 triangles using just bound(activated) index array
  228. glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
  229. DWGLErrorAssert();
  230.  
  231. //Deactivate array buffers
  232. glDisableVertexAttribArray(vertexLoc);
  233.  
  234. // bind with 0, so, switch back to normal pointer operation
  235. glBindBuffer(GL_ARRAY_BUFFER, 0);
  236. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  237. DWGLErrorAssert();
  238. }
  239.  
  240. //////////////////////////////////////////////////////////////////////////
  241. // GLUT specific code and callback functions
  242. //////////////////////////////////////////////////////////////////////////
  243. void display(void)
  244. {
  245. DWGLErrorAssert();
  246. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  247.  
  248. //Render Scene Code
  249. DrawPlane(g_pPlane, g_pShader,g_pModelViewProjMatrix);
  250.  
  251. glutSwapBuffers();
  252. }
  253.  
  254. void reshape(int width, int height)
  255. {
  256. glViewport(0, 0, (GLsizei)width,(GLsizei)height);
  257. currentWindowWidth = width;
  258. currentWindowHeight = height;
  259. }
  260.  
  261. void idle(void)
  262. {
  263. glutPostRedisplay();
  264. }
  265.  
  266. //////////////////////////////////////////////////////////////////////////
  267. // Application/Scene Setup and Initialisation
  268. //////////////////////////////////////////////////////////////////////////
  269. void InitApplication(Plane* pPlane,Shader* pShader)
  270. {
  271. glFrontFace(GL_CW);
  272. glDisable(GL_CULL_FACE);
  273. glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
  274. glColor3f(1.f, 1.f, 1.f);
  275. glClearColor(0.f, 0.f, 1.f, 1.f);
  276.  
  277. //Generate buffers for plane
  278. GenerateBuffers(pPlane);
  279.  
  280. //Compile shader source
  281. LoadAndCompileShader(vertexShaderSrc, &(pShader->vertexShaderId), GL_VERTEX_SHADER);
  282. LoadAndCompileShader(fragmentShaderSrc, &(pShader->fragmentShaderId), GL_FRAGMENT_SHADER);
  283.  
  284. //Link and attach shaders
  285. AttachAndLinkShaders(pShader->vertexShaderId, pShader->fragmentShaderId, &(pShader->shaderProgramId));
  286.  
  287.  
  288. //Setup camera projection matrix
  289. cml::matrix44f projection; //projection matrix (row major type)
  290. cml::matrix_perspective(projection, //Projection matrix to set
  291. -1.0f, //Left
  292. 1.0f, //Right
  293. -1.0f, //Bottom
  294. 1.0f, //Top
  295. 1.0f, //Near
  296. 100.0f, //Far
  297. cml::right_handed, //Handedness
  298. cml::z_clip_neg_one //enum specifying near clipping range of the
  299. ); //canonical view volume for projection matrices
  300.  
  301. //Setup the camera view matrix
  302. //Setup view matrix
  303. cml::matrix44f view; //view matrix (row major type)
  304. cml::vector3f eye, target, up;
  305. eye.set(0.f,0.f,10.f); // Set 'eye' to (0.f,0.f,10.f)
  306. target.set(0.f,0.f,0.f); // Set 'target' to (0.f,0.f,0.f)
  307. up.set(0.f,1.f,0.f); // Set 'up' to (0,1,0), the cardinal Y axis
  308. cml::matrix_look_at_RH(view, eye, target, up);
  309.  
  310. //Set the global pointers
  311. g_pPlane = pPlane;
  312. g_pShader = pShader;
  313. g_pModelViewProjMatrix = new cml::matrix44f();
  314. *g_pModelViewProjMatrix = projection*view;
  315.  
  316. for (int i=0; i<4; i++)
  317. {
  318. for(int j=0;j<4;j++)
  319. printf("%f ", (*g_pModelViewProjMatrix)(i,j));
  320.  
  321. printf("\n");
  322. }
  323.  
  324. }
  325.  
  326.  
  327. int main(int argc, char** argv)
  328. {
  329. //Initialising GLUT
  330. glutInit(&argc, argv);
  331. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  332. glutInitWindowSize(currentWindowWidth,currentWindowHeight);
  333. glutCreateWindow("Trial GL");
  334. glutDisplayFunc(display);
  335. glutReshapeFunc(reshape);
  336. glutIdleFunc(idle);
  337. DWGLErrorAssert();
  338.  
  339. //Create a valid OpenGL rendering context and call glewInit()
  340. //to initialize the extension entry points. If glewInit() returns GLEW_OK,
  341. //the initialization succeeded and we can use the available extensions as
  342. //well as core OpenGL functionality.
  343. GLenum err = glewInit();
  344. if (GLEW_OK != err)
  345. {
  346. //Problem: glewInit failed, something is seriously wrong.
  347. fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
  348. }
  349. fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
  350.  
  351. //Send message to console
  352. printf("Starting Application...\n");
  353.  
  354. //Create plane
  355. struct Plane newPlane;
  356.  
  357. //Create shader
  358. struct Shader newShader;
  359.  
  360. InitApplication(&newPlane,&newShader);
  361.  
  362. //Start main loop
  363. glutMainLoop();
  364.  
  365. return 0;
  366. }

Report this snippet  

You need to login to post a comment.