2 * Utilities for OpenGL shading language
15 #include "shaderutil.h"
17 /** time to compile previous shader */
18 static GLdouble CompileTime
= 0.0;
20 /** time to linke previous program */
21 static GLdouble LinkTime
= 0.0;
25 ShadersSupported(void)
27 const char *version
= (const char *) glGetString(GL_VERSION
);
29 /* NVIDIA binary drivers will return "3.0.0", and they clearly support
32 if (version
[0] >= '2' && version
[1] == '.') {
35 else if (glutExtensionSupported("GL_ARB_vertex_shader")
36 && glutExtensionSupported("GL_ARB_fragment_shader")
37 && glutExtensionSupported("GL_ARB_shader_objects")) {
38 fprintf(stderr
, "Warning: Trying ARB GLSL instead of OpenGL 2.x. This may not work.\n");
41 fprintf(stderr
, "Sorry, GLSL not supported with this OpenGL.\n");
47 CompileShaderText(GLenum shaderType
, const char *text
)
53 shader
= glCreateShader(shaderType
);
54 glShaderSource(shader
, 1, (const GLchar
**) &text
, NULL
);
56 t0
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
57 glCompileShader(shader
);
58 t1
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
60 CompileTime
= t1
- t0
;
62 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &stat
);
66 glGetShaderInfoLog(shader
, 1000, &len
, log
);
67 fprintf(stderr
, "Error: problem compiling shader: %s\n", log
);
71 /*printf("Shader compiled OK\n");*/
78 * Read a shader from a file.
81 CompileShaderFile(GLenum shaderType
, const char *filename
)
83 const int max
= 100*1000;
85 char *buffer
= (char*) malloc(max
);
89 f
= fopen(filename
, "r");
91 fprintf(stderr
, "Unable to open shader file %s\n", filename
);
96 n
= fread(buffer
, 1, max
, f
);
97 /*printf("read %d bytes from shader file %s\n", n, filename);*/
100 shader
= CompileShaderText(shaderType
, buffer
);
116 LinkShaders(GLuint vertShader
, GLuint fragShader
)
118 GLuint program
= glCreateProgram();
121 assert(vertShader
|| fragShader
);
124 glAttachShader(program
, fragShader
);
126 glAttachShader(program
, vertShader
);
128 t0
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
129 glLinkProgram(program
);
130 t1
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
137 glGetProgramiv(program
, GL_LINK_STATUS
, &stat
);
141 glGetProgramInfoLog(program
, 1000, &len
, log
);
142 fprintf(stderr
, "Shader link error:\n%s\n", log
);
152 ValidateShaderProgram(GLuint program
)
155 glValidateProgramARB(program
);
156 glGetProgramiv(program
, GL_VALIDATE_STATUS
, &stat
);
161 glGetProgramInfoLog(program
, 1000, &len
, log
);
162 fprintf(stderr
, "Program validation error:\n%s\n", log
);
166 return (GLboolean
) stat
;
171 GetShaderCompileTime(void)
178 GetShaderLinkTime(void)
185 SetUniformValues(GLuint program
, struct uniform_info uniforms
[])
189 for (i
= 0; uniforms
[i
].name
; i
++) {
191 = glGetUniformLocation(program
, uniforms
[i
].name
);
193 switch (uniforms
[i
].type
) {
198 case GL_SAMPLER_CUBE
:
199 case GL_SAMPLER_2D_RECT_ARB
:
200 assert(uniforms
[i
].value
[0] >= 0.0F
);
201 glUniform1i(uniforms
[i
].location
,
202 (GLint
) uniforms
[i
].value
[0]);
205 glUniform1fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
208 glUniform2fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
211 glUniform3fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
214 glUniform4fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
217 if (strncmp(uniforms
[i
].name
, "gl_", 3) == 0) {
218 /* built-in uniform: ignore */
222 "Unexpected uniform data type in SetUniformValues\n");
230 /** Get list of uniforms used in the program */
232 GetUniforms(GLuint program
, struct uniform_info uniforms
[])
236 glGetProgramiv(program
, GL_ACTIVE_UNIFORMS
, &n
);
237 glGetProgramiv(program
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, &max
);
239 for (i
= 0; i
< n
; i
++) {
244 glGetActiveUniform(program
, i
, 100, &len
, &size
, &type
, name
);
246 uniforms
[i
].name
= strdup(name
);
247 uniforms
[i
].size
= size
;
248 uniforms
[i
].type
= type
;
249 uniforms
[i
].location
= glGetUniformLocation(program
, name
);
252 uniforms
[i
].name
= NULL
; /* end of list */
259 PrintUniforms(const struct uniform_info uniforms
[])
263 printf("Uniforms:\n");
265 for (i
= 0; uniforms
[i
].name
; i
++) {
266 printf(" %d: %s size=%d type=0x%x loc=%d value=%g, %g, %g, %g\n",
271 uniforms
[i
].location
,
272 uniforms
[i
].value
[0],
273 uniforms
[i
].value
[1],
274 uniforms
[i
].value
[2],
275 uniforms
[i
].value
[3]);
280 /** Get list of attribs used in the program */
282 GetAttribs(GLuint program
, struct attrib_info attribs
[])
286 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTES
, &n
);
287 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, &max
);
289 for (i
= 0; i
< n
; i
++) {
294 glGetActiveAttrib(program
, i
, 100, &len
, &size
, &type
, name
);
296 attribs
[i
].name
= strdup(name
);
297 attribs
[i
].size
= size
;
298 attribs
[i
].type
= type
;
299 attribs
[i
].location
= glGetAttribLocation(program
, name
);
302 attribs
[i
].name
= NULL
; /* end of list */
309 PrintAttribs(const struct attrib_info attribs
[])
313 printf("Attribs:\n");
315 for (i
= 0; attribs
[i
].name
; i
++) {
316 printf(" %d: %s size=%d type=0x%x loc=%d\n",
321 attribs
[i
].location
);