2 * Utilities for OpenGL shading language
15 #include "shaderutil.h"
19 ShadersSupported(void)
21 const char *version
= (const char *) glGetString(GL_VERSION
);
22 if (version
[0] == '2' && version
[1] == '.') {
25 else if (glutExtensionSupported("GL_ARB_vertex_shader")
26 && glutExtensionSupported("GL_ARB_fragment_shader")
27 && glutExtensionSupported("GL_ARB_shader_objects")) {
28 fprintf(stderr
, "Warning: Trying ARB GLSL instead of OpenGL 2.x. This may not work.\n");
36 CompileShaderText(GLenum shaderType
, const char *text
)
41 shader
= glCreateShader(shaderType
);
42 glShaderSource(shader
, 1, (const GLchar
**) &text
, NULL
);
43 glCompileShader(shader
);
44 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &stat
);
48 glGetShaderInfoLog(shader
, 1000, &len
, log
);
49 fprintf(stderr
, "Error: problem compiling shader: %s\n", log
);
53 /*printf("Shader compiled OK\n");*/
60 * Read a shader from a file.
63 CompileShaderFile(GLenum shaderType
, const char *filename
)
65 const int max
= 100*1000;
67 char *buffer
= (char*) malloc(max
);
71 f
= fopen(filename
, "r");
73 fprintf(stderr
, "Unable to open shader file %s\n", filename
);
77 n
= fread(buffer
, 1, max
, f
);
78 /*printf("read %d bytes from shader file %s\n", n, filename);*/
81 shader
= CompileShaderText(shaderType
, buffer
);
95 LinkShaders(GLuint vertShader
, GLuint fragShader
)
97 GLuint program
= glCreateProgram();
99 assert(vertShader
|| fragShader
);
102 glAttachShader(program
, fragShader
);
104 glAttachShader(program
, vertShader
);
105 glLinkProgram(program
);
110 glGetProgramiv(program
, GL_LINK_STATUS
, &stat
);
114 glGetProgramInfoLog(program
, 1000, &len
, log
);
115 fprintf(stderr
, "Shader link error:\n%s\n", log
);
125 SetUniformValues(GLuint program
, struct uniform_info uniforms
[])
129 for (i
= 0; uniforms
[i
].name
; i
++) {
131 = glGetUniformLocation(program
, uniforms
[i
].name
);
133 switch (uniforms
[i
].type
) {
138 case GL_SAMPLER_CUBE
:
139 case GL_SAMPLER_2D_RECT_ARB
:
140 glUniform1i(uniforms
[i
].location
,
141 (GLint
) uniforms
[i
].value
[0]);
144 glUniform1fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
147 glUniform2fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
150 glUniform3fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
153 glUniform4fv(uniforms
[i
].location
, 1, uniforms
[i
].value
);
156 if (strncmp(uniforms
[i
].name
, "gl_", 3) == 0) {
157 /* built-in uniform: ignore */
161 "Unexpected uniform data type in SetUniformValues\n");
169 /** Get list of uniforms used in the program */
171 GetUniforms(GLuint program
, struct uniform_info uniforms
[])
175 glGetProgramiv(program
, GL_ACTIVE_UNIFORMS
, &n
);
176 glGetProgramiv(program
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, &max
);
178 for (i
= 0; i
< n
; i
++) {
183 glGetActiveUniform(program
, i
, 100, &len
, &size
, &type
, name
);
185 uniforms
[i
].name
= strdup(name
);
186 uniforms
[i
].size
= size
;
187 uniforms
[i
].type
= type
;
188 uniforms
[i
].location
= glGetUniformLocation(program
, name
);
191 uniforms
[i
].name
= NULL
; /* end of list */
198 PrintUniforms(const struct uniform_info uniforms
[])
202 printf("Uniforms:\n");
204 for (i
= 0; uniforms
[i
].name
; i
++) {
205 printf(" %d: %s size=%d type=0x%x loc=%d value=%g, %g, %g, %g\n",
210 uniforms
[i
].location
,
211 uniforms
[i
].value
[0],
212 uniforms
[i
].value
[1],
213 uniforms
[i
].value
[2],
214 uniforms
[i
].value
[3]);
219 /** Get list of attribs used in the program */
221 GetAttribs(GLuint program
, struct attrib_info attribs
[])
225 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTES
, &n
);
226 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, &max
);
228 for (i
= 0; i
< n
; i
++) {
233 glGetActiveAttrib(program
, i
, 100, &len
, &size
, &type
, name
);
235 attribs
[i
].name
= strdup(name
);
236 attribs
[i
].size
= size
;
237 attribs
[i
].type
= type
;
238 attribs
[i
].location
= glGetAttribLocation(program
, name
);
241 attribs
[i
].name
= NULL
; /* end of list */
248 PrintAttribs(const struct attrib_info attribs
[])
252 printf("Attribs:\n");
254 for (i
= 0; attribs
[i
].name
; i
++) {
255 printf(" %d: %s size=%d type=0x%x loc=%d\n",
260 attribs
[i
].location
);