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.
21 #define GL_GLEXT_PROTOTYPES 1
25 #include "pvr2/glutil.h"
27 #define MAX_ERROR_BUF 4096
29 gboolean glsl_is_supported()
31 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
32 isGLExtensionSupported("GL_ARB_vertex_shader") &&
33 isGLExtensionSupported("GL_ARB_shading_language_100");
36 #ifdef GL_ARB_shader_objects
37 static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
39 void glsl_print_error( char *msg, GLhandleARB obj )
41 char buf[MAX_ERROR_BUF];
43 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
44 ERROR( "%s: %s", msg, buf );
47 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
51 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
53 glsl_print_error(msg, obj);
59 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
61 if( glGetError() != GL_NO_ERROR ) {
62 glsl_print_error(msg, obj);
68 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
70 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
72 if( vertex_src == NULL && fragment_src == NULL ) {
73 return TRUE; // nothing to do
76 glsl_program = glCreateProgramObjectARB();
78 if( vertex_src != NULL ) {
79 glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
80 glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
81 glCompileShaderARB(glsl_vert_shader);
82 vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
84 if( fragment_src != NULL ) {
85 glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
86 glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
87 glCompileShaderARB(glsl_frag_shader);
88 fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
92 if( vertex_src != NULL ) {
93 glAttachObjectARB(glsl_program, glsl_vert_shader);
95 if( fragment_src != NULL ) {
96 glAttachObjectARB(glsl_program, glsl_frag_shader);
98 glLinkProgramARB(glsl_program);
99 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
102 glUseProgramObjectARB(glsl_program);
103 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
105 glsl_unload_shaders();
110 void glsl_enable_shader(gboolean en)
112 if( glsl_program != 0 ) {
114 glUseProgramObjectARB(glsl_program);
116 glUseProgramObjectARB(0);
121 void glsl_unload_shaders(void)
123 glUseProgramObjectARB(0);
124 glDetachObjectARB(glsl_program, glsl_vert_shader);
125 glDetachObjectARB(glsl_program, glsl_frag_shader);
126 glDeleteObjectARB(glsl_program);
127 glDeleteObjectARB(glsl_vert_shader);
128 glDeleteObjectARB(glsl_frag_shader);
131 #elif HAVE_OPENGL_SHADER
132 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
134 gboolean glsl_check_shader_error( char *msg, GLuint shader )
138 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
140 char buf[MAX_ERROR_BUF];
142 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
143 ERROR( "%s: %s", msg, buf );
148 gboolean glsl_check_program_error( char *msg, GLuint program )
150 if( glGetError() != GL_NO_ERROR ) {
151 char buf[MAX_ERROR_BUF];
153 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
154 ERROR( "%s: %s", msg, buf );
160 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
162 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
164 if( vertex_src == NULL && fragment_src == NULL ) {
168 glsl_program = glCreateProgram();
170 if( vertex_src != NULL ) {
171 glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
172 glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
173 glCompileShader(glsl_vert_shader);
174 vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
176 if( fragment_src != NULL ) {
177 glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
178 glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
179 glCompileShader(glsl_frag_shader);
180 fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
184 if( vertex_src != NULL ) {
185 glAttachShader(glsl_program, glsl_vert_shader);
187 if( fragment_src != NULL ) {
188 glAttachShader(glsl_program, glsl_frag_shader);
190 glLinkProgram(glsl_program);
191 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
195 glUseProgram(glsl_program);
197 glsl_unload_shaders();
203 void glsl_enable_shader(gboolean en)
205 if( glsl_program != 0 ) {
207 glUseProgram(glsl_program);
214 void glsl_unload_shaders(void)
217 glDetachShader(glsl_program, glsl_vert_shader);
218 glDetachShader(glsl_program, glsl_frag_shader);
219 glDeleteProgram(glsl_program);
220 glDeleteShader(glsl_vert_shader);
221 glDeleteShader(glsl_frag_shader);
225 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
230 void glsl_unload_shaders()
.