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