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