1 // 2 // Book: OpenGL(R) ES 2.0 Programming Guide 3 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner 4 // ISBN-10: 0321502795 5 // ISBN-13: 9780321502797 6 // Publisher: Addison-Wesley Professional 7 // URLs: http://safari.informit.com/9780321563835 8 // http://www.opengles-book.com 9 // 10 11 // ESShader.c 12 // 13 // Utility functions for loading shaders and creating program objects. 14 // 15 16 /// 17 // Includes 18 // 19 #include "esUtil.h" 20 #include <stdlib.h> 21 22 ////////////////////////////////////////////////////////////////// 23 // 24 // Private Functions 25 // 26 // 27 28 29 30 ////////////////////////////////////////////////////////////////// 31 // 32 // Public Functions 33 // 34 // 35 36 // 37 /// 38 /// \brief Load a shader, check for compile errors, print error messages to output log 39 /// \param type Type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER) 40 /// \param shaderSrc Shader source string 41 /// \return A new shader object on success, 0 on failure 42 // 43 GLuint ESUTIL_API esLoadShader ( GLenum type, const char *shaderSrc ) 44 { 45 GLuint shader; 46 GLint compiled; 47 48 // Create the shader object 49 shader = glCreateShader ( type ); 50 51 if ( shader == 0 ) 52 return 0; 53 54 // Load the shader source 55 glShaderSource ( shader, 1, &shaderSrc, NULL ); 56 57 // Compile the shader 58 glCompileShader ( shader ); 59 60 // Check the compile status 61 glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); 62 63 if ( !compiled ) 64 { 65 GLint infoLen = 0; 66 67 glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen ); 68 69 if ( infoLen > 1 ) 70 { 71 char* infoLog = malloc (sizeof(char) * infoLen ); 72 73 glGetShaderInfoLog ( shader, infoLen, NULL, infoLog ); 74 esLogMessage ( "Error compiling shader:\n%s\n", infoLog ); 75 76 free ( infoLog ); 77 } 78 79 glDeleteShader ( shader ); 80 return 0; 81 } 82 83 return shader; 84 85 } 86 87 88 // 89 /// 90 /// \brief Load a vertex and fragment shader, create a program object, link program. 91 // Errors output to log. 92 /// \param vertShaderSrc Vertex shader source code 93 /// \param fragShaderSrc Fragment shader source code 94 /// \return A new program object linked with the vertex/fragment shader pair, 0 on failure 95 // 96 GLuint ESUTIL_API esLoadProgram ( const char *vertShaderSrc, const char *fragShaderSrc ) 97 { 98 GLuint vertexShader; 99 GLuint fragmentShader; 100 GLuint programObject; 101 GLint linked; 102 103 // Load the vertex/fragment shaders 104 vertexShader = esLoadShader ( GL_VERTEX_SHADER, vertShaderSrc ); 105 if ( vertexShader == 0 ) 106 return 0; 107 108 fragmentShader = esLoadShader ( GL_FRAGMENT_SHADER, fragShaderSrc ); 109 if ( fragmentShader == 0 ) 110 { 111 glDeleteShader( vertexShader ); 112 return 0; 113 } 114 115 // Create the program object 116 programObject = glCreateProgram ( ); 117 118 if ( programObject == 0 ) 119 return 0; 120 121 glAttachShader ( programObject, vertexShader ); 122 glAttachShader ( programObject, fragmentShader ); 123 124 // Link the program 125 glLinkProgram ( programObject ); 126 127 // Check the link status 128 glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); 129 130 if ( !linked ) 131 { 132 GLint infoLen = 0; 133 134 glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen ); 135 136 if ( infoLen > 1 ) 137 { 138 char* infoLog = malloc (sizeof(char) * infoLen ); 139 140 glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog ); 141 esLogMessage ( "Error linking program:\n%s\n", infoLog ); 142 143 free ( infoLog ); 144 } 145 146 glDeleteProgram ( programObject ); 147 return 0; 148 } 149 150 // Free up no longer needed shader resources 151 glDeleteShader ( vertexShader ); 152 glDeleteShader ( fragmentShader ); 153 154 return programObject; 155 } 156