blob: 0ea1f8331ff3cbcc82e1529f041b5b27a22981f5 [file] [log] [blame]
Brianf44ba112007-01-16 14:55:43 -07001/**
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"
Brian2dca3372008-04-09 22:28:23 -060016#include "shaderutil.h"
Brianf44ba112007-01-16 14:55:43 -070017
18
Brian Paulc0dd9122008-08-16 09:36:46 -060019static char *FragProgFile = "CH11-bumpmap.frag";
20static char *VertProgFile = "CH11-bumpmap.vert";
Brianf44ba112007-01-16 14:55:43 -070021
22/* program/shader objects */
23static GLuint fragShader;
24static GLuint vertShader;
25static GLuint program;
26
27
Brianf44ba112007-01-16 14:55:43 -070028static struct uniform_info Uniforms[] = {
Brian2dca3372008-04-09 22:28:23 -060029 { "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
Brianf44ba112007-01-16 14:55:43 -070035};
36
37static GLint win = 0;
38
Brian271d5042007-01-16 15:27:11 -070039static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
Brianf44ba112007-01-16 14:55:43 -070040
41static GLuint tangentAttrib;
42
Brian271d5042007-01-16 15:27:11 -070043static GLboolean Anim = GL_FALSE;
44
Brianf44ba112007-01-16 14:55:43 -070045
46static void
47CheckError(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 */
59static void
60Square(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
73static void
Brian271d5042007-01-16 15:27:11 -070074Cube(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
121static void
122Idle(void)
123{
124 GLint t = glutGet(GLUT_ELAPSED_TIME);
125 yRot = t * 0.05;
126 glutPostRedisplay();
127}
128
129
130static void
Brianf44ba112007-01-16 14:55:43 -0700131Redisplay(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
Brian271d5042007-01-16 15:27:11 -0700140 Cube(1.5);
Brianf44ba112007-01-16 14:55:43 -0700141
142 glPopMatrix();
143
Brianf44ba112007-01-16 14:55:43 -0700144 CheckError(__LINE__);
145
146 glutSwapBuffers();
147}
148
149
150static void
151Reshape(int width, int height)
152{
Brian Paul08a1e1e2009-04-09 17:04:58 -0600153 float ar = (float) width / (float) height;
Brianf44ba112007-01-16 14:55:43 -0700154 glViewport(0, 0, width, height);
155 glMatrixMode(GL_PROJECTION);
156 glLoadIdentity();
Brian Paul08a1e1e2009-04-09 17:04:58 -0600157 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
Brianf44ba112007-01-16 14:55:43 -0700158 glMatrixMode(GL_MODELVIEW);
159 glLoadIdentity();
160 glTranslatef(0.0f, 0.0f, -15.0f);
161}
162
163
164static void
165CleanUp(void)
166{
167 glDeleteShader_func(fragShader);
168 glDeleteShader_func(vertShader);
169 glDeleteProgram_func(program);
170 glutDestroyWindow(win);
171}
172
173
174static void
175Key(unsigned char key, int x, int y)
176{
177 const GLfloat step = 2.0;
178 (void) x;
179 (void) y;
180
181 switch(key) {
Brian271d5042007-01-16 15:27:11 -0700182 case 'a':
183 Anim = !Anim;
184 glutIdleFunc(Anim ? Idle : NULL);
185 break;
Brianf44ba112007-01-16 14:55:43 -0700186 case 'z':
187 zRot += step;
188 break;
189 case 'Z':
190 zRot -= step;
191 break;
192 case 27:
193 CleanUp();
194 exit(0);
195 break;
196 }
197 glutPostRedisplay();
198}
199
200
201static void
202SpecialKey(int key, int x, int y)
203{
204 const GLfloat step = 2.0;
205
206 (void) x;
207 (void) y;
208
209 switch(key) {
210 case GLUT_KEY_UP:
211 xRot += step;
212 break;
213 case GLUT_KEY_DOWN:
214 xRot -= step;
215 break;
216 case GLUT_KEY_LEFT:
217 yRot -= step;
218 break;
219 case GLUT_KEY_RIGHT:
220 yRot += step;
221 break;
222 }
223 glutPostRedisplay();
224}
225
226
Brianf44ba112007-01-16 14:55:43 -0700227static void
228Init(void)
229{
Brian2dca3372008-04-09 22:28:23 -0600230 if (!ShadersSupported())
231 exit(1);
Brianf44ba112007-01-16 14:55:43 -0700232
233 GetExtensionFuncs();
234
Brian2dca3372008-04-09 22:28:23 -0600235 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
236 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
237 program = LinkShaders(vertShader, fragShader);
Brianf44ba112007-01-16 14:55:43 -0700238
Brianf44ba112007-01-16 14:55:43 -0700239 glUseProgram_func(program);
240
241 assert(glIsProgram_func(program));
242 assert(glIsShader_func(fragShader));
243 assert(glIsShader_func(vertShader));
244
245 assert(glGetError() == 0);
246
247 CheckError(__LINE__);
248
Brian2dca3372008-04-09 22:28:23 -0600249 InitUniforms(program, Uniforms);
Brianf44ba112007-01-16 14:55:43 -0700250
251 CheckError(__LINE__);
252
253 tangentAttrib = glGetAttribLocation_func(program, "Tangent");
254 printf("Tangent Attrib: %d\n", tangentAttrib);
255
256 assert(tangentAttrib >= 0);
257
258 CheckError(__LINE__);
259
260 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
261
262 glEnable(GL_DEPTH_TEST);
263
264 glColor3f(1, 0, 0);
265}
266
267
268static void
269ParseOptions(int argc, char *argv[])
270{
271 int i;
272 for (i = 1; i < argc; i++) {
273 if (strcmp(argv[i], "-fs") == 0) {
274 FragProgFile = argv[i+1];
275 }
276 else if (strcmp(argv[i], "-vs") == 0) {
277 VertProgFile = argv[i+1];
278 }
279 }
280}
281
282
283int
284main(int argc, char *argv[])
285{
286 glutInit(&argc, argv);
287 glutInitWindowPosition( 0, 0);
288 glutInitWindowSize(400, 400);
289 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
290 win = glutCreateWindow(argv[0]);
291 glutReshapeFunc(Reshape);
292 glutKeyboardFunc(Key);
293 glutSpecialFunc(SpecialKey);
294 glutDisplayFunc(Redisplay);
295 ParseOptions(argc, argv);
296 Init();
297 glutMainLoop();
298 return 0;
299}
300