filename | src/pvr2/gl_sl.c |
changeset | 635:76c63aac3590 |
next | 656:031d23fa6d0b |
author | nkeynes |
date | Tue Mar 11 08:50:16 2008 +0000 (16 years ago) |
branch | lxdream-render |
permissions | -rw-r--r-- |
last change | Use maxz rather than minz for tri sorting (better results atm) Change depth-test-disable to depth-mask (more correct) Implement alpha test for punchthru polys |
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 #define GL_GLEXT_PROTOTYPES 1
23 #include "lxdream.h"
24 #include "display.h"
25 #include "pvr2/glutil.h"
27 #define MAX_ERROR_BUF 4096
29 gboolean glsl_is_supported()
30 {
31 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
32 isGLExtensionSupported("GL_ARB_vertex_shader") &&
33 isGLExtensionSupported("GL_ARB_shading_language_100");
34 }
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 )
40 {
41 char buf[MAX_ERROR_BUF];
42 GLsizei length;
43 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
44 ERROR( "%s: %s", msg, buf );
45 }
47 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
48 {
49 GLint value;
51 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
52 if( value == 0 ) {
53 glsl_print_error(msg, obj);
54 return FALSE;
55 }
56 return TRUE;
57 }
59 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
60 {
61 if( glGetError() != GL_NO_ERROR ) {
62 glsl_print_error(msg, obj);
63 }
64 return TRUE;
65 }
68 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
69 {
70 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
72 if( vertex_src == NULL && fragment_src == NULL ) {
73 return TRUE; // nothing to do
74 }
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);
83 }
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);
89 }
91 if( vsok && fsok ) {
92 if( vertex_src != NULL ) {
93 glAttachObjectARB(glsl_program, glsl_vert_shader);
94 }
95 if( fragment_src != NULL ) {
96 glAttachObjectARB(glsl_program, glsl_frag_shader);
97 }
98 glLinkProgramARB(glsl_program);
99 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
100 }
101 if( pok ) {
102 glUseProgramObjectARB(glsl_program);
103 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
104 } else {
105 glsl_unload_shaders();
106 }
107 return pok;
108 }
110 void glsl_enable_shader(gboolean en)
111 {
112 if( glsl_program != 0 ) {
113 if( en ) {
114 glUseProgramObjectARB(glsl_program);
115 } else {
116 glUseProgramObjectARB(0);
117 }
118 }
119 }
121 void glsl_unload_shaders(void)
122 {
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);
129 }
131 #else
132 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
134 gboolean glsl_check_shader_error( char *msg, GLuint shader )
135 {
136 GLint value;
138 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
139 if( value == 0 ) {
140 char buf[MAX_ERROR_BUF];
141 GLsizei length;
142 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
143 ERROR( "%s: %s", msg, buf );
144 return FALSE;
145 }
146 return TRUE;
147 }
148 gboolean glsl_check_program_error( char *msg, GLuint program )
149 {
150 if( glGetError() != GL_NO_ERROR ) {
151 char buf[MAX_ERROR_BUF];
152 GLsizei length;
153 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
154 ERROR( "%s: %s", msg, buf );
155 return FALSE;
156 }
157 return TRUE;
158 }
160 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
161 {
162 gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
164 if( vertex_src == NULL && fragment_src == NULL ) {
165 return TRUE;
166 }
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 );
175 }
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 );
181 }
183 if( vsok && fsok ) {
184 if( vertex_src != NULL ) {
185 glAttachShader(glsl_program, glsl_vert_shader);
186 }
187 if( fragment_src != NULL ) {
188 glAttachShader(glsl_program, glsl_frag_shader);
189 }
190 glLinkProgram(glsl_program);
191 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
192 }
194 if( pok ) {
195 glUseProgram(glsl_program);
196 } else {
197 glsl_unload_shaders();
198 }
199 return pok;
200 }
203 void glsl_enable_shader(gboolean en)
204 {
205 if( glsl_program != 0 ) {
206 if( en ) {
207 glUseProgram(glsl_program);
208 } else {
209 glUseProgram(0);
210 }
211 }
212 }
214 void glsl_unload_shaders(void)
215 {
216 glUseProgram(0);
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);
222 }
223 #endif
.