filename | src/pvr2/gl_sl.c |
changeset | 736:a02d1475ccfd |
prev | 679:f5ae66677a49 |
next | 1009:c29795e15cef |
author | nkeynes |
date | Mon Jan 26 07:26:24 2009 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Add read_byte_for_write mem function for correct implementation of AND.B and friends with TLB enabled. Add read_byte and read_long MMIO stubs to do correct sign extension of IO reads |
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 glsl_enable_shaders(FALSE); // initially disabled
103 } else {
104 glsl_unload_shaders();
105 }
106 return pok;
107 }
109 void glsl_enable_shaders(gboolean en)
110 {
111 if( glsl_program != 0 ) {
112 if( en ) {
113 glUseProgramObjectARB(glsl_program);
114 } else {
115 glUseProgramObjectARB(0);
116 }
117 }
118 }
120 void glsl_unload_shaders(void)
121 {
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);
128 }
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 )
134 {
135 GLint value;
137 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
138 if( value == 0 ) {
139 char buf[MAX_ERROR_BUF];
140 GLsizei length;
141 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
142 ERROR( "%s: %s", msg, buf );
143 return FALSE;
144 }
145 return TRUE;
146 }
147 gboolean glsl_check_program_error( char *msg, GLuint program )
148 {
149 if( glGetError() != GL_NO_ERROR ) {
150 char buf[MAX_ERROR_BUF];
151 GLsizei length;
152 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
153 ERROR( "%s: %s", msg, buf );
154 return FALSE;
155 }
156 return TRUE;
157 }
159 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
160 {
161 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
163 if( vertex_src == NULL && fragment_src == NULL ) {
164 return TRUE;
165 }
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 );
174 }
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 );
180 }
182 if( vsok && fsok ) {
183 if( vertex_src != NULL ) {
184 glAttachShader(glsl_program, glsl_vert_shader);
185 }
186 if( fragment_src != NULL ) {
187 glAttachShader(glsl_program, glsl_frag_shader);
188 }
189 glLinkProgram(glsl_program);
190 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
191 }
193 if( pok ) {
194 glUseProgram(glsl_program);
195 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
196 glsl_enable_shaders(FALSE); // initially disabled
197 } else {
198 glsl_unload_shaders();
199 }
200 return pok;
201 }
204 void glsl_enable_shaders(gboolean en)
205 {
206 if( glsl_program != 0 ) {
207 if( en ) {
208 glUseProgram(glsl_program);
209 } else {
210 glUseProgram(0);
211 }
212 }
213 }
215 void glsl_unload_shaders(void)
216 {
217 glUseProgram(0);
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);
223 }
225 #else
226 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
227 {
228 return FALSE;
229 }
231 void glsl_unload_shaders()
232 {
233 }
235 void glsl_enable_shaders( gboolean enable )
236 {
237 }
238 #endif
.