4 * GLSL wrapper code to hide the differences between the different gl/sl APIs.
6 * Copyright (c) 2007-2010 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
23 #include "pvr2/glutil.h"
25 #define MAX_ERROR_BUF 4096
26 #define INVALID_SHADER 0
27 #define INVALID_PROGRAM 0
29 #ifdef HAVE_OPENGL_SHADER_ARB
30 typedef GLhandleARB gl_program_t;
31 typedef GLhandleARB gl_shader_t;
33 typedef GLuint gl_program_t;
34 typedef GLuint gl_shader_t;
37 gboolean glsl_is_supported();
38 gl_shader_t glsl_create_vertex_shader( const char *source );
39 gl_shader_t glsl_create_fragment_shader( const char *source );
40 gl_program_t glsl_create_program( gl_shader_t *shaderv );
41 void glsl_use_program(gl_program_t program);
42 void glsl_destroy_shader(gl_shader_t shader);
43 void glsl_destroy_program(gl_program_t program);
45 #ifdef HAVE_OPENGL_SHADER_ARB
47 gboolean glsl_is_supported()
49 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
50 isGLExtensionSupported("GL_ARB_vertex_shader") &&
51 isGLExtensionSupported("GL_ARB_shading_language_100");
54 const char *glsl_get_version()
56 return glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
59 void glsl_print_error( char *msg, GLhandleARB obj )
61 char buf[MAX_ERROR_BUF];
63 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
64 ERROR( "%s: %s", msg, buf );
67 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
71 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
73 glsl_print_error(msg, obj);
79 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
81 if( glGetError() != GL_NO_ERROR ) {
82 glsl_print_error(msg, obj);
87 gl_shader_t glsl_create_vertex_shader( const char *source )
90 gl_shader_t shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
92 glShaderSourceARB( shader, 1, &source, NULL );
93 glCompileShaderARB(shader);
94 ok = glsl_check_shader_error("Failed to compile vertex shader", shader);
96 glDeleteObjectARB(shader);
97 return INVALID_SHADER;
103 gl_shader_t glsl_create_fragment_shader( const char *source )
106 gl_shader_t shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
108 glShaderSourceARB( shader, 1, &source, NULL );
109 glCompileShaderARB(shader);
110 ok = glsl_check_shader_error("Failed to compile fragment shader", shader);
112 glDeleteObjectARB(shader);
113 return INVALID_SHADER;
119 gl_program_t glsl_create_program( gl_shader_t *shaderv )
123 gl_program_t program = glCreateProgramObjectARB();
125 for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {
126 glAttachObjectARB(program, shaderv[i]);
129 glLinkProgramARB(program);
130 ok = glsl_check_program_error( "Failed to link shader program", program );
132 glDeleteObjectARB(program);
133 return INVALID_PROGRAM;
139 void glsl_use_program(gl_program_t program)
141 glUseProgramObjectARB(program);
142 glsl_check_program_error( "Failed to activate shader program", program );
145 void glsl_destroy_shader(gl_shader_t shader)
147 glDeleteObjectARB(shader);
150 void glsl_destroy_program(gl_program_t program)
152 glDeleteObjectARB(program);
155 #elif HAVE_OPENGL_SHADER
157 gboolean glsl_is_supported()
159 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
160 isGLExtensionSupported("GL_ARB_vertex_shader") &&
161 isGLExtensionSupported("GL_ARB_shading_language_100");
164 const char *glsl_get_version()
166 return glGetString(GL_SHADING_LANGUAGE_VERSION);
169 gboolean glsl_check_shader_error( char *msg, GLuint shader )
173 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
175 char buf[MAX_ERROR_BUF];
177 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
178 ERROR( "%s: %s", msg, buf );
184 gboolean glsl_check_program_error( char *msg, GLuint program )
186 if( glGetError() != GL_NO_ERROR ) {
187 char buf[MAX_ERROR_BUF];
189 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
190 ERROR( "%s: %s", msg, buf );
196 gl_shader_t glsl_create_vertex_shader( const char *source )
199 gl_shader_t shader = glCreateShader(GL_VERTEX_SHADER);
201 glShaderSource( shader, 1, &source, NULL );
202 glCompileShader(shader);
203 ok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
205 glDeleteShader(shader);
206 return INVALID_SHADER;
213 gl_shader_t glsl_create_fragment_shader( const char *source )
216 gl_shader_t shader = glCreateShader(GL_FRAGMENT_SHADER);
218 glShaderSource( shader, 1, &source, NULL );
219 glCompileShader(shader);
220 ok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
222 glDeleteShader(shader);
223 return INVALID_SHADER;
229 gl_program_t glsl_create_program( gl_shader_t *shaderv )
233 gl_program_t program = glCreateProgram();
235 for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {
236 glAttachShader(program, shaderv[i]);
238 glLinkProgram(program);
239 ok = glsl_check_program_error( "Failed to link shader program", program );
241 glDeleteProgram(program);
242 return INVALID_PROGRAM;
248 void glsl_use_program(gl_program_t program)
250 glUseProgram(program);
253 void glsl_destroy_shader(gl_shader_t shader)
255 glDeleteShader(shader);
258 void glsl_destroy_program(gl_program_t program)
260 glDeleteProgram(program);
264 gboolean glsl_is_supported()
269 int glsl_get_version()
274 gl_shader_t glsl_create_vertex_shader( const char *source )
279 gl_shader_t glsl_create_fragment_shader( const char *source )
284 gl_program_t glsl_create_program( gl_shader_t vertex, gl_shader_t fragment )
289 void glsl_use_program(gl_program_t program)
293 void glsl_destroy_shader(gl_shader_t shader)
297 void glsl_destroy_program(gl_program_t program)
302 /****************************************************************************/
304 /* Pull in the auto-generated shader definitions */
306 #include "pvr2/shaders.def"
308 static gl_program_t program_array[GLSL_NUM_PROGRAMS];
310 gboolean glsl_load_shaders()
312 gl_shader_t shader_array[GLSL_NUM_SHADERS];
315 for( i=0; i<GLSL_NUM_SHADERS; i++ )
316 shader_array[i] = INVALID_SHADER;
317 for( i=0; i<GLSL_NUM_PROGRAMS; i++ )
318 program_array[i] = INVALID_PROGRAM;
320 /* Compile the shader fragments */
321 for( i=0; shader_source[i].type != GLSL_NO_SHADER; i++ ) {
322 gl_shader_t shader = INVALID_SHADER;
323 switch(shader_source[i].type) {
324 case GLSL_VERTEX_SHADER:
325 shader = glsl_create_vertex_shader(shader_source[i].source);
327 case GLSL_FRAGMENT_SHADER:
328 shader = glsl_create_fragment_shader(shader_source[i].source);
331 if( shader == INVALID_SHADER ) {
335 shader_array[i] = shader;
339 /* Link the programs */
340 if(ok) for( i=0; program_list[i][0] != GLSL_NO_SHADER; i++ ) {
341 gl_shader_t shaderv[GLSL_NUM_SHADERS+1];
342 for( j=0; program_list[i][j] != GLSL_NO_SHADER; j++ ) {
343 shaderv[j] = shader_array[program_list[i][j]];
345 shaderv[j] = INVALID_SHADER;
346 gl_program_t program = glsl_create_program(shaderv);
347 if( program == INVALID_PROGRAM ) {
351 program_array[i] = program;
356 * Destroy the compiled fragments (the linked programs don't need them
359 for( i=0; i<GLSL_NUM_SHADERS; i++ ) {
360 if( shader_array[i] != INVALID_SHADER )
361 glsl_destroy_shader(shader_array[i]);
365 * If we errored, delete the programs. It's all or nothing.
368 glsl_unload_shaders();
374 void glsl_unload_shaders()
377 for( i=0; i<GLSL_NUM_PROGRAMS; i++ ) {
378 if( program_array[i] != INVALID_PROGRAM ) {
379 glsl_destroy_program(program_array[i]);
380 program_array[i] = INVALID_PROGRAM;
385 gboolean glsl_set_shader(unsigned i)
387 assert( i >= 0 && i <= GLSL_LAST_PROGRAM );
389 if( program_array[i] != INVALID_PROGRAM ) {
390 glsl_use_program(program_array[i]);
397 void glsl_clear_shader()
.