filename | src/drivers/gl_sl.c |
changeset | 477:9a373f2ff009 |
prev | 424:421d68e78c46 |
next | 538:7f176617a968 |
author | nkeynes |
date | Sat Nov 17 01:18:09 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Move the failing TA tests into a separate file for now - there's a bug about these already (basically error handling behaviour) |
view | annotate | diff | log | raw |
1 /**
2 * $Id: gl_sl.c,v 1.3 2007-10-31 09:10:23 nkeynes Exp $
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 <GL/gl.h>
24 #include <GL/glext.h>
25 #include "lxdream.h"
26 #include "drivers/gl_common.h"
27 #include "display.h"
29 #define MAX_ERROR_BUF 4096
31 static GLuint glsl_program, glsl_vert_shader, glsl_frag_shader;
33 gboolean glsl_is_supported()
34 {
35 return isGLExtensionSupported("GL_ARB_fragment_shader") &&
36 isGLExtensionSupported("GL_ARB_vertex_shader") &&
37 isGLExtensionSupported("GL_ARB_shading_language_100");
38 }
40 #ifdef GL_ARB_shader_objects
41 void glsl_print_error( char *msg, GLhandleARB obj )
42 {
43 char buf[MAX_ERROR_BUF];
44 GLsizei length;
45 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
46 ERROR( "%s: %s", msg, buf );
47 }
49 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
50 {
51 GLint value;
53 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
54 if( value == 0 ) {
55 glsl_print_error(msg, obj);
56 return FALSE;
57 }
58 return TRUE;
59 }
61 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
62 {
63 if( glGetError() != GL_NO_ERROR ) {
64 glsl_print_error(msg, obj);
65 }
66 return TRUE;
67 }
70 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
71 {
72 gboolean vsok, fsok, pok = FALSE;
73 glsl_program = glCreateProgramObjectARB();
75 glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
76 glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
77 glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
78 glCompileShaderARB(glsl_vert_shader);
79 vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
80 glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
81 glCompileShaderARB(glsl_frag_shader);
82 fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
84 if( vsok && fsok ) {
85 glAttachObjectARB(glsl_program, glsl_vert_shader);
86 glAttachObjectARB(glsl_program, glsl_frag_shader);
87 glLinkProgramARB(glsl_program);
88 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
89 }
90 if( pok ) {
91 glUseProgramObjectARB(glsl_program);
92 pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
93 } else {
94 glsl_unload_shaders();
95 }
96 return pok;
97 }
99 void glsl_unload_shaders(void)
100 {
101 glUseProgramObjectARB(0);
102 glDetachObjectARB(glsl_program, glsl_vert_shader);
103 glDetachObjectARB(glsl_program, glsl_frag_shader);
104 glDeleteObjectARB(glsl_program);
105 glDeleteObjectARB(glsl_vert_shader);
106 glDeleteObjectARB(glsl_frag_shader);
107 }
109 #else
110 gboolean glsl_check_shader_error( char *msg, GLuint shader )
111 {
112 GLint value;
114 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
115 if( value == 0 ) {
116 char buf[MAX_ERROR_BUF];
117 GLsizei length;
118 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
119 ERROR( "%s: %s", msg, buf );
120 return FALSE;
121 }
122 return TRUE;
123 }
124 gboolean glsl_check_program_error( char *msg, GLuint program )
125 {
126 if( glGetError() != GL_NO_ERROR ) {
127 char buf[MAX_ERROR_BUF];
128 GLsizei length;
129 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
130 ERROR( "%s: %s", msg, buf );
131 return FALSE;
132 }
133 return TRUE;
134 }
136 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
137 {
138 gboolean vsok, fsok, pok = FALSE;
139 glsl_program = glCreateProgram();
140 glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
141 glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
142 glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
143 glCompileShader(glsl_vert_shader);
144 vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
145 glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
146 glCompileShader(glsl_frag_shader);
147 fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
149 if( vsok && fsok ) {
150 glAttachShader(glsl_program, glsl_vert_shader);
151 glAttachShader(glsl_program, glsl_frag_shader);
152 glLinkProgram(glsl_program);
153 pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
154 }
156 if( pok ) {
157 glUseProgram(glsl_program);
158 } else {
159 glsl_unload_shaders();
160 }
161 return pok;
162 }
164 void glsl_unload_shaders(void)
165 {
166 glUseProgram(0);
167 glDetachShader(glsl_program, glsl_vert_shader);
168 glDetachShader(glsl_program, glsl_frag_shader);
169 glDeleteProgram(glsl_program);
170 glDeleteShader(glsl_vert_shader);
171 glDeleteShader(glsl_frag_shader);
172 }
173 #endif
.