2 * Procedural Bump Mapping demo. Uses the example shaders from
3 * chapter 11 of the OpenGL Shading Language "orange" book.
14 #include "shaderutil.h"
18 static char *FragProgFile
= "CH11-bumpmap.frag";
19 static char *FragTexProgFile
= "CH11-bumpmaptex.frag";
20 static char *VertProgFile
= "CH11-bumpmap.vert";
21 static char *TextureFile
= "../images/tile.rgb";
23 /* program/shader objects */
24 static GLuint fragShader
;
25 static GLuint fragTexShader
;
26 static GLuint vertShader
;
27 static GLuint program
;
28 static GLuint texProgram
;
31 static struct uniform_info Uniforms
[] = {
32 { "LightPosition", 1, GL_FLOAT_VEC3
, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
33 { "SurfaceColor", 1, GL_FLOAT_VEC3
, { 0.8, 0.8, 0.2, 0 }, -1 },
34 { "BumpDensity", 1, GL_FLOAT
, { 10.0, 0, 0, 0 }, -1 },
35 { "BumpSize", 1, GL_FLOAT
, { 0.125, 0, 0, 0 }, -1 },
36 { "SpecularFactor", 1, GL_FLOAT
, { 0.5, 0, 0, 0 }, -1 },
40 static struct uniform_info TexUniforms
[] = {
41 { "LightPosition", 1, GL_FLOAT_VEC3
, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
42 { "Tex", 1, GL_INT
, { 0, 0, 0, 0 }, -1 },
43 { "BumpDensity", 1, GL_FLOAT
, { 10.0, 0, 0, 0 }, -1 },
44 { "BumpSize", 1, GL_FLOAT
, { 0.125, 0, 0, 0 }, -1 },
45 { "SpecularFactor", 1, GL_FLOAT
, { 0.5, 0, 0, 0 }, -1 },
51 static GLfloat xRot
= 20.0f
, yRot
= 0.0f
, zRot
= 0.0f
;
53 static GLint tangentAttrib
;
54 static GLint tangentAttribTex
;
56 static GLuint Texture
;
58 static GLboolean Anim
= GL_FALSE
;
59 static GLboolean Textured
= GL_FALSE
;
65 GLenum err
= glGetError();
67 printf("GL Error %s (0x%x) at line %d\n",
68 gluErrorString(err
), (int) err
, line
);
73 * Draw a square, specifying normal and tangent vectors.
79 glVertexAttrib3f(tangentAttrib
, 1, 0, 0);
81 glTexCoord2f(0, 0); glVertex2f(-size
, -size
);
82 glTexCoord2f(1, 0); glVertex2f( size
, -size
);
83 glTexCoord2f(1, 1); glVertex2f( size
, size
);
84 glTexCoord2f(0, 1); glVertex2f(-size
, size
);
94 glRotatef(90, 0, 1, 0);
95 glTranslatef(0, 0, size
);
101 glRotatef(-90, 0, 1, 0);
102 glTranslatef(0, 0, size
);
108 glRotatef(90, 1, 0, 0);
109 glTranslatef(0, 0, size
);
115 glRotatef(-90, 1, 0, 0);
116 glTranslatef(0, 0, size
);
123 glTranslatef(0, 0, size
);
129 glRotatef(180, 0, 1, 0);
130 glTranslatef(0, 0, size
);
140 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
149 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
152 glRotatef(xRot
, 1.0f
, 0.0f
, 0.0f
);
153 glRotatef(yRot
, 0.0f
, 1.0f
, 0.0f
);
154 glRotatef(zRot
, 0.0f
, 0.0f
, 1.0f
);
157 glUseProgram(texProgram
);
159 glUseProgram(program
);
165 CheckError(__LINE__
);
172 Reshape(int width
, int height
)
174 float ar
= (float) width
/ (float) height
;
175 glViewport(0, 0, width
, height
);
176 glMatrixMode(GL_PROJECTION
);
178 glFrustum(-ar
, ar
, -1.0, 1.0, 5.0, 25.0);
179 glMatrixMode(GL_MODELVIEW
);
181 glTranslatef(0.0f
, 0.0f
, -15.0f
);
188 glDeleteShader(fragShader
);
189 glDeleteShader(fragTexShader
);
190 glDeleteShader(vertShader
);
191 glDeleteProgram(program
);
192 glDeleteProgram(texProgram
);
193 glutDestroyWindow(win
);
198 Key(unsigned char key
, int x
, int y
)
200 const GLfloat step
= 2.0;
207 glutIdleFunc(Anim
? Idle
: NULL
);
210 Textured
= !Textured
;
228 SpecialKey(int key
, int x
, int y
)
230 const GLfloat step
= 2.0;
256 if (!ShadersSupported())
259 vertShader
= CompileShaderFile(GL_VERTEX_SHADER
, VertProgFile
);
260 fragShader
= CompileShaderFile(GL_FRAGMENT_SHADER
, FragProgFile
);
261 program
= LinkShaders(vertShader
, fragShader
);
263 glUseProgram(program
);
265 assert(glIsProgram(program
));
266 assert(glIsShader(fragShader
));
267 assert(glIsShader(vertShader
));
269 assert(glGetError() == 0);
271 CheckError(__LINE__
);
273 SetUniformValues(program
, Uniforms
);
274 PrintUniforms(Uniforms
);
276 CheckError(__LINE__
);
278 tangentAttrib
= glGetAttribLocation(program
, "Tangent");
279 printf("Tangent Attrib: %d\n", tangentAttrib
);
281 assert(tangentAttrib
>= 0);
283 CheckError(__LINE__
);
287 * As above, but fragment shader also uses a texture map.
289 fragTexShader
= CompileShaderFile(GL_FRAGMENT_SHADER
, FragTexProgFile
);
290 texProgram
= LinkShaders(vertShader
, fragTexShader
);
291 glUseProgram(texProgram
);
292 assert(glIsProgram(texProgram
));
293 assert(glIsShader(fragTexShader
));
294 SetUniformValues(texProgram
, TexUniforms
);
295 PrintUniforms(TexUniforms
);
300 glGenTextures(1, &Texture
);
301 glBindTexture(GL_TEXTURE_2D
, Texture
);
302 LoadRGBMipmaps(TextureFile
, GL_RGB
);
305 glClearColor(0.4f
, 0.4f
, 0.8f
, 0.0f
);
307 glEnable(GL_DEPTH_TEST
);
314 ParseOptions(int argc
, char *argv
[])
317 for (i
= 1; i
< argc
; i
++) {
318 if (strcmp(argv
[i
], "-fs") == 0) {
319 FragProgFile
= argv
[++i
];
321 else if (strcmp(argv
[i
], "-vs") == 0) {
322 VertProgFile
= argv
[++i
];
324 else if (strcmp(argv
[i
], "-t") == 0) {
325 TextureFile
= argv
[++i
];
332 main(int argc
, char *argv
[])
334 glutInit(&argc
, argv
);
335 glutInitWindowSize(400, 400);
336 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
337 win
= glutCreateWindow(argv
[0]);
339 glutReshapeFunc(Reshape
);
340 glutKeyboardFunc(Key
);
341 glutSpecialFunc(SpecialKey
);
342 glutDisplayFunc(Redisplay
);
343 ParseOptions(argc
, argv
);