progs/util: make sure function pointers are initialized
[mesa.git] / progs / util / shaderutil.c
1 /**
2 * Utilities for OpenGL shading language
3 *
4 * Brian Paul
5 * 9 April 2008
6 */
7
8
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <GL/glew.h>
13 #include <GL/glut.h>
14 #include "extfuncs.h"
15 #include "shaderutil.h"
16
17
18 static void
19 Init(void)
20 {
21 static GLboolean firstCall = GL_TRUE;
22 if (firstCall) {
23 GetExtensionFuncs();
24 firstCall = GL_FALSE;
25 }
26 }
27
28
29 GLboolean
30 ShadersSupported(void)
31 {
32 const char *version = (const char *) glGetString(GL_VERSION);
33 if (version[0] == '2' && version[1] == '.') {
34 return GL_TRUE;
35 }
36 else if (glutExtensionSupported("GL_ARB_vertex_shader")
37 && glutExtensionSupported("GL_ARB_fragment_shader")
38 && glutExtensionSupported("GL_ARB_shader_objects")) {
39 fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x. This may not work.\n");
40 return GL_TRUE;
41 }
42 return GL_TRUE;
43 }
44
45
46 GLuint
47 CompileShaderText(GLenum shaderType, const char *text)
48 {
49 GLuint shader;
50 GLint stat;
51
52 Init();
53
54 shader = glCreateShader_func(shaderType);
55 glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
56 glCompileShader_func(shader);
57 glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
58 if (!stat) {
59 GLchar log[1000];
60 GLsizei len;
61 glGetShaderInfoLog_func(shader, 1000, &len, log);
62 fprintf(stderr, "Error: problem compiling shader: %s\n", log);
63 exit(1);
64 }
65 else {
66 /*printf("Shader compiled OK\n");*/
67 }
68 return shader;
69 }
70
71
72 /**
73 * Read a shader from a file.
74 */
75 GLuint
76 CompileShaderFile(GLenum shaderType, const char *filename)
77 {
78 const int max = 100*1000;
79 int n;
80 char *buffer = (char*) malloc(max);
81 GLuint shader;
82 FILE *f;
83
84 Init();
85
86
87 f = fopen(filename, "r");
88 if (!f) {
89 fprintf(stderr, "Unable to open shader file %s\n", filename);
90 return 0;
91 }
92
93 n = fread(buffer, 1, max, f);
94 /*printf("read %d bytes from shader file %s\n", n, filename);*/
95 if (n > 0) {
96 buffer[n] = 0;
97 shader = CompileShaderText(shaderType, buffer);
98 }
99 else {
100 return 0;
101 }
102
103 fclose(f);
104 free(buffer);
105
106 return shader;
107 }
108
109
110 GLuint
111 LinkShaders(GLuint vertShader, GLuint fragShader)
112 {
113 GLuint program = glCreateProgram_func();
114
115 assert(vertShader || fragShader);
116
117 if (fragShader)
118 glAttachShader_func(program, fragShader);
119 if (vertShader)
120 glAttachShader_func(program, vertShader);
121 glLinkProgram_func(program);
122
123 /* check link */
124 {
125 GLint stat;
126 glGetProgramiv_func(program, GL_LINK_STATUS, &stat);
127 if (!stat) {
128 GLchar log[1000];
129 GLsizei len;
130 glGetProgramInfoLog_func(program, 1000, &len, log);
131 fprintf(stderr, "Shader link error:\n%s\n", log);
132 return 0;
133 }
134 }
135
136 return program;
137 }
138
139
140 void
141 InitUniforms(GLuint program, struct uniform_info uniforms[])
142 {
143 GLuint i;
144
145 for (i = 0; uniforms[i].name; i++) {
146 uniforms[i].location
147 = glGetUniformLocation_func(program, uniforms[i].name);
148
149 printf("Uniform %s location: %d\n", uniforms[i].name,
150 uniforms[i].location);
151
152 switch (uniforms[i].size) {
153 case 1:
154 if (uniforms[i].type == GL_INT)
155 glUniform1i_func(uniforms[i].location,
156 (GLint) uniforms[i].value[0]);
157 else
158 glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value);
159 break;
160 case 2:
161 glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value);
162 break;
163 case 3:
164 glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value);
165 break;
166 case 4:
167 glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value);
168 break;
169 default:
170 abort();
171 }
172 }
173 }