filename | src/pvr2/gl_sl.c |
changeset | 669:ab344e42bca9 |
prev | 656:031d23fa6d0b |
next | 679:f5ae66677a49 |
author | nkeynes |
date | Thu May 29 10:50:25 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Remove pvr2mmio.h include from pvr2.h (it's supposed to be moore or less private) Move redraw function from driver into pvr2_redraw_display() |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
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.
7 *
8 * Copyright (c) 2007 Nathan Keynes.
9 *
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.
14 *
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.
19 */
21 #include "lxdream.h"
22 #include "display.h"
23 #include "pvr2/glutil.h"
25 #define MAX_ERROR_BUF 4096
27 gboolean glsl_is_supported()
28 {
29 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
30 isGLExtensionSupported("GL_ARB_vertex_shader") &&
31 isGLExtensionSupported("GL_ARB_shading_language_100");
32 }
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 )
38 {
39 char buf[MAX_ERROR_BUF];
40 GLsizei length;
41 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
42 ERROR( "%s: %s", msg, buf );
43 }
45 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
46 {
47 GLint value;
49 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
50 if( value == 0 ) {
51 glsl_print_error(msg, obj);
52 return FALSE;
53 }
54 return TRUE;
55 }
57 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
58 {
59 if( glGetError() != GL_NO_ERROR ) {
60 glsl_print_error(msg, obj);
61 }
62 return TRUE;
63 }
66 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
67 {
68 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
70 if( vertex_src == NULL && fragment_src == NULL ) {
71 return TRUE; // nothing to do
72 }
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);
81 }
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);
87 }
89 if( vsok && fsok ) {
90 if( vertex_src != NULL ) {
91 glAttachObjectARB(glsl_program, glsl_vert_shader);
92 }
93 if( fragment_src != NULL ) {
94 glAttachObjectARB(glsl_program, glsl_frag_shader);
95 }
96 glLinkProgramARB(glsl_program);
97 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
98 }
99 if( pok ) {
100 glUseProgramObjectARB(glsl_program);
101 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
102 } else {
103 glsl_unload_shaders();
104 }
105 return pok;
106 }
108 void glsl_enable_shaders(gboolean en)
109 {
110 if( glsl_program != 0 ) {
111 if( en ) {
112 glUseProgramObjectARB(glsl_program);
113 } else {
114 glUseProgramObjectARB(0);
115 }
116 }
117 }
119 void glsl_unload_shaders(void)
120 {
121 glUseProgramObjectARB(0);
122 glDetachObjectARB(glsl_program, glsl_vert_shader);
123 glDetachObjectARB(glsl_program, glsl_frag_shader);
124 glDeleteObjectARB(glsl_program);
125 glDeleteObjectARB(glsl_vert_shader);
126 glDeleteObjectARB(glsl_frag_shader);
127 }
129 #elif HAVE_OPENGL_SHADER
130 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
132 gboolean glsl_check_shader_error( char *msg, GLuint shader )
133 {
134 GLint value;
136 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
137 if( value == 0 ) {
138 char buf[MAX_ERROR_BUF];
139 GLsizei length;
140 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
141 ERROR( "%s: %s", msg, buf );
142 return FALSE;
143 }
144 return TRUE;
145 }
146 gboolean glsl_check_program_error( char *msg, GLuint program )
147 {
148 if( glGetError() != GL_NO_ERROR ) {
149 char buf[MAX_ERROR_BUF];
150 GLsizei length;
151 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
152 ERROR( "%s: %s", msg, buf );
153 return FALSE;
154 }
155 return TRUE;
156 }
158 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
159 {
160 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
162 if( vertex_src == NULL && fragment_src == NULL ) {
163 return TRUE;
164 }
166 glsl_program = glCreateProgram();
168 if( vertex_src != NULL ) {
169 glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
170 glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
171 glCompileShader(glsl_vert_shader);
172 vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
173 }
174 if( fragment_src != NULL ) {
175 glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
176 glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
177 glCompileShader(glsl_frag_shader);
178 fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
179 }
181 if( vsok && fsok ) {
182 if( vertex_src != NULL ) {
183 glAttachShader(glsl_program, glsl_vert_shader);
184 }
185 if( fragment_src != NULL ) {
186 glAttachShader(glsl_program, glsl_frag_shader);
187 }
188 glLinkProgram(glsl_program);
189 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
190 }
192 if( pok ) {
193 glUseProgram(glsl_program);
194 } else {
195 glsl_unload_shaders();
196 }
197 return pok;
198 }
201 void glsl_enable_shaders(gboolean en)
202 {
203 if( glsl_program != 0 ) {
204 if( en ) {
205 glUseProgram(glsl_program);
206 } else {
207 glUseProgram(0);
208 }
209 }
210 }
212 void glsl_unload_shaders(void)
213 {
214 glUseProgram(0);
215 glDetachShader(glsl_program, glsl_vert_shader);
216 glDetachShader(glsl_program, glsl_frag_shader);
217 glDeleteProgram(glsl_program);
218 glDeleteShader(glsl_vert_shader);
219 glDeleteShader(glsl_frag_shader);
220 }
222 #else
223 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
224 {
225 return FALSE;
226 }
228 void glsl_unload_shaders()
229 {
230 }
232 void glsl_enable_shaders( gboolean enable )
233 {
234 }
235 #endif
.