Index: third_party/gles_book_examples/Chapter_2/Hello_Triangle/Hello_Triangle.c |
=================================================================== |
--- third_party/gles_book_examples/Chapter_2/Hello_Triangle/Hello_Triangle.c (revision 35503) |
+++ third_party/gles_book_examples/Chapter_2/Hello_Triangle/Hello_Triangle.c (working copy) |
@@ -1,109 +1,194 @@ |
-// |
-// Book: OpenGL(R) ES 2.0 Programming Guide |
-// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner |
-// ISBN-10: 0321502795 |
-// ISBN-13: 9780321502797 |
-// Publisher: Addison-Wesley Professional |
-// URLs: http://safari.informit.com/9780321563835 |
-// http://www.opengles-book.com |
-// |
- |
-// Hello_Triangle.c |
-// |
-// This is a simple example that draws a single triangle with |
-// a minimal vertex/fragment shader. The purpose of this |
-// example is to demonstrate the basic concepts of |
-// OpenGL ES 2.0 rendering. |
- |
-#include "Hello_Triangle.h" |
- |
-#include <stdlib.h> |
- |
-/// |
-// Initialize the shader and program object |
-// |
-int htInit ( ESContext *esContext ) |
-{ |
- HTUserData *userData = esContext->userData; |
- |
- GLbyte vShaderStr[] = |
- "attribute vec4 vPosition; \n" |
- "void main() \n" |
- "{ \n" |
- " gl_Position = vPosition; \n" |
- "} \n"; |
- |
- // TODO(alokp): Shaders containing "precision" do not compile. |
- GLbyte fShaderStr[] = |
- "void main() \n" |
- "{ \n" |
- " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n" |
- "} \n"; |
- |
- // TODO(alokp): Client-side vertex arrays do not work. |
- GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f, |
- -0.5f, -0.5f, 0.0f, |
- 0.5f, -0.5f, 0.0f }; |
- |
- userData->programObject = esLoadProgram ( vShaderStr, fShaderStr ); |
- if ( userData->programObject == 0 ) return FALSE; |
- |
- // Bind vPosition to attribute 0 |
- glBindAttribLocation ( userData->programObject, 0, "vPosition" ); |
- |
- glGenBuffers ( 1, &userData->vbo ); |
- glBindBuffer ( GL_ARRAY_BUFFER, userData->vbo ); |
- glBufferData ( GL_ARRAY_BUFFER, sizeof(vVertices), NULL, GL_STATIC_DRAW ); |
- glBufferSubData ( GL_ARRAY_BUFFER, 0, sizeof(vVertices), vVertices ); |
- |
- glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); |
- return TRUE; |
-} |
- |
-/// |
-// Draw a triangle using the shader pair created in Init() |
-// |
-void htDraw ( ESContext *esContext ) |
-{ |
- HTUserData *userData = esContext->userData; |
- |
- // Set the viewport |
- glViewport ( 0, 0, esContext->width, esContext->height ); |
- |
- // Clear the color buffer |
- glClear ( GL_COLOR_BUFFER_BIT ); |
- |
- // Use the program object |
- glUseProgram ( userData->programObject ); |
- |
- // Load the vertex data |
- glBindBuffer ( GL_ARRAY_BUFFER, userData->vbo ); |
- glEnableVertexAttribArray ( 0 ); |
- glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 ); |
- |
- glDrawArrays ( GL_TRIANGLES, 0, 3 ); |
- |
- // Nothing is drawn or application crashes without glFlush. |
- // TODO(alokp): glFlush should not be necessary with SwapBuffers(). |
- glFlush(); |
-} |
- |
-/// |
-// Cleanup |
-// |
-void htShutDown ( ESContext *esContext ) |
-{ |
- HTUserData *userData = esContext->userData; |
- |
- // Delete program object |
- if ( userData->programObject != 0 ) |
- { |
- glDeleteProgram ( userData->programObject ); |
- userData->programObject = 0; |
- } |
- if ( userData->vbo != 0 ) |
- { |
- glDeleteBuffers ( 1, &userData->vbo ); |
- userData->vbo = 0; |
- } |
-} |
+// |
+// Book: OpenGL(R) ES 2.0 Programming Guide |
+// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner |
+// ISBN-10: 0321502795 |
+// ISBN-13: 9780321502797 |
+// Publisher: Addison-Wesley Professional |
+// URLs: http://safari.informit.com/9780321563835 |
+// http://www.opengles-book.com |
+// |
+ |
+// Hello_Triangle.c |
+// |
+// This is a simple example that draws a single triangle with |
+// a minimal vertex/fragment shader. The purpose of this |
+// example is to demonstrate the basic concepts of |
+// OpenGL ES 2.0 rendering. |
+#include <stdlib.h> |
+#include "esUtil.h" |
+ |
+typedef struct |
+{ |
+ // Handle to a program object |
+ GLuint programObject; |
+ |
+} UserData; |
+ |
+/// |
+// Create a shader object, load the shader source, and |
+// compile the shader. |
+// |
+GLuint LoadShader ( GLenum type, const char *shaderSrc ) |
+{ |
+ GLuint shader; |
+ GLint compiled; |
+ |
+ // Create the shader object |
+ shader = glCreateShader ( type ); |
+ |
+ if ( shader == 0 ) |
+ return 0; |
+ |
+ // Load the shader source |
+ glShaderSource ( shader, 1, &shaderSrc, NULL ); |
+ |
+ // Compile the shader |
+ glCompileShader ( shader ); |
+ |
+ // Check the compile status |
+ glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); |
+ |
+ if ( !compiled ) |
+ { |
+ GLint infoLen = 0; |
+ |
+ glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen ); |
+ |
+ if ( infoLen > 1 ) |
+ { |
+ char* infoLog = malloc (sizeof(char) * infoLen ); |
+ |
+ glGetShaderInfoLog ( shader, infoLen, NULL, infoLog ); |
+ esLogMessage ( "Error compiling shader:\n%s\n", infoLog ); |
+ |
+ free ( infoLog ); |
+ } |
+ |
+ glDeleteShader ( shader ); |
+ return 0; |
+ } |
+ |
+ return shader; |
+ |
+} |
+ |
+/// |
+// Initialize the shader and program object |
+// |
+int Init ( ESContext *esContext ) |
+{ |
+ UserData *userData = esContext->userData; |
+ GLbyte vShaderStr[] = |
+ "attribute vec4 vPosition; \n" |
+ "void main() \n" |
+ "{ \n" |
+ " gl_Position = vPosition; \n" |
+ "} \n"; |
+ |
+ GLbyte fShaderStr[] = |
+ "precision mediump float;\n"\ |
+ "void main() \n" |
+ "{ \n" |
+ " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n" |
+ "} \n"; |
+ |
+ GLuint vertexShader; |
+ GLuint fragmentShader; |
+ GLuint programObject; |
+ GLint linked; |
+ |
+ // Load the vertex/fragment shaders |
+ vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr ); |
+ fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr ); |
+ |
+ // Create the program object |
+ programObject = glCreateProgram ( ); |
+ |
+ if ( programObject == 0 ) |
+ return 0; |
+ |
+ glAttachShader ( programObject, vertexShader ); |
+ glAttachShader ( programObject, fragmentShader ); |
+ |
+ // Bind vPosition to attribute 0 |
+ glBindAttribLocation ( programObject, 0, "vPosition" ); |
+ |
+ // Link the program |
+ glLinkProgram ( programObject ); |
+ |
+ // Check the link status |
+ glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); |
+ |
+ if ( !linked ) |
+ { |
+ GLint infoLen = 0; |
+ |
+ glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen ); |
+ |
+ if ( infoLen > 1 ) |
+ { |
+ char* infoLog = malloc (sizeof(char) * infoLen ); |
+ |
+ glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog ); |
+ esLogMessage ( "Error linking program:\n%s\n", infoLog ); |
+ |
+ free ( infoLog ); |
+ } |
+ |
+ glDeleteProgram ( programObject ); |
+ return FALSE; |
+ } |
+ |
+ // Store the program object |
+ userData->programObject = programObject; |
+ |
+ glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); |
+ return TRUE; |
+} |
+ |
+/// |
+// Draw a triangle using the shader pair created in Init() |
+// |
+void Draw ( ESContext *esContext ) |
+{ |
+ UserData *userData = esContext->userData; |
+ GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f, |
+ -0.5f, -0.5f, 0.0f, |
+ 0.5f, -0.5f, 0.0f }; |
+ |
+ // Set the viewport |
+ glViewport ( 0, 0, esContext->width, esContext->height ); |
+ |
+ // Clear the color buffer |
+ glClear ( GL_COLOR_BUFFER_BIT ); |
+ |
+ // Use the program object |
+ glUseProgram ( userData->programObject ); |
+ |
+ // Load the vertex data |
+ glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices ); |
+ glEnableVertexAttribArray ( 0 ); |
+ |
+ glDrawArrays ( GL_TRIANGLES, 0, 3 ); |
+ |
+ eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface ); |
+} |
+ |
+ |
+int main ( int argc, char *argv[] ) |
+{ |
+ ESContext esContext; |
+ UserData userData; |
+ |
+ esInitContext ( &esContext ); |
+ esContext.userData = &userData; |
+ |
+ esCreateWindow ( &esContext, "Hello Triangle", 320, 240, ES_WINDOW_RGB ); |
+ |
+ if ( !Init ( &esContext ) ) |
+ return 0; |
+ |
+ esRegisterDrawFunc ( &esContext, Draw ); |
+ |
+ esMainLoop ( &esContext ); |
+} |