Update .gitignore for progs/glsl
[mesa.git] / progs / glsl / bump.c
1 /**
2 * Procedural Bump Mapping 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/glut.h>
13 #include <GL/glu.h>
14 #include <GL/glext.h>
15 #include "extfuncs.h"
16 #include "shaderutil.h"
17
18
19 static char *FragProgFile = "CH11-bumpmap.frag.txt";
20 static char *VertProgFile = "CH11-bumpmap.vert.txt";
21
22 /* program/shader objects */
23 static GLuint fragShader;
24 static GLuint vertShader;
25 static GLuint program;
26
27
28 static struct uniform_info Uniforms[] = {
29 { "LightPosition", 3, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
30 { "SurfaceColor", 3, GL_FLOAT, { 0.8, 0.8, 0.2, 0 }, -1 },
31 { "BumpDensity", 1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 },
32 { "BumpSize", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
33 { "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
34 END_OF_UNIFORMS
35 };
36
37 static GLint win = 0;
38
39 static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
40
41 static GLuint tangentAttrib;
42
43 static GLboolean Anim = GL_FALSE;
44
45
46 static void
47 CheckError(int line)
48 {
49 GLenum err = glGetError();
50 if (err) {
51 printf("GL Error %s (0x%x) at line %d\n",
52 gluErrorString(err), (int) err, line);
53 }
54 }
55
56 /*
57 * Draw a square, specifying normal and tangent vectors.
58 */
59 static void
60 Square(GLfloat size)
61 {
62 glNormal3f(0, 0, 1);
63 glVertexAttrib3f_func(tangentAttrib, 1, 0, 0);
64 glBegin(GL_POLYGON);
65 glTexCoord2f(0, 0); glVertex2f(-size, -size);
66 glTexCoord2f(1, 0); glVertex2f( size, -size);
67 glTexCoord2f(1, 1); glVertex2f( size, size);
68 glTexCoord2f(0, 1); glVertex2f(-size, size);
69 glEnd();
70 }
71
72
73 static void
74 Cube(GLfloat size)
75 {
76 /* +X */
77 glPushMatrix();
78 glRotatef(90, 0, 1, 0);
79 glTranslatef(0, 0, size);
80 Square(size);
81 glPopMatrix();
82
83 /* -X */
84 glPushMatrix();
85 glRotatef(-90, 0, 1, 0);
86 glTranslatef(0, 0, size);
87 Square(size);
88 glPopMatrix();
89
90 /* +Y */
91 glPushMatrix();
92 glRotatef(90, 1, 0, 0);
93 glTranslatef(0, 0, size);
94 Square(size);
95 glPopMatrix();
96
97 /* -Y */
98 glPushMatrix();
99 glRotatef(-90, 1, 0, 0);
100 glTranslatef(0, 0, size);
101 Square(size);
102 glPopMatrix();
103
104
105 /* +Z */
106 glPushMatrix();
107 glTranslatef(0, 0, size);
108 Square(size);
109 glPopMatrix();
110
111 /* -Z */
112 glPushMatrix();
113 glRotatef(180, 0, 1, 0);
114 glTranslatef(0, 0, size);
115 Square(size);
116 glPopMatrix();
117
118 }
119
120
121 static void
122 Idle(void)
123 {
124 GLint t = glutGet(GLUT_ELAPSED_TIME);
125 yRot = t * 0.05;
126 glutPostRedisplay();
127 }
128
129
130 static void
131 Redisplay(void)
132 {
133 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
134
135 glPushMatrix();
136 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
137 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
138 glRotatef(zRot, 0.0f, 0.0f, 1.0f);
139
140 Cube(1.5);
141
142 glPopMatrix();
143
144 glFinish();
145 glFlush();
146
147 CheckError(__LINE__);
148
149 glutSwapBuffers();
150 }
151
152
153 static void
154 Reshape(int width, int height)
155 {
156 glViewport(0, 0, width, height);
157 glMatrixMode(GL_PROJECTION);
158 glLoadIdentity();
159 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
160 glMatrixMode(GL_MODELVIEW);
161 glLoadIdentity();
162 glTranslatef(0.0f, 0.0f, -15.0f);
163 }
164
165
166 static void
167 CleanUp(void)
168 {
169 glDeleteShader_func(fragShader);
170 glDeleteShader_func(vertShader);
171 glDeleteProgram_func(program);
172 glutDestroyWindow(win);
173 }
174
175
176 static void
177 Key(unsigned char key, int x, int y)
178 {
179 const GLfloat step = 2.0;
180 (void) x;
181 (void) y;
182
183 switch(key) {
184 case 'a':
185 Anim = !Anim;
186 glutIdleFunc(Anim ? Idle : NULL);
187 break;
188 case 'z':
189 zRot += step;
190 break;
191 case 'Z':
192 zRot -= step;
193 break;
194 case 27:
195 CleanUp();
196 exit(0);
197 break;
198 }
199 glutPostRedisplay();
200 }
201
202
203 static void
204 SpecialKey(int key, int x, int y)
205 {
206 const GLfloat step = 2.0;
207
208 (void) x;
209 (void) y;
210
211 switch(key) {
212 case GLUT_KEY_UP:
213 xRot += step;
214 break;
215 case GLUT_KEY_DOWN:
216 xRot -= step;
217 break;
218 case GLUT_KEY_LEFT:
219 yRot -= step;
220 break;
221 case GLUT_KEY_RIGHT:
222 yRot += step;
223 break;
224 }
225 glutPostRedisplay();
226 }
227
228
229 static void
230 Init(void)
231 {
232 if (!ShadersSupported())
233 exit(1);
234
235 GetExtensionFuncs();
236
237 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
238 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
239 program = LinkShaders(vertShader, fragShader);
240
241 glUseProgram_func(program);
242
243 assert(glIsProgram_func(program));
244 assert(glIsShader_func(fragShader));
245 assert(glIsShader_func(vertShader));
246
247 assert(glGetError() == 0);
248
249 CheckError(__LINE__);
250
251 InitUniforms(program, Uniforms);
252
253 CheckError(__LINE__);
254
255 tangentAttrib = glGetAttribLocation_func(program, "Tangent");
256 printf("Tangent Attrib: %d\n", tangentAttrib);
257
258 assert(tangentAttrib >= 0);
259
260 CheckError(__LINE__);
261
262 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
263
264 glEnable(GL_DEPTH_TEST);
265
266 glColor3f(1, 0, 0);
267 }
268
269
270 static void
271 ParseOptions(int argc, char *argv[])
272 {
273 int i;
274 for (i = 1; i < argc; i++) {
275 if (strcmp(argv[i], "-fs") == 0) {
276 FragProgFile = argv[i+1];
277 }
278 else if (strcmp(argv[i], "-vs") == 0) {
279 VertProgFile = argv[i+1];
280 }
281 }
282 }
283
284
285 int
286 main(int argc, char *argv[])
287 {
288 glutInit(&argc, argv);
289 glutInitWindowPosition( 0, 0);
290 glutInitWindowSize(400, 400);
291 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
292 win = glutCreateWindow(argv[0]);
293 glutReshapeFunc(Reshape);
294 glutKeyboardFunc(Key);
295 glutSpecialFunc(SpecialKey);
296 glutDisplayFunc(Redisplay);
297 ParseOptions(argc, argv);
298 Init();
299 glutMainLoop();
300 return 0;
301 }
302