blob: ddb986abcb54e9924abbbd7364cb32a1d7fd785d [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>
Brian Paulee0b1bc2009-07-17 13:23:11 -060012#include <GL/glew.h>
Brianf44ba112007-01-16 14:55:43 -070013#include <GL/glut.h>
Brian2dca3372008-04-09 22:28:23 -060014#include "shaderutil.h"
Brianf44ba112007-01-16 14:55:43 -070015
16
Brian Paulc0dd9122008-08-16 09:36:46 -060017static char *FragProgFile = "CH11-bumpmap.frag";
18static char *VertProgFile = "CH11-bumpmap.vert";
Brianf44ba112007-01-16 14:55:43 -070019
20/* program/shader objects */
21static GLuint fragShader;
22static GLuint vertShader;
23static GLuint program;
24
25
Brianf44ba112007-01-16 14:55:43 -070026static struct uniform_info Uniforms[] = {
Brian2dca3372008-04-09 22:28:23 -060027 { "LightPosition", 3, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
28 { "SurfaceColor", 3, GL_FLOAT, { 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
Brianf44ba112007-01-16 14:55:43 -070033};
34
35static GLint win = 0;
36
Brian271d5042007-01-16 15:27:11 -070037static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
Brianf44ba112007-01-16 14:55:43 -070038
39static GLuint tangentAttrib;
40
Brian271d5042007-01-16 15:27:11 -070041static GLboolean Anim = GL_FALSE;
42
Brianf44ba112007-01-16 14:55:43 -070043
44static void
45CheckError(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 */
57static void
58Square(GLfloat size)
59{
60 glNormal3f(0, 0, 1);
Brian Paulee0b1bc2009-07-17 13:23:11 -060061 glVertexAttrib3f(tangentAttrib, 1, 0, 0);
Brianf44ba112007-01-16 14:55:43 -070062 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
71static void
Brian271d5042007-01-16 15:27:11 -070072Cube(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
119static void
120Idle(void)
121{
122 GLint t = glutGet(GLUT_ELAPSED_TIME);
123 yRot = t * 0.05;
124 glutPostRedisplay();
125}
126
127
128static void
Brianf44ba112007-01-16 14:55:43 -0700129Redisplay(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
Brian271d5042007-01-16 15:27:11 -0700138 Cube(1.5);
Brianf44ba112007-01-16 14:55:43 -0700139
140 glPopMatrix();
141
Brianf44ba112007-01-16 14:55:43 -0700142 CheckError(__LINE__);
143
144 glutSwapBuffers();
145}
146
147
148static void
149Reshape(int width, int height)
150{
Brian Paul08a1e1e2009-04-09 17:04:58 -0600151 float ar = (float) width / (float) height;
Brianf44ba112007-01-16 14:55:43 -0700152 glViewport(0, 0, width, height);
153 glMatrixMode(GL_PROJECTION);
154 glLoadIdentity();
Brian Paul08a1e1e2009-04-09 17:04:58 -0600155 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
Brianf44ba112007-01-16 14:55:43 -0700156 glMatrixMode(GL_MODELVIEW);
157 glLoadIdentity();
158 glTranslatef(0.0f, 0.0f, -15.0f);
159}
160
161
162static void
163CleanUp(void)
164{
Brian Paulee0b1bc2009-07-17 13:23:11 -0600165 glDeleteShader(fragShader);
166 glDeleteShader(vertShader);
167 glDeleteProgram(program);
Brianf44ba112007-01-16 14:55:43 -0700168 glutDestroyWindow(win);
169}
170
171
172static void
173Key(unsigned char key, int x, int y)
174{
175 const GLfloat step = 2.0;
176 (void) x;
177 (void) y;
178
179 switch(key) {
Brian271d5042007-01-16 15:27:11 -0700180 case 'a':
181 Anim = !Anim;
182 glutIdleFunc(Anim ? Idle : NULL);
183 break;
Brianf44ba112007-01-16 14:55:43 -0700184 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
199static void
200SpecialKey(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
Brianf44ba112007-01-16 14:55:43 -0700225static void
226Init(void)
227{
Brian2dca3372008-04-09 22:28:23 -0600228 if (!ShadersSupported())
229 exit(1);
Brianf44ba112007-01-16 14:55:43 -0700230
Brian2dca3372008-04-09 22:28:23 -0600231 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
232 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
233 program = LinkShaders(vertShader, fragShader);
Brianf44ba112007-01-16 14:55:43 -0700234
Brian Paulee0b1bc2009-07-17 13:23:11 -0600235 glUseProgram(program);
Brianf44ba112007-01-16 14:55:43 -0700236
Brian Paulee0b1bc2009-07-17 13:23:11 -0600237 assert(glIsProgram(program));
238 assert(glIsShader(fragShader));
239 assert(glIsShader(vertShader));
Brianf44ba112007-01-16 14:55:43 -0700240
241 assert(glGetError() == 0);
242
243 CheckError(__LINE__);
244
Brian2dca3372008-04-09 22:28:23 -0600245 InitUniforms(program, Uniforms);
Brianf44ba112007-01-16 14:55:43 -0700246
247 CheckError(__LINE__);
248
Brian Paulee0b1bc2009-07-17 13:23:11 -0600249 tangentAttrib = glGetAttribLocation(program, "Tangent");
Brianf44ba112007-01-16 14:55:43 -0700250 printf("Tangent Attrib: %d\n", tangentAttrib);
251
252 assert(tangentAttrib >= 0);
253
254 CheckError(__LINE__);
255
256 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
257
258 glEnable(GL_DEPTH_TEST);
259
260 glColor3f(1, 0, 0);
261}
262
263
264static void
265ParseOptions(int argc, char *argv[])
266{
267 int i;
268 for (i = 1; i < argc; i++) {
269 if (strcmp(argv[i], "-fs") == 0) {
270 FragProgFile = argv[i+1];
271 }
272 else if (strcmp(argv[i], "-vs") == 0) {
273 VertProgFile = argv[i+1];
274 }
275 }
276}
277
278
279int
280main(int argc, char *argv[])
281{
282 glutInit(&argc, argv);
283 glutInitWindowPosition( 0, 0);
284 glutInitWindowSize(400, 400);
285 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
286 win = glutCreateWindow(argv[0]);
Keith Whitwellb799af92009-06-29 14:13:58 +0100287 glewInit();
Brianf44ba112007-01-16 14:55:43 -0700288 glutReshapeFunc(Reshape);
289 glutKeyboardFunc(Key);
290 glutSpecialFunc(SpecialKey);
291 glutDisplayFunc(Redisplay);
292 ParseOptions(argc, argv);
293 Init();
294 glutMainLoop();
295 return 0;
296}
297