2 * "Toy Ball" shader demo. Uses the example shaders from
3 * chapter 11 of the OpenGL Shading Language "orange" book.
18 static char *FragProgFile
= "CH11-toyball.frag.txt";
19 static char *VertProgFile
= "CH11-toyball.vert.txt";
21 /* program/shader objects */
22 static GLuint fragShader
;
23 static GLuint vertShader
;
24 static GLuint program
;
34 static struct uniform_info Uniforms
[] = {
35 { "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
36 { "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } },
37 { "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } },
38 { "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } },
39 { "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } },
40 { "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } },
41 { "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } },
42 { "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } },
43 { "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } },
44 { "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } },
45 { "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } },
46 { "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } },
47 { "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } },
48 { "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } },
49 { "FWidth", 1, -1, { 0.005, 0, 0, 0 } },
50 { NULL
, 0, 0, { 0, 0, 0, 0 } }
54 static GLboolean Anim
= GL_FALSE
;
55 static GLfloat TexRot
= 0.0;
56 static GLfloat xRot
= 0.0f
, yRot
= 0.0f
, zRot
= 0.0f
;
72 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
75 glRotatef(xRot
, 1.0f
, 0.0f
, 0.0f
);
76 glRotatef(yRot
, 0.0f
, 1.0f
, 0.0f
);
77 glRotatef(zRot
, 0.0f
, 0.0f
, 1.0f
);
79 glMatrixMode(GL_TEXTURE
);
81 glRotatef(TexRot
, 0.0f
, 1.0f
, 0.0f
);
82 glMatrixMode(GL_MODELVIEW
);
84 glutSolidSphere(2.0, 20, 10);
95 Reshape(int width
, int height
)
97 glViewport(0, 0, width
, height
);
98 glMatrixMode(GL_PROJECTION
);
100 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
101 glMatrixMode(GL_MODELVIEW
);
103 glTranslatef(0.0f
, 0.0f
, -15.0f
);
110 glDeleteShader_func(fragShader
);
111 glDeleteShader_func(vertShader
);
112 glDeleteProgram_func(program
);
113 glutDestroyWindow(win
);
118 Key(unsigned char key
, int x
, int y
)
120 const GLfloat step
= 2.0;
148 SpecialKey(int key
, int x
, int y
)
150 const GLfloat step
= 2.0;
175 LoadAndCompileShader(GLuint shader
, const char *text
)
179 glShaderSource_func(shader
, 1, (const GLchar
**) &text
, NULL
);
181 glCompileShader_func(shader
);
183 glGetShaderiv_func(shader
, GL_COMPILE_STATUS
, &stat
);
187 glGetShaderInfoLog_func(shader
, 1000, &len
, log
);
188 fprintf(stderr
, "toyball: problem compiling shader: %s\n", log
);
192 printf("Shader compiled OK\n");
198 * Read a shader from a file.
201 ReadShader(GLuint shader
, const char *filename
)
203 const int max
= 100*1000;
205 char *buffer
= (char*) malloc(max
);
206 FILE *f
= fopen(filename
, "r");
208 fprintf(stderr
, "toyball: Unable to open shader file %s\n", filename
);
212 n
= fread(buffer
, 1, max
, f
);
213 printf("toyball: read %d bytes from shader file %s\n", n
, filename
);
216 LoadAndCompileShader(shader
, buffer
);
225 CheckLink(GLuint prog
)
228 glGetProgramiv_func(prog
, GL_LINK_STATUS
, &stat
);
232 glGetProgramInfoLog_func(prog
, 1000, &len
, log
);
233 fprintf(stderr
, "Linker error:\n%s\n", log
);
236 fprintf(stderr
, "Link success!\n");
247 version
= (const char *) glGetString(GL_VERSION
);
248 if (version
[0] != '2' || version
[1] != '.') {
249 printf("Warning: this program expects OpenGL 2.0\n");
252 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER
));
256 vertShader
= glCreateShader_func(GL_VERTEX_SHADER
);
257 ReadShader(vertShader
, VertProgFile
);
259 fragShader
= glCreateShader_func(GL_FRAGMENT_SHADER
);
260 ReadShader(fragShader
, FragProgFile
);
262 program
= glCreateProgram_func();
263 glAttachShader_func(program
, fragShader
);
264 glAttachShader_func(program
, vertShader
);
265 glLinkProgram_func(program
);
267 glUseProgram_func(program
);
269 assert(glIsProgram_func(program
));
270 assert(glIsShader_func(fragShader
));
271 assert(glIsShader_func(vertShader
));
274 for (i
= 0; Uniforms
[i
].name
; i
++) {
276 = glGetUniformLocation_func(program
, Uniforms
[i
].name
);
277 printf("Uniform %s location: %d\n", Uniforms
[i
].name
,
278 Uniforms
[i
].location
);
279 switch (Uniforms
[i
].size
) {
281 glUniform1fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
284 glUniform2fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
287 glUniform3fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
290 glUniform4fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
297 assert(glGetError() == 0);
299 glClearColor(0.4f
, 0.4f
, 0.8f
, 0.0f
);
301 glEnable(GL_DEPTH_TEST
);
308 ParseOptions(int argc
, char *argv
[])
311 for (i
= 1; i
< argc
; i
++) {
312 if (strcmp(argv
[i
], "-fs") == 0) {
313 FragProgFile
= argv
[i
+1];
315 else if (strcmp(argv
[i
], "-vs") == 0) {
316 VertProgFile
= argv
[i
+1];
323 main(int argc
, char *argv
[])
325 glutInit(&argc
, argv
);
326 glutInitWindowPosition( 0, 0);
327 glutInitWindowSize(400, 400);
328 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
329 win
= glutCreateWindow(argv
[0]);
330 glutReshapeFunc(Reshape
);
331 glutKeyboardFunc(Key
);
332 glutSpecialFunc(SpecialKey
);
333 glutDisplayFunc(Redisplay
);
334 ParseOptions(argc
, argv
);