toyball.c revision 32001f49
1/**
2 * "Toy Ball" shader 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 "glut_wrap.h"
14#include "shaderutil.h"
15
16
17static char *FragProgFile = "CH11-toyball.frag";
18static char *VertProgFile = "CH11-toyball.vert";
19
20/* program/shader objects */
21static GLuint fragShader;
22static GLuint vertShader;
23static GLuint program;
24
25
26static struct uniform_info Uniforms[] = {
27   { "LightDir",    1, GL_FLOAT_VEC4, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
28   { "HVector",     1, GL_FLOAT_VEC4, { 0.32506, 0.32506, 0.88808, 0.0 }, -1 },
29   { "BallCenter",  1, GL_FLOAT_VEC4, { 0.0, 0.0, 0.0, 1.0 }, -1 },
30   { "SpecularColor", 1, GL_FLOAT_VEC4, { 0.4, 0.4, 0.4, 60.0 }, -1 },
31   { "Red",         1, GL_FLOAT_VEC4, { 0.6, 0.0, 0.0, 1.0 }, -1 },
32   { "Blue",        1, GL_FLOAT_VEC4, { 0.0, 0.3, 0.6, 1.0 }, -1 },
33   { "Yellow",      1, GL_FLOAT_VEC4, { 0.6, 0.5, 0.0, 1.0 }, -1 },
34   { "HalfSpace0",  1, GL_FLOAT_VEC4, { 1.0, 0.0, 0.0, 0.2 }, -1 },
35   { "HalfSpace1",  1, GL_FLOAT_VEC4, { 0.309016994, 0.951056516, 0.0, 0.2 }, -1 },
36   { "HalfSpace2",  1, GL_FLOAT_VEC4, { -0.809016994, 0.587785252, 0.0, 0.2 }, -1 },
37   { "HalfSpace3",  1, GL_FLOAT_VEC4, { -0.809016994, -0.587785252, 0.0, 0.2 }, -1 },
38   { "HalfSpace4",  1, GL_FLOAT_VEC4, { 0.309116994, -0.951056516, 0.0, 0.2 }, -1 },
39   { "InOrOutInit", 1, GL_FLOAT, { -3.0, 0, 0, 0 }, -1 },
40   { "StripeWidth", 1, GL_FLOAT, {  0.3, 0, 0, 0 }, -1 },
41   { "FWidth",      1, GL_FLOAT, { 0.005, 0, 0, 0 }, -1 },
42   END_OF_UNIFORMS
43};
44
45static GLint win = 0;
46static GLboolean Anim = GL_FALSE;
47static GLfloat TexRot = 0.0;
48static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
49
50
51static void
52Idle(void)
53{
54   TexRot += 2.0;
55   if (TexRot > 360.0)
56      TexRot -= 360.0;
57   glutPostRedisplay();
58}
59
60
61static void
62Redisplay(void)
63{
64   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
65
66   glPushMatrix();
67   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
68   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
69   glRotatef(zRot, 0.0f, 0.0f, 1.0f);
70
71   glMatrixMode(GL_TEXTURE);
72   glLoadIdentity();
73   glRotatef(TexRot, 0.0f, 1.0f, 0.0f);
74   glMatrixMode(GL_MODELVIEW);
75
76   glutSolidSphere(2.0, 20, 10);
77
78   glPopMatrix();
79
80   glutSwapBuffers();
81}
82
83
84static void
85Reshape(int width, int height)
86{
87   glViewport(0, 0, width, height);
88   glMatrixMode(GL_PROJECTION);
89   glLoadIdentity();
90   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
91   glMatrixMode(GL_MODELVIEW);
92   glLoadIdentity();
93   glTranslatef(0.0f, 0.0f, -15.0f);
94}
95
96
97static void
98CleanUp(void)
99{
100   glDeleteShader(fragShader);
101   glDeleteShader(vertShader);
102   glDeleteProgram(program);
103   glutDestroyWindow(win);
104}
105
106
107static void
108Key(unsigned char key, int x, int y)
109{
110   const GLfloat step = 2.0;
111  (void) x;
112  (void) y;
113
114   switch(key) {
115   case 'a':
116      Anim = !Anim;
117      if (Anim)
118         glutIdleFunc(Idle);
119      else
120         glutIdleFunc(NULL);
121      break;
122   case 'z':
123      zRot += step;
124      break;
125   case 'Z':
126      zRot -= step;
127      break;
128   case 27:
129      CleanUp();
130      exit(0);
131      break;
132   }
133   glutPostRedisplay();
134}
135
136
137static void
138SpecialKey(int key, int x, int y)
139{
140   const GLfloat step = 2.0;
141
142  (void) x;
143  (void) y;
144
145   switch(key) {
146   case GLUT_KEY_UP:
147      xRot += step;
148      break;
149   case GLUT_KEY_DOWN:
150      xRot -= step;
151      break;
152   case GLUT_KEY_LEFT:
153      yRot -= step;
154      break;
155   case GLUT_KEY_RIGHT:
156      yRot += step;
157      break;
158   }
159   glutPostRedisplay();
160}
161
162
163
164static void
165Init(void)
166{
167   if (!ShadersSupported())
168      exit(1);
169
170   vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
171   fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
172   program = LinkShaders(vertShader, fragShader);
173
174   glUseProgram(program);
175
176   SetUniformValues(program, Uniforms);
177   PrintUniforms(Uniforms);
178
179   assert(glGetError() == 0);
180
181   glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
182
183   glEnable(GL_DEPTH_TEST);
184
185   glColor3f(1, 0, 0);
186}
187
188
189static void
190ParseOptions(int argc, char *argv[])
191{
192   int i;
193   for (i = 1; i < argc; i++) {
194      if (strcmp(argv[i], "-fs") == 0) {
195         FragProgFile = argv[i+1];
196      }
197      else if (strcmp(argv[i], "-vs") == 0) {
198         VertProgFile = argv[i+1];
199      }
200   }
201}
202
203
204int
205main(int argc, char *argv[])
206{
207   glutInit(&argc, argv);
208   glutInitWindowSize(400, 400);
209   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
210   win = glutCreateWindow(argv[0]);
211   glewInit();
212   glutReshapeFunc(Reshape);
213   glutKeyboardFunc(Key);
214   glutSpecialFunc(SpecialKey);
215   glutDisplayFunc(Redisplay);
216   ParseOptions(argc, argv);
217   Init();
218   glutMainLoop();
219   return 0;
220}
221
222