toyball.c revision 32001f49
132001f49Smrg/**
232001f49Smrg * "Toy Ball" shader demo.  Uses the example shaders from
332001f49Smrg * chapter 11 of the OpenGL Shading Language "orange" book.
432001f49Smrg * 16 Jan 2007
532001f49Smrg */
632001f49Smrg
732001f49Smrg#include <assert.h>
832001f49Smrg#include <string.h>
932001f49Smrg#include <stdio.h>
1032001f49Smrg#include <stdlib.h>
1132001f49Smrg#include <math.h>
1232001f49Smrg#include <GL/glew.h>
1332001f49Smrg#include "glut_wrap.h"
1432001f49Smrg#include "shaderutil.h"
1532001f49Smrg
1632001f49Smrg
1732001f49Smrgstatic char *FragProgFile = "CH11-toyball.frag";
1832001f49Smrgstatic char *VertProgFile = "CH11-toyball.vert";
1932001f49Smrg
2032001f49Smrg/* program/shader objects */
2132001f49Smrgstatic GLuint fragShader;
2232001f49Smrgstatic GLuint vertShader;
2332001f49Smrgstatic GLuint program;
2432001f49Smrg
2532001f49Smrg
2632001f49Smrgstatic struct uniform_info Uniforms[] = {
2732001f49Smrg   { "LightDir",    1, GL_FLOAT_VEC4, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
2832001f49Smrg   { "HVector",     1, GL_FLOAT_VEC4, { 0.32506, 0.32506, 0.88808, 0.0 }, -1 },
2932001f49Smrg   { "BallCenter",  1, GL_FLOAT_VEC4, { 0.0, 0.0, 0.0, 1.0 }, -1 },
3032001f49Smrg   { "SpecularColor", 1, GL_FLOAT_VEC4, { 0.4, 0.4, 0.4, 60.0 }, -1 },
3132001f49Smrg   { "Red",         1, GL_FLOAT_VEC4, { 0.6, 0.0, 0.0, 1.0 }, -1 },
3232001f49Smrg   { "Blue",        1, GL_FLOAT_VEC4, { 0.0, 0.3, 0.6, 1.0 }, -1 },
3332001f49Smrg   { "Yellow",      1, GL_FLOAT_VEC4, { 0.6, 0.5, 0.0, 1.0 }, -1 },
3432001f49Smrg   { "HalfSpace0",  1, GL_FLOAT_VEC4, { 1.0, 0.0, 0.0, 0.2 }, -1 },
3532001f49Smrg   { "HalfSpace1",  1, GL_FLOAT_VEC4, { 0.309016994, 0.951056516, 0.0, 0.2 }, -1 },
3632001f49Smrg   { "HalfSpace2",  1, GL_FLOAT_VEC4, { -0.809016994, 0.587785252, 0.0, 0.2 }, -1 },
3732001f49Smrg   { "HalfSpace3",  1, GL_FLOAT_VEC4, { -0.809016994, -0.587785252, 0.0, 0.2 }, -1 },
3832001f49Smrg   { "HalfSpace4",  1, GL_FLOAT_VEC4, { 0.309116994, -0.951056516, 0.0, 0.2 }, -1 },
3932001f49Smrg   { "InOrOutInit", 1, GL_FLOAT, { -3.0, 0, 0, 0 }, -1 },
4032001f49Smrg   { "StripeWidth", 1, GL_FLOAT, {  0.3, 0, 0, 0 }, -1 },
4132001f49Smrg   { "FWidth",      1, GL_FLOAT, { 0.005, 0, 0, 0 }, -1 },
4232001f49Smrg   END_OF_UNIFORMS
4332001f49Smrg};
4432001f49Smrg
4532001f49Smrgstatic GLint win = 0;
4632001f49Smrgstatic GLboolean Anim = GL_FALSE;
4732001f49Smrgstatic GLfloat TexRot = 0.0;
4832001f49Smrgstatic GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
4932001f49Smrg
5032001f49Smrg
5132001f49Smrgstatic void
5232001f49SmrgIdle(void)
5332001f49Smrg{
5432001f49Smrg   TexRot += 2.0;
5532001f49Smrg   if (TexRot > 360.0)
5632001f49Smrg      TexRot -= 360.0;
5732001f49Smrg   glutPostRedisplay();
5832001f49Smrg}
5932001f49Smrg
6032001f49Smrg
6132001f49Smrgstatic void
6232001f49SmrgRedisplay(void)
6332001f49Smrg{
6432001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6532001f49Smrg
6632001f49Smrg   glPushMatrix();
6732001f49Smrg   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
6832001f49Smrg   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
6932001f49Smrg   glRotatef(zRot, 0.0f, 0.0f, 1.0f);
7032001f49Smrg
7132001f49Smrg   glMatrixMode(GL_TEXTURE);
7232001f49Smrg   glLoadIdentity();
7332001f49Smrg   glRotatef(TexRot, 0.0f, 1.0f, 0.0f);
7432001f49Smrg   glMatrixMode(GL_MODELVIEW);
7532001f49Smrg
7632001f49Smrg   glutSolidSphere(2.0, 20, 10);
7732001f49Smrg
7832001f49Smrg   glPopMatrix();
7932001f49Smrg
8032001f49Smrg   glutSwapBuffers();
8132001f49Smrg}
8232001f49Smrg
8332001f49Smrg
8432001f49Smrgstatic void
8532001f49SmrgReshape(int width, int height)
8632001f49Smrg{
8732001f49Smrg   glViewport(0, 0, width, height);
8832001f49Smrg   glMatrixMode(GL_PROJECTION);
8932001f49Smrg   glLoadIdentity();
9032001f49Smrg   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
9132001f49Smrg   glMatrixMode(GL_MODELVIEW);
9232001f49Smrg   glLoadIdentity();
9332001f49Smrg   glTranslatef(0.0f, 0.0f, -15.0f);
9432001f49Smrg}
9532001f49Smrg
9632001f49Smrg
9732001f49Smrgstatic void
9832001f49SmrgCleanUp(void)
9932001f49Smrg{
10032001f49Smrg   glDeleteShader(fragShader);
10132001f49Smrg   glDeleteShader(vertShader);
10232001f49Smrg   glDeleteProgram(program);
10332001f49Smrg   glutDestroyWindow(win);
10432001f49Smrg}
10532001f49Smrg
10632001f49Smrg
10732001f49Smrgstatic void
10832001f49SmrgKey(unsigned char key, int x, int y)
10932001f49Smrg{
11032001f49Smrg   const GLfloat step = 2.0;
11132001f49Smrg  (void) x;
11232001f49Smrg  (void) y;
11332001f49Smrg
11432001f49Smrg   switch(key) {
11532001f49Smrg   case 'a':
11632001f49Smrg      Anim = !Anim;
11732001f49Smrg      if (Anim)
11832001f49Smrg         glutIdleFunc(Idle);
11932001f49Smrg      else
12032001f49Smrg         glutIdleFunc(NULL);
12132001f49Smrg      break;
12232001f49Smrg   case 'z':
12332001f49Smrg      zRot += step;
12432001f49Smrg      break;
12532001f49Smrg   case 'Z':
12632001f49Smrg      zRot -= step;
12732001f49Smrg      break;
12832001f49Smrg   case 27:
12932001f49Smrg      CleanUp();
13032001f49Smrg      exit(0);
13132001f49Smrg      break;
13232001f49Smrg   }
13332001f49Smrg   glutPostRedisplay();
13432001f49Smrg}
13532001f49Smrg
13632001f49Smrg
13732001f49Smrgstatic void
13832001f49SmrgSpecialKey(int key, int x, int y)
13932001f49Smrg{
14032001f49Smrg   const GLfloat step = 2.0;
14132001f49Smrg
14232001f49Smrg  (void) x;
14332001f49Smrg  (void) y;
14432001f49Smrg
14532001f49Smrg   switch(key) {
14632001f49Smrg   case GLUT_KEY_UP:
14732001f49Smrg      xRot += step;
14832001f49Smrg      break;
14932001f49Smrg   case GLUT_KEY_DOWN:
15032001f49Smrg      xRot -= step;
15132001f49Smrg      break;
15232001f49Smrg   case GLUT_KEY_LEFT:
15332001f49Smrg      yRot -= step;
15432001f49Smrg      break;
15532001f49Smrg   case GLUT_KEY_RIGHT:
15632001f49Smrg      yRot += step;
15732001f49Smrg      break;
15832001f49Smrg   }
15932001f49Smrg   glutPostRedisplay();
16032001f49Smrg}
16132001f49Smrg
16232001f49Smrg
16332001f49Smrg
16432001f49Smrgstatic void
16532001f49SmrgInit(void)
16632001f49Smrg{
16732001f49Smrg   if (!ShadersSupported())
16832001f49Smrg      exit(1);
16932001f49Smrg
17032001f49Smrg   vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
17132001f49Smrg   fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
17232001f49Smrg   program = LinkShaders(vertShader, fragShader);
17332001f49Smrg
17432001f49Smrg   glUseProgram(program);
17532001f49Smrg
17632001f49Smrg   SetUniformValues(program, Uniforms);
17732001f49Smrg   PrintUniforms(Uniforms);
17832001f49Smrg
17932001f49Smrg   assert(glGetError() == 0);
18032001f49Smrg
18132001f49Smrg   glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
18232001f49Smrg
18332001f49Smrg   glEnable(GL_DEPTH_TEST);
18432001f49Smrg
18532001f49Smrg   glColor3f(1, 0, 0);
18632001f49Smrg}
18732001f49Smrg
18832001f49Smrg
18932001f49Smrgstatic void
19032001f49SmrgParseOptions(int argc, char *argv[])
19132001f49Smrg{
19232001f49Smrg   int i;
19332001f49Smrg   for (i = 1; i < argc; i++) {
19432001f49Smrg      if (strcmp(argv[i], "-fs") == 0) {
19532001f49Smrg         FragProgFile = argv[i+1];
19632001f49Smrg      }
19732001f49Smrg      else if (strcmp(argv[i], "-vs") == 0) {
19832001f49Smrg         VertProgFile = argv[i+1];
19932001f49Smrg      }
20032001f49Smrg   }
20132001f49Smrg}
20232001f49Smrg
20332001f49Smrg
20432001f49Smrgint
20532001f49Smrgmain(int argc, char *argv[])
20632001f49Smrg{
20732001f49Smrg   glutInit(&argc, argv);
20832001f49Smrg   glutInitWindowSize(400, 400);
20932001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
21032001f49Smrg   win = glutCreateWindow(argv[0]);
21132001f49Smrg   glewInit();
21232001f49Smrg   glutReshapeFunc(Reshape);
21332001f49Smrg   glutKeyboardFunc(Key);
21432001f49Smrg   glutSpecialFunc(SpecialKey);
21532001f49Smrg   glutDisplayFunc(Redisplay);
21632001f49Smrg   ParseOptions(argc, argv);
21732001f49Smrg   Init();
21832001f49Smrg   glutMainLoop();
21932001f49Smrg   return 0;
22032001f49Smrg}
22132001f49Smrg
222