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//
43GLuint 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//
96GLuint 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