1 /***************************************************************************
3 * Copyright 2010,2011 BMW Car IT GmbH
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 ****************************************************************************/
20 #ifndef _RENDERUTIL_H_
21 #define _RENDERUTIL_H_
23 #include "GLES2/gl2.h"
30 // Loads a file containing shader code
31 static char* RenderUtilLoadShaderFile(const char *szFilename)
39 pFile = fopen(szFilename, "rb");
42 LOG_ERROR("RenderUtilLoadShaderFile","Unable to open ShaderFile " << szFilename);
46 fseek(pFile, 0, SEEK_END);
47 long size = ftell(pFile);
48 fseek(pFile, 0, SEEK_SET);
50 char *pBuffer = new char[size+1];
53 LOG_ERROR("RenderUtilLoadShaderFile","Unable to allocate Memory for ShaderFile " << szFilename);
58 if(1 != fread(pBuffer, size, 1, pFile))
60 LOG_ERROR("RenderUtilLoadShaderFile","Unable to allocate Memory for ShaderFile " << szFilename);
68 LOG_DEBUG("RenderUtilShaderDebug","loaded file with bytes: " << size);
74 // If shader compilation fails, prints the associated logs
75 static void RenderUtilShaderDebug(GLuint obj, GLenum status, const char* op)
77 char errorMessage[1024];
82 if (status == GL_COMPILE_STATUS) {
83 glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len);
86 glGetShaderInfoLog(obj, len, NULL, str);
89 glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len);
92 glGetProgramInfoLog(obj, len, NULL, str);
95 if (str != NULL && *str != '\0') {
96 strncpy(errorMessage, "--- ",1024);
97 strncat(errorMessage,op, 1000);
98 strncat(errorMessage, " log ---", 8);
99 LOG_DEBUG("RenderUtilShaderDebug",errorMessage);
100 LOG_DEBUG("RenderUtilShaderDebug",str);
102 if (str) { delete[] str; }
104 // check the compile / link status.
105 if (status == GL_COMPILE_STATUS) {
106 glGetShaderiv(obj, status, &success);
108 glGetShaderiv(obj, GL_SHADER_SOURCE_LENGTH, &len);
111 glGetShaderSource(obj, len, NULL, str);
112 if (str != NULL && *str != '\0') {
113 strncpy(errorMessage, "--- ",1024);
114 strncat(errorMessage,op, 1000);
115 strncat(errorMessage, " log ---", 8);
116 LOG_DEBUG("RenderUtilShaderDebug",errorMessage);
117 LOG_DEBUG("RenderUtilShaderDebug",str);
123 glGetProgramiv(obj, status, &success);
128 strncpy(errorMessage, "--- ",1024);
129 strncat(errorMessage,op, 1000);
130 strncat(errorMessage, " failed ---", 7);
131 LOG_DEBUG("RenderUtilShaderDebug",errorMessage);
135 // Take precompiled shader binaries and builds a shader program
136 static GLuint RenderUtilLoadShaderBinaries(
137 const char* vertBin, GLuint vertBinSize,
138 const char* fragBin, GLuint fragBinSize,
142 // Binary shaders not supportable for non-ES OpenGL
143 #ifdef GL_ES_VERSION_2_0
149 // Create the program
150 prog = glCreateProgram();
152 // Create the GL shader objects
153 vertShader = glCreateShader(GL_VERTEX_SHADER);
154 fragShader = glCreateShader(GL_FRAGMENT_SHADER);
156 // Load the binary data into the shader objects
157 glShaderBinary(1, &vertShader,
158 binaryFormat, vertBin, vertBinSize);
159 glShaderBinary(1, &fragShader,
160 binaryFormat, fragBin, fragBinSize);
162 // Attach the shaders to the program
163 glAttachShader(prog, vertShader);
164 glAttachShader(prog, fragShader);
167 // Delete the shaders
168 glDeleteShader(vertShader);
169 glDeleteShader(fragShader);
172 // Link the shader program
175 RenderUtilShaderDebug(prog, GL_LINK_STATUS, "Program Link");
178 #else // GL_ES_VERSION_2_0
180 #endif // GL_ES_VERSION_2_0
183 // Takes shader source files, compiles them, and builds a shader program
184 static GLuint RenderUtilLoadShaderSources(
185 const char* vertFile,
186 const char* fragFile,
189 LOG_DEBUG("RenderUtilShaderDebug","loading shaders sources");
190 LOG_DEBUG("RenderUtilShaderDebug","loading vertex shader: " << vertFile);
191 LOG_DEBUG("RenderUtilShaderDebug","loading fragment shader: " << fragFile);
202 // Load the shader files
203 vertSource =RenderUtilLoadShaderFile(vertFile);
204 fragSource = RenderUtilLoadShaderFile(fragFile);
205 LOG_DEBUG("RenderUtilShaderDebug","loaded shaders source files");
206 if (!vertSource || !fragSource) goto done;
207 vertSourceLen = (GLint)strlen(vertSource);
208 fragSourceLen = (GLint)strlen(fragSource);
210 // Create the program
211 prog = glCreateProgram();
213 LOG_DEBUG("RenderUtilShaderDebug","could not create prog, prog is 0");
215 // Create the GL shader objects
216 vertShader = glCreateShader(GL_VERTEX_SHADER);
217 fragShader = glCreateShader(GL_FRAGMENT_SHADER);
219 // Load shader sources into GL and compile
220 glShaderSource(vertShader, 1, (const char**)&vertSource, &vertSourceLen);
221 glCompileShader(vertShader);
223 RenderUtilShaderDebug(vertShader, GL_COMPILE_STATUS, "Vert Compile");
225 glGetShaderiv(vertShader, GL_COMPILE_STATUS, &compiled);
228 glShaderSource(fragShader, 1, (const char**)&fragSource, &fragSourceLen);
229 glCompileShader(fragShader);
231 RenderUtilShaderDebug(fragShader, GL_COMPILE_STATUS, "Frag Compile");
232 glGetShaderiv(fragShader, GL_COMPILE_STATUS, &compiled);
235 // Attach the shaders to the program
236 glAttachShader(prog, vertShader);
237 glAttachShader(prog, fragShader);
239 // Delete the shaders
240 glDeleteShader(vertShader);
241 glDeleteShader(fragShader);
243 // Link and validate the shader program
247 RenderUtilShaderDebug(prog, GL_LINK_STATUS, "Program Link");
248 glValidateProgram(prog);
250 RenderUtilShaderDebug(prog, GL_VALIDATE_STATUS, "Program Validate");
252 glGetProgramiv(prog, GL_LINK_STATUS, &linked);
254 LOG_DEBUG("RenderUtilShaderDebug","could not link shader");
256 LOG_DEBUG("RenderUtilShaderDebug","could not compile fragment shader");
260 LOG_DEBUG("RenderUtilShaderDebug","could not compile vertex shader");
263 if (!compiled || !linked)
265 glDeleteProgram(prog);
276 #endif /* _RENDERUTIL_H_ */