4 * GLSL shader loader/unloader. Current version assumes there's exactly
5 * 1 shader program that's used globally. This may turn out not to be the
6 * most efficient approach.
8 * Copyright (c) 2007 Nathan Keynes.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
23 #include "pvr2/glutil.h"
25 #define MAX_ERROR_BUF 4096
27 gboolean glsl_is_supported()
29 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
30 isGLExtensionSupported("GL_ARB_vertex_shader") &&
31 isGLExtensionSupported("GL_ARB_shading_language_100");
34 #ifdef GL_ARB_shader_objects
35 static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
37 void glsl_print_error( char *msg, GLhandleARB obj )
39 char buf[MAX_ERROR_BUF];
41 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
42 ERROR( "%s: %s", msg, buf );
45 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
49 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
51 glsl_print_error(msg, obj);
57 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
59 if( glGetError() != GL_NO_ERROR ) {
60 glsl_print_error(msg, obj);
66 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
68 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
70 if( vertex_src == NULL && fragment_src == NULL ) {
71 return TRUE; // nothing to do
74 glsl_program = glCreateProgramObjectARB();
76 if( vertex_src != NULL ) {
77 glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
78 glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
79 glCompileShaderARB(glsl_vert_shader);
80 vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
82 if( fragment_src != NULL ) {
83 glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
84 glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
85 glCompileShaderARB(glsl_frag_shader);
86 fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
90 if( vertex_src != NULL ) {
91 glAttachObjectARB(glsl_program, glsl_vert_shader);
93 if( fragment_src != NULL ) {
94 glAttachObjectARB(glsl_program, glsl_frag_shader);
96 glLinkProgramARB(glsl_program);
97 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
100 glUseProgramObjectARB(glsl_program);
101 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
102 glsl_enable_shaders(FALSE); // initially disabled
104 glsl_unload_shaders();
109 void glsl_enable_shaders(gboolean en)
111 if( glsl_program != 0 ) {
113 glUseProgramObjectARB(glsl_program);
115 glUseProgramObjectARB(0);
120 void glsl_unload_shaders(void)
122 glUseProgramObjectARB(0);
123 glDetachObjectARB(glsl_program, glsl_vert_shader);
124 glDetachObjectARB(glsl_program, glsl_frag_shader);
125 glDeleteObjectARB(glsl_program);
126 glDeleteObjectARB(glsl_vert_shader);
127 glDeleteObjectARB(glsl_frag_shader);
130 #elif HAVE_OPENGL_SHADER
131 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
133 gboolean glsl_check_shader_error( char *msg, GLuint shader )
137 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
139 char buf[MAX_ERROR_BUF];
141 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
142 ERROR( "%s: %s", msg, buf );
147 gboolean glsl_check_program_error( char *msg, GLuint program )
149 if( glGetError() != GL_NO_ERROR ) {
150 char buf[MAX_ERROR_BUF];
152 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
153 ERROR( "%s: %s", msg, buf );
159 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
161 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
163 if( vertex_src == NULL && fragment_src == NULL ) {
167 glsl_program = glCreateProgram();
169 if( vertex_src != NULL ) {
170 glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
171 glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
172 glCompileShader(glsl_vert_shader);
173 vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
175 if( fragment_src != NULL ) {
176 glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
177 glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
178 glCompileShader(glsl_frag_shader);
179 fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
183 if( vertex_src != NULL ) {
184 glAttachShader(glsl_program, glsl_vert_shader);
186 if( fragment_src != NULL ) {
187 glAttachShader(glsl_program, glsl_frag_shader);
189 glLinkProgram(glsl_program);
190 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
194 glUseProgram(glsl_program);
195 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
196 glsl_enable_shaders(FALSE); // initially disabled
198 glsl_unload_shaders();
204 void glsl_enable_shaders(gboolean en)
206 if( glsl_program != 0 ) {
208 glUseProgram(glsl_program);
215 void glsl_unload_shaders(void)
218 glDetachShader(glsl_program, glsl_vert_shader);
219 glDetachShader(glsl_program, glsl_frag_shader);
220 glDeleteProgram(glsl_program);
221 glDeleteShader(glsl_vert_shader);
222 glDeleteShader(glsl_frag_shader);
226 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
231 void glsl_unload_shaders()
235 void glsl_enable_shaders( gboolean enable )
.