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