get rid of unused span->start field
[mesa.git] / progs / glsl / toyball.c
1 /**
2 * "Toy Ball" shader demo. Uses the example shaders from
3 * chapter 11 of the OpenGL Shading Language "orange" book.
4 * 16 Jan 2007
5 */
6
7 #include <assert.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 #include <GL/gl.h>
13 #include <GL/glut.h>
14 #include <GL/glext.h>
15 #include "extfuncs.h"
16
17
18 static char *FragProgFile = "CH11-toyball.frag.txt";
19 static char *VertProgFile = "CH11-toyball.vert.txt";
20
21 /* program/shader objects */
22 static GLuint fragShader;
23 static GLuint vertShader;
24 static GLuint program;
25
26
27 struct uniform_info {
28 const char *name;
29 GLuint size;
30 GLint location;
31 GLfloat value[4];
32 };
33
34 static struct uniform_info Uniforms[] = {
35 { "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
36 { "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } },
37 { "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } },
38 { "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } },
39 { "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } },
40 { "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } },
41 { "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } },
42 { "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } },
43 { "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } },
44 { "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } },
45 { "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } },
46 { "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } },
47 { "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } },
48 { "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } },
49 { "FWidth", 1, -1, { 0.005, 0, 0, 0 } },
50 { NULL, 0, 0, { 0, 0, 0, 0 } }
51 };
52
53 static GLint win = 0;
54
55 static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
56
57
58 static void
59 Redisplay(void)
60 {
61 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
62
63 glPushMatrix();
64 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
65 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
66 glRotatef(zRot, 0.0f, 0.0f, 1.0f);
67
68 glutSolidSphere(2.0, 20, 10);
69
70 glPopMatrix();
71
72 glFinish();
73 glFlush();
74 glutSwapBuffers();
75 }
76
77
78 static void
79 Reshape(int width, int height)
80 {
81 glViewport(0, 0, width, height);
82 glMatrixMode(GL_PROJECTION);
83 glLoadIdentity();
84 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
85 glMatrixMode(GL_MODELVIEW);
86 glLoadIdentity();
87 glTranslatef(0.0f, 0.0f, -15.0f);
88 }
89
90
91 static void
92 CleanUp(void)
93 {
94 glDeleteShader_func(fragShader);
95 glDeleteShader_func(vertShader);
96 glDeleteProgram_func(program);
97 glutDestroyWindow(win);
98 }
99
100
101 static void
102 Key(unsigned char key, int x, int y)
103 {
104 const GLfloat step = 2.0;
105 (void) x;
106 (void) y;
107
108 switch(key) {
109 case 'z':
110 zRot += step;
111 break;
112 case 'Z':
113 zRot -= step;
114 break;
115 case 27:
116 CleanUp();
117 exit(0);
118 break;
119 }
120 glutPostRedisplay();
121 }
122
123
124 static void
125 SpecialKey(int key, int x, int y)
126 {
127 const GLfloat step = 2.0;
128
129 (void) x;
130 (void) y;
131
132 switch(key) {
133 case GLUT_KEY_UP:
134 xRot += step;
135 break;
136 case GLUT_KEY_DOWN:
137 xRot -= step;
138 break;
139 case GLUT_KEY_LEFT:
140 yRot -= step;
141 break;
142 case GLUT_KEY_RIGHT:
143 yRot += step;
144 break;
145 }
146 glutPostRedisplay();
147 }
148
149
150
151 static void
152 LoadAndCompileShader(GLuint shader, const char *text)
153 {
154 GLint stat;
155
156 glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
157
158 glCompileShader_func(shader);
159
160 glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
161 if (!stat) {
162 GLchar log[1000];
163 GLsizei len;
164 glGetShaderInfoLog_func(shader, 1000, &len, log);
165 fprintf(stderr, "brick: problem compiling shader: %s\n", log);
166 exit(1);
167 }
168 else {
169 printf("Shader compiled OK\n");
170 }
171 }
172
173
174 /**
175 * Read a shader from a file.
176 */
177 static void
178 ReadShader(GLuint shader, const char *filename)
179 {
180 const int max = 100*1000;
181 int n;
182 char *buffer = (char*) malloc(max);
183 FILE *f = fopen(filename, "r");
184 if (!f) {
185 fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
186 exit(1);
187 }
188
189 n = fread(buffer, 1, max, f);
190 printf("brick: read %d bytes from shader file %s\n", n, filename);
191 if (n > 0) {
192 buffer[n] = 0;
193 LoadAndCompileShader(shader, buffer);
194 }
195
196 fclose(f);
197 free(buffer);
198 }
199
200
201 static void
202 CheckLink(GLuint prog)
203 {
204 GLint stat;
205 glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
206 if (!stat) {
207 GLchar log[1000];
208 GLsizei len;
209 glGetProgramInfoLog_func(prog, 1000, &len, log);
210 fprintf(stderr, "Linker error:\n%s\n", log);
211 }
212 else {
213 fprintf(stderr, "Link success!\n");
214 }
215 }
216
217
218 static void
219 Init(void)
220 {
221 const char *version;
222 GLint i;
223
224 version = (const char *) glGetString(GL_VERSION);
225 if (version[0] != '2' || version[1] != '.') {
226 printf("Warning: this program expects OpenGL 2.0\n");
227 /*exit(1);*/
228 }
229 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
230
231 GetExtensionFuncs();
232
233 vertShader = glCreateShader_func(GL_VERTEX_SHADER);
234 ReadShader(vertShader, VertProgFile);
235
236 fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
237 ReadShader(fragShader, FragProgFile);
238
239 program = glCreateProgram_func();
240 glAttachShader_func(program, fragShader);
241 glAttachShader_func(program, vertShader);
242 glLinkProgram_func(program);
243 CheckLink(program);
244 glUseProgram_func(program);
245
246 assert(glIsProgram_func(program));
247 assert(glIsShader_func(fragShader));
248 assert(glIsShader_func(vertShader));
249
250
251 for (i = 0; Uniforms[i].name; i++) {
252 Uniforms[i].location
253 = glGetUniformLocation_func(program, Uniforms[i].name);
254 printf("Uniform %s location: %d\n", Uniforms[i].name,
255 Uniforms[i].location);
256 switch (Uniforms[i].size) {
257 case 1:
258 glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
259 break;
260 case 2:
261 glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
262 break;
263 case 3:
264 glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
265 break;
266 case 4:
267 glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
268 break;
269 default:
270 abort();
271 }
272 }
273
274 assert(glGetError() == 0);
275
276 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
277
278 glEnable(GL_DEPTH_TEST);
279
280 glColor3f(1, 0, 0);
281 }
282
283
284 static void
285 ParseOptions(int argc, char *argv[])
286 {
287 int i;
288 for (i = 1; i < argc; i++) {
289 if (strcmp(argv[i], "-fs") == 0) {
290 FragProgFile = argv[i+1];
291 }
292 else if (strcmp(argv[i], "-vs") == 0) {
293 VertProgFile = argv[i+1];
294 }
295 }
296 }
297
298
299 int
300 main(int argc, char *argv[])
301 {
302 glutInit(&argc, argv);
303 glutInitWindowPosition( 0, 0);
304 glutInitWindowSize(400, 400);
305 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
306 win = glutCreateWindow(argv[0]);
307 glutReshapeFunc(Reshape);
308 glutKeyboardFunc(Key);
309 glutSpecialFunc(SpecialKey);
310 glutDisplayFunc(Redisplay);
311 ParseOptions(argc, argv);
312 Init();
313 glutMainLoop();
314 return 0;
315 }
316