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 } }
55 static GLfloat xRot
= 0.0f
, yRot
= 0.0f
, zRot
= 0.0f
;
61 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
64 glRotatef(xRot
, 1.0f
, 0.0f
, 0.0f
);
65 glRotatef(yRot
, 0.0f
, 1.0f
, 0.0f
);
66 glRotatef(zRot
, 0.0f
, 0.0f
, 1.0f
);
68 glutSolidSphere(2.0, 20, 10);
79 Reshape(int width
, int height
)
81 glViewport(0, 0, width
, height
);
82 glMatrixMode(GL_PROJECTION
);
84 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
85 glMatrixMode(GL_MODELVIEW
);
87 glTranslatef(0.0f
, 0.0f
, -15.0f
);
94 glDeleteShader_func(fragShader
);
95 glDeleteShader_func(vertShader
);
96 glDeleteProgram_func(program
);
97 glutDestroyWindow(win
);
102 Key(unsigned char key
, int x
, int y
)
104 const GLfloat step
= 2.0;
125 SpecialKey(int key
, int x
, int y
)
127 const GLfloat step
= 2.0;
152 LoadAndCompileShader(GLuint shader
, const char *text
)
156 glShaderSource_func(shader
, 1, (const GLchar
**) &text
, NULL
);
158 glCompileShader_func(shader
);
160 glGetShaderiv_func(shader
, GL_COMPILE_STATUS
, &stat
);
164 glGetShaderInfoLog_func(shader
, 1000, &len
, log
);
165 fprintf(stderr
, "brick: problem compiling shader: %s\n", log
);
169 printf("Shader compiled OK\n");
175 * Read a shader from a file.
178 ReadShader(GLuint shader
, const char *filename
)
180 const int max
= 100*1000;
182 char *buffer
= (char*) malloc(max
);
183 FILE *f
= fopen(filename
, "r");
185 fprintf(stderr
, "brick: Unable to open shader file %s\n", filename
);
189 n
= fread(buffer
, 1, max
, f
);
190 printf("brick: read %d bytes from shader file %s\n", n
, filename
);
193 LoadAndCompileShader(shader
, buffer
);
202 CheckLink(GLuint prog
)
205 glGetProgramiv_func(prog
, GL_LINK_STATUS
, &stat
);
209 glGetProgramInfoLog_func(prog
, 1000, &len
, log
);
210 fprintf(stderr
, "Linker error:\n%s\n", log
);
213 fprintf(stderr
, "Link success!\n");
224 version
= (const char *) glGetString(GL_VERSION
);
225 if (version
[0] != '2' || version
[1] != '.') {
226 printf("Warning: this program expects OpenGL 2.0\n");
229 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER
));
233 vertShader
= glCreateShader_func(GL_VERTEX_SHADER
);
234 ReadShader(vertShader
, VertProgFile
);
236 fragShader
= glCreateShader_func(GL_FRAGMENT_SHADER
);
237 ReadShader(fragShader
, FragProgFile
);
239 program
= glCreateProgram_func();
240 glAttachShader_func(program
, fragShader
);
241 glAttachShader_func(program
, vertShader
);
242 glLinkProgram_func(program
);
244 glUseProgram_func(program
);
246 assert(glIsProgram_func(program
));
247 assert(glIsShader_func(fragShader
));
248 assert(glIsShader_func(vertShader
));
251 for (i
= 0; Uniforms
[i
].name
; i
++) {
253 = glGetUniformLocation_func(program
, Uniforms
[i
].name
);
254 printf("Uniform %s location: %d\n", Uniforms
[i
].name
,
255 Uniforms
[i
].location
);
256 switch (Uniforms
[i
].size
) {
258 glUniform1fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
261 glUniform2fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
264 glUniform3fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
267 glUniform4fv_func(Uniforms
[i
].location
, 1, Uniforms
[i
].value
);
274 assert(glGetError() == 0);
276 glClearColor(0.4f
, 0.4f
, 0.8f
, 0.0f
);
278 glEnable(GL_DEPTH_TEST
);
285 ParseOptions(int argc
, char *argv
[])
288 for (i
= 1; i
< argc
; i
++) {
289 if (strcmp(argv
[i
], "-fs") == 0) {
290 FragProgFile
= argv
[i
+1];
292 else if (strcmp(argv
[i
], "-vs") == 0) {
293 VertProgFile
= argv
[i
+1];
300 main(int argc
, char *argv
[])
302 glutInit(&argc
, argv
);
303 glutInitWindowPosition( 0, 0);
304 glutInitWindowSize(400, 400);
305 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
306 win
= glutCreateWindow(argv
[0]);
307 glutReshapeFunc(Reshape
);
308 glutKeyboardFunc(Key
);
309 glutSpecialFunc(SpecialKey
);
310 glutDisplayFunc(Redisplay
);
311 ParseOptions(argc
, argv
);