Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/freeglut/progs/demos/shapes/shapes.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /*! \file shapes.c | |
| 2 \ingroup demos | |
| 3 | |
| 4 This program is a test harness for the various shapes | |
| 5 in OpenGLUT. It may also be useful to see which | |
| 6 parameters control what behavior in the OpenGLUT | |
| 7 objects. | |
| 8 | |
| 9 Spinning wireframe and solid-shaded shapes are | |
| 10 displayed. Some parameters can be adjusted. | |
| 11 | |
| 12 Keys: | |
| 13 - <tt>Esc </tt> Quit | |
| 14 - <tt>q Q </tt> Quit | |
| 15 - <tt>i I </tt> Show info | |
| 16 - <tt>p P </tt> Toggle perspective or orthographic projection | |
| 17 - <tt>r R </tt> Toggle fixed or animated rotation around model X-axis | |
| 18 - <tt>s S </tt> Toggle toggle fixed function or shader render path | |
| 19 - <tt>n N </tt> Toggle visualization of object's normal vectors | |
| 20 - <tt>= + </tt> Increase \a slices | |
| 21 - <tt>- _ </tt> Decreate \a slices | |
| 22 - <tt>, < </tt> Decreate \a stacks | |
| 23 - <tt>. > </tt> Increase \a stacks | |
| 24 - <tt>9 ( </tt> Decreate \a depth (Sierpinski Sponge) | |
| 25 - <tt>0 ) </tt> Increase \a depth (Sierpinski Sponge) | |
| 26 - <tt>up </tt> Increase "outer radius" | |
| 27 - <tt>down </tt> Decrease "outer radius" | |
| 28 - <tt>left </tt> Decrease "inner radius" | |
| 29 - <tt>right</tt> Increase "inner radius" | |
| 30 - <tt>PgUp </tt> Next shape-drawing function | |
| 31 - <tt>PgDn </tt> Prev shape-drawing function | |
| 32 | |
| 33 \author Written by Nigel Stewart November 2003 | |
| 34 | |
| 35 \author Portions Copyright (C) 2004, the OpenGLUT project contributors. <br> | |
| 36 OpenGLUT branched from freeglut in February, 2004. | |
| 37 | |
| 38 \image html openglut_shapes.png OpenGLUT Geometric Shapes Demonstration | |
| 39 \include demos/shapes/shapes.c | |
| 40 */ | |
| 41 | |
| 42 #include <GL/freeglut.h> | |
| 43 | |
| 44 #include <stdarg.h> | |
| 45 #include <stdio.h> | |
| 46 #include <stdlib.h> | |
| 47 #include <stddef.h> | |
| 48 | |
| 49 #include "glmatrix.h" | |
| 50 | |
| 51 #ifdef _MSC_VER | |
| 52 /* DUMP MEMORY LEAKS */ | |
| 53 #include <crtdbg.h> | |
| 54 #endif | |
| 55 | |
| 56 /* report GL errors, if any, to stderr */ | |
| 57 void checkError(const char *functionName) | |
| 58 { | |
| 59 GLenum error; | |
| 60 while (( error = glGetError() ) != GL_NO_ERROR) { | |
| 61 fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 /* | |
| 66 * OpenGL 2+ shader mode needs some function and macro definitions, | |
| 67 * avoiding a dependency on additional libraries like GLEW or the | |
| 68 * GL/glext.h header | |
| 69 */ | |
| 70 #ifndef GL_FRAGMENT_SHADER | |
| 71 #define GL_FRAGMENT_SHADER 0x8B30 | |
| 72 #endif | |
| 73 | |
| 74 #ifndef GL_VERTEX_SHADER | |
| 75 #define GL_VERTEX_SHADER 0x8B31 | |
| 76 #endif | |
| 77 | |
| 78 #ifndef GL_COMPILE_STATUS | |
| 79 #define GL_COMPILE_STATUS 0x8B81 | |
| 80 #endif | |
| 81 | |
| 82 #ifndef GL_LINK_STATUS | |
| 83 #define GL_LINK_STATUS 0x8B82 | |
| 84 #endif | |
| 85 | |
| 86 #ifndef GL_INFO_LOG_LENGTH | |
| 87 #define GL_INFO_LOG_LENGTH 0x8B84 | |
| 88 #endif | |
| 89 | |
| 90 typedef ptrdiff_t ourGLsizeiptr; | |
| 91 typedef char ourGLchar; | |
| 92 | |
| 93 #ifndef APIENTRY | |
| 94 #define APIENTRY | |
| 95 #endif | |
| 96 | |
| 97 #ifndef GL_VERSION_2_0 | |
| 98 typedef GLuint (APIENTRY *PFNGLCREATESHADERPROC) (GLenum type); | |
| 99 typedef void (APIENTRY *PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const ourGLchar **string, const GLint *length); | |
| 100 typedef void (APIENTRY *PFNGLCOMPILESHADERPROC) (GLuint shader); | |
| 101 typedef GLuint (APIENTRY *PFNGLCREATEPROGRAMPROC) (void); | |
| 102 typedef void (APIENTRY *PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); | |
| 103 typedef void (APIENTRY *PFNGLLINKPROGRAMPROC) (GLuint program); | |
| 104 typedef void (APIENTRY *PFNGLUSEPROGRAMPROC) (GLuint program); | |
| 105 typedef void (APIENTRY *PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); | |
| 106 typedef void (APIENTRY *PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog); | |
| 107 typedef void (APIENTRY *PFNGLGETPROGRAMIVPROC) (GLenum target, GLenum pname, GLint *params); | |
| 108 typedef void (APIENTRY *PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog); | |
| 109 typedef GLint (APIENTRY *PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const ourGLchar *name); | |
| 110 typedef GLint (APIENTRY *PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const ourGLchar *name); | |
| 111 typedef void (APIENTRY *PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
| 112 typedef void (APIENTRY *PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
| 113 #endif | |
| 114 | |
| 115 PFNGLCREATESHADERPROC gl_CreateShader; | |
| 116 PFNGLSHADERSOURCEPROC gl_ShaderSource; | |
| 117 PFNGLCOMPILESHADERPROC gl_CompileShader; | |
| 118 PFNGLCREATEPROGRAMPROC gl_CreateProgram; | |
| 119 PFNGLATTACHSHADERPROC gl_AttachShader; | |
| 120 PFNGLLINKPROGRAMPROC gl_LinkProgram; | |
| 121 PFNGLUSEPROGRAMPROC gl_UseProgram; | |
| 122 PFNGLGETSHADERIVPROC gl_GetShaderiv; | |
| 123 PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog; | |
| 124 PFNGLGETPROGRAMIVPROC gl_GetProgramiv; | |
| 125 PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog; | |
| 126 PFNGLGETATTRIBLOCATIONPROC gl_GetAttribLocation; | |
| 127 PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation; | |
| 128 PFNGLUNIFORMMATRIX4FVPROC gl_UniformMatrix4fv; | |
| 129 PFNGLUNIFORMMATRIX3FVPROC gl_UniformMatrix3fv; | |
| 130 | |
| 131 void initExtensionEntries(void) | |
| 132 { | |
| 133 gl_CreateShader = (PFNGLCREATESHADERPROC) glutGetProcAddress ("glCreateShader"); | |
| 134 gl_ShaderSource = (PFNGLSHADERSOURCEPROC) glutGetProcAddress ("glShaderSource"); | |
| 135 gl_CompileShader = (PFNGLCOMPILESHADERPROC) glutGetProcAddress ("glCompileShader"); | |
| 136 gl_CreateProgram = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress ("glCreateProgram"); | |
| 137 gl_AttachShader = (PFNGLATTACHSHADERPROC) glutGetProcAddress ("glAttachShader"); | |
| 138 gl_LinkProgram = (PFNGLLINKPROGRAMPROC) glutGetProcAddress ("glLinkProgram"); | |
| 139 gl_UseProgram = (PFNGLUSEPROGRAMPROC) glutGetProcAddress ("glUseProgram"); | |
| 140 gl_GetShaderiv = (PFNGLGETSHADERIVPROC) glutGetProcAddress ("glGetShaderiv"); | |
| 141 gl_GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress ("glGetShaderInfoLog"); | |
| 142 gl_GetProgramiv = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress ("glGetProgramiv"); | |
| 143 gl_GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress ("glGetProgramInfoLog"); | |
| 144 gl_GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress ("glGetAttribLocation"); | |
| 145 gl_GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress ("glGetUniformLocation"); | |
| 146 gl_UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress ("glUniformMatrix4fv"); | |
| 147 gl_UniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) glutGetProcAddress ("glUniformMatrix3fv"); | |
| 148 if (!gl_CreateShader || !gl_ShaderSource || !gl_CompileShader || !gl_CreateProgram || !gl_AttachShader || !gl_LinkProgram || !gl_UseProgram || !gl_GetShaderiv || !gl_GetShaderInfoLog || !gl_GetProgramiv || !gl_GetProgramInfoLog || !gl_GetAttribLocation || !gl_GetUniformLocation || !gl_UniformMatrix4fv || !gl_UniformMatrix3fv) | |
| 149 { | |
| 150 fprintf (stderr, "glCreateShader, glShaderSource, glCompileShader, glCreateProgram, glAttachShader, glLinkProgram, glUseProgram, glGetShaderiv, glGetShaderInfoLog, glGetProgramiv, glGetProgramInfoLog, glGetAttribLocation, glGetUniformLocation, glUniformMatrix4fv or gl_UniformMatrix3fv not found"); | |
| 151 exit(1); | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 const ourGLchar *vertexShaderSource[] = { | |
| 156 "/**", | |
| 157 " * From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Smooth_Specular_Highlights", | |
| 158 " * This file is in the public domain.", | |
| 159 " * Contributors: Sylvain Beucler", | |
| 160 " */", | |
| 161 "attribute vec3 fg_coord;", | |
| 162 "attribute vec3 fg_normal;", | |
| 163 "varying vec4 position; /* position of the vertex (and fragment) in world space */", | |
| 164 "varying vec3 varyingNormalDirection; /* surface normal vector in world space */", | |
| 165 "uniform mat4 m, p; /* don't need v, as always identity in our demo */", | |
| 166 "uniform mat3 m_3x3_inv_transp;", | |
| 167 " ", | |
| 168 "void main()", | |
| 169 "{", | |
| 170 " vec4 fg_coord4 = vec4(fg_coord, 1.0);", | |
| 171 " position = m * fg_coord4;", | |
| 172 " varyingNormalDirection = normalize(m_3x3_inv_transp * fg_normal);", | |
| 173 " ", | |
| 174 " mat4 mvp = p*m; /* normally p*v*m */", | |
| 175 " gl_Position = mvp * fg_coord4;", | |
| 176 "}" | |
| 177 }; | |
| 178 | |
| 179 const ourGLchar *fragmentShaderSource[] = { | |
| 180 "/**", | |
| 181 " * From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Smooth_Specular_Highlights", | |
| 182 " * This file is in the public domain.", | |
| 183 " * Contributors: Martin Kraus, Sylvain Beucler", | |
| 184 " */", | |
| 185 "varying vec4 position; /* position of the vertex (and fragment) in world space */", | |
| 186 "varying vec3 varyingNormalDirection; /* surface normal vector in world space */", | |
| 187 "/* uniform mat4 v_inv; // in this demo, the view matrix is always an identity matrix */", | |
| 188 " ", | |
| 189 "struct lightSource", | |
| 190 "{", | |
| 191 " vec4 position;", | |
| 192 " vec4 diffuse;", | |
| 193 " vec4 specular;", | |
| 194 " float constantAttenuation, linearAttenuation, quadraticAttenuation;", | |
| 195 " float spotCutoff, spotExponent;", | |
| 196 " vec3 spotDirection;", | |
| 197 "};", | |
| 198 "lightSource light0 = lightSource(", | |
| 199 " vec4(2.0, 5.0, 5.0, 0.0),", | |
| 200 " vec4(1.0, 1.0, 1.0, 1.0),", | |
| 201 " vec4(1.0, 1.0, 1.0, 1.0),", | |
| 202 " 0.0, 1.0, 0.0,", | |
| 203 " 180.0, 0.0,", | |
| 204 " vec3(0.0, 0.0, 0.0)", | |
| 205 ");", | |
| 206 "vec4 scene_ambient = vec4(0.2, 0.2, 0.2, 1.0);", | |
| 207 " ", | |
| 208 "struct material", | |
| 209 "{", | |
| 210 " vec4 ambient;", | |
| 211 " vec4 diffuse;", | |
| 212 " vec4 specular;", | |
| 213 " float shininess;", | |
| 214 "};", | |
| 215 "material frontMaterial = material(", | |
| 216 " vec4(1.0, 0.0, 0.0, 1.0),", | |
| 217 " vec4(1.0, 0.0, 0.0, 1.0),", | |
| 218 " vec4(1.0, 1.0, 1.0, 1.0),", | |
| 219 " 100.0", | |
| 220 ");", | |
| 221 " ", | |
| 222 "void main()", | |
| 223 "{", | |
| 224 " vec3 normalDirection = normalize(varyingNormalDirection);", | |
| 225 " /* vec3 viewDirection = normalize(vec3(v_inv * vec4(0.0, 0.0, 0.0, 1.0) - position)); */", | |
| 226 " vec3 viewDirection = normalize(vec3(vec4(0.0, 0.0, 0.0, 1.0) - position)); /* in this demo, the view matrix is always an identity matrix */", | |
| 227 " vec3 lightDirection;", | |
| 228 " float attenuation;", | |
| 229 " ", | |
| 230 " if (0.0 == light0.position.w) /* directional light? */", | |
| 231 " {", | |
| 232 " attenuation = 1.0; /* no attenuation */", | |
| 233 " lightDirection = normalize(vec3(light0.position));", | |
| 234 " } ", | |
| 235 " else /* point light or spotlight (or other kind of light) */", | |
| 236 " {", | |
| 237 " vec3 positionToLightSource = vec3(light0.position - position);", | |
| 238 " float distance = length(positionToLightSource);", | |
| 239 " lightDirection = normalize(positionToLightSource);", | |
| 240 " attenuation = 1.0 / (light0.constantAttenuation", | |
| 241 " + light0.linearAttenuation * distance", | |
| 242 " + light0.quadraticAttenuation * distance * distance);", | |
| 243 " ", | |
| 244 " if (light0.spotCutoff <= 90.0) /* spotlight? */", | |
| 245 " {", | |
| 246 " float clampedCosine = max(0.0, dot(-lightDirection, light0.spotDirection));", | |
| 247 " if (clampedCosine < cos(radians(light0.spotCutoff))) /* outside of spotlight cone? */", | |
| 248 " {", | |
| 249 " attenuation = 0.0;", | |
| 250 " }", | |
| 251 " else", | |
| 252 " {", | |
| 253 " attenuation = attenuation * pow(clampedCosine, light0.spotExponent); ", | |
| 254 " }", | |
| 255 " }", | |
| 256 " }", | |
| 257 " ", | |
| 258 " vec3 ambientLighting = vec3(scene_ambient) * vec3(frontMaterial.ambient);", | |
| 259 " ", | |
| 260 " vec3 diffuseReflection = attenuation ", | |
| 261 " * vec3(light0.diffuse) * vec3(frontMaterial.diffuse)", | |
| 262 " * max(0.0, dot(normalDirection, lightDirection));", | |
| 263 " ", | |
| 264 " vec3 specularReflection;", | |
| 265 " if (dot(normalDirection, lightDirection) < 0.0) /* light source on the wrong side? */", | |
| 266 " {", | |
| 267 " specularReflection = vec3(0.0, 0.0, 0.0); /* no specular reflection */", | |
| 268 " }", | |
| 269 " else /* light source on the right side */", | |
| 270 " {", | |
| 271 " specularReflection = attenuation * vec3(light0.specular) * vec3(frontMaterial.specular) ", | |
| 272 " * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), frontMaterial.shininess);", | |
| 273 " }", | |
| 274 " ", | |
| 275 " gl_FragColor = vec4(ambientLighting + diffuseReflection + specularReflection, 1.0);", | |
| 276 "}" | |
| 277 }; | |
| 278 | |
| 279 GLint getAttribOrUniformLocation(const char* name, GLuint program, GLboolean isAttrib) | |
| 280 { | |
| 281 if (isAttrib) | |
| 282 { | |
| 283 GLint attrib = gl_GetAttribLocation(program, name); | |
| 284 if (attrib == -1) | |
| 285 { | |
| 286 fprintf(stderr, "Warning: Could not bind attrib %s\n", name); | |
| 287 } | |
| 288 | |
| 289 checkError ("getAttribOrUniformLocation"); | |
| 290 return attrib; | |
| 291 } | |
| 292 else | |
| 293 { | |
| 294 GLint uniform = gl_GetUniformLocation(program, name); | |
| 295 if (uniform == -1) | |
| 296 { | |
| 297 fprintf(stderr, "Warning: Could not bind uniform %s\n", name); | |
| 298 } | |
| 299 | |
| 300 checkError ("getAttribOrUniformLocation"); | |
| 301 return uniform; | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 GLuint program; | |
| 306 GLint attribute_fg_coord = -1, attribute_fg_normal = -1; | |
| 307 GLint uniform_m = -1, uniform_p = -1, uniform_m_3x3_inv_transp = -1; | |
| 308 GLint shaderReady = 0; /* Set to 1 when all initialization went well, to -1 when shader somehow unusable. */ | |
| 309 | |
| 310 | |
| 311 | |
| 312 void compileAndCheck(GLuint shader) | |
| 313 { | |
| 314 GLint status; | |
| 315 gl_CompileShader (shader); | |
| 316 gl_GetShaderiv (shader, GL_COMPILE_STATUS, &status); | |
| 317 if (status == GL_FALSE) { | |
| 318 GLint infoLogLength; | |
| 319 ourGLchar *infoLog; | |
| 320 gl_GetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLogLength); | |
| 321 infoLog = (ourGLchar*) malloc (infoLogLength); | |
| 322 gl_GetShaderInfoLog (shader, infoLogLength, NULL, infoLog); | |
| 323 fprintf (stderr, "compile log: %s\n", infoLog); | |
| 324 free (infoLog); | |
| 325 } | |
| 326 checkError ("compileAndCheck"); | |
| 327 } | |
| 328 | |
| 329 GLuint compileShaderSource(GLenum type, GLsizei count, const ourGLchar **string) | |
| 330 { | |
| 331 GLuint shader = gl_CreateShader (type); | |
| 332 gl_ShaderSource (shader, count, string, NULL); | |
| 333 | |
| 334 checkError ("compileShaderSource"); | |
| 335 | |
| 336 compileAndCheck (shader); | |
| 337 return shader; | |
| 338 } | |
| 339 | |
| 340 void linkAndCheck(GLuint program) | |
| 341 { | |
| 342 GLint status; | |
| 343 gl_LinkProgram (program); | |
| 344 gl_GetProgramiv (program, GL_LINK_STATUS, &status); | |
| 345 if (status == GL_FALSE) { | |
| 346 GLint infoLogLength; | |
| 347 ourGLchar *infoLog; | |
| 348 gl_GetProgramiv (program, GL_INFO_LOG_LENGTH, &infoLogLength); | |
| 349 infoLog = (ourGLchar*) malloc (infoLogLength); | |
| 350 gl_GetProgramInfoLog (program, infoLogLength, NULL, infoLog); | |
| 351 fprintf (stderr, "link log: %s\n", infoLog); | |
| 352 free (infoLog); | |
| 353 } | |
| 354 checkError ("linkAndCheck"); | |
| 355 } | |
| 356 | |
| 357 void createProgram(GLuint vertexShader, GLuint fragmentShader) | |
| 358 { | |
| 359 program = gl_CreateProgram (); | |
| 360 if (vertexShader != 0) { | |
| 361 gl_AttachShader (program, vertexShader); | |
| 362 } | |
| 363 if (fragmentShader != 0) { | |
| 364 gl_AttachShader (program, fragmentShader); | |
| 365 } | |
| 366 | |
| 367 checkError ("createProgram"); | |
| 368 | |
| 369 linkAndCheck (program); | |
| 370 } | |
| 371 | |
| 372 void initShader(void) | |
| 373 { | |
| 374 const GLsizei vertexShaderLines = sizeof(vertexShaderSource) / sizeof(ourGLchar*); | |
| 375 GLuint vertexShader = | |
| 376 compileShaderSource (GL_VERTEX_SHADER, vertexShaderLines, vertexShaderSource); | |
| 377 | |
| 378 const GLsizei fragmentShaderLines = sizeof(fragmentShaderSource) / sizeof(ourGLchar*); | |
| 379 GLuint fragmentShader = | |
| 380 compileShaderSource (GL_FRAGMENT_SHADER, fragmentShaderLines, fragmentShaderSource); | |
| 381 | |
| 382 checkError ("initShader - 1"); | |
| 383 | |
| 384 createProgram (vertexShader, fragmentShader); | |
| 385 | |
| 386 gl_UseProgram (program); | |
| 387 | |
| 388 attribute_fg_coord = getAttribOrUniformLocation("fg_coord" , program, GL_TRUE); | |
| 389 attribute_fg_normal = getAttribOrUniformLocation("fg_normal" , program, GL_TRUE); | |
| 390 uniform_m = getAttribOrUniformLocation("m" , program, GL_FALSE); | |
| 391 uniform_p = getAttribOrUniformLocation("p" , program, GL_FALSE); | |
| 392 uniform_m_3x3_inv_transp= getAttribOrUniformLocation("m_3x3_inv_transp" , program, GL_FALSE); | |
| 393 | |
| 394 gl_UseProgram (0); | |
| 395 | |
| 396 if (attribute_fg_coord==-1 || attribute_fg_normal==-1 || | |
| 397 uniform_m==-1 || uniform_p==-1 || uniform_m_3x3_inv_transp==-1) | |
| 398 shaderReady = -1; | |
| 399 else | |
| 400 shaderReady = 1; | |
| 401 | |
| 402 checkError ("initShader - 2"); | |
| 403 } | |
| 404 | |
| 405 /* | |
| 406 * This macro is only intended to be used on arrays, of course. | |
| 407 */ | |
| 408 #define NUMBEROF(x) ((sizeof(x))/(sizeof(x[0]))) | |
| 409 | |
| 410 /* | |
| 411 * These global variables control which object is drawn, | |
| 412 * and how it is drawn. No object uses all of these | |
| 413 * variables. | |
| 414 */ | |
| 415 static int function_index; | |
| 416 static int slices = 16; | |
| 417 static int stacks = 16; | |
| 418 static double irad = .25; | |
| 419 static double orad = 1.0; /* doubles as size for objects other than Torus */ | |
| 420 static int depth = 4; | |
| 421 static double offset[ 3 ] = { 0, 0, 0 }; | |
| 422 static GLboolean show_info = GL_TRUE; | |
| 423 static float ar; | |
| 424 static GLboolean persProject = GL_TRUE; | |
| 425 static GLboolean animateXRot = GL_FALSE; | |
| 426 static GLboolean useShader = GL_FALSE; | |
| 427 static GLboolean visNormals = GL_FALSE; | |
| 428 | |
| 429 /* | |
| 430 * Enum to tell drawSizeInfo what to draw for each object | |
| 431 */ | |
| 432 #define GEO_NO_SIZE 0 | |
| 433 #define GEO_SIZE 1 | |
| 434 #define GEO_SCALE 2 | |
| 435 #define GEO_INNER_OUTER_RAD 4 | |
| 436 #define GEO_RAD 8 | |
| 437 #define GEO_BASE_HEIGHT 16 | |
| 438 #define GEO_RAD_HEIGHT 32 | |
| 439 | |
| 440 /* | |
| 441 * These one-liners draw particular objects, fetching appropriate | |
| 442 * information from the above globals. They are just thin wrappers | |
| 443 * for the FreeGLUT objects. | |
| 444 */ | |
| 445 static void drawSolidTetrahedron(void) { glutSolidTetrahedron (); } | |
| 446 static void drawWireTetrahedron(void) { glutWireTetrahedron (); } | |
| 447 static void drawSolidCube(void) { glutSolidCube(orad); } /* orad doubles as size input */ | |
| 448 static void drawWireCube(void) { glutWireCube(orad); } /* orad doubles as size input */ | |
| 449 static void drawSolidOctahedron(void) { glutSolidOctahedron (); } | |
| 450 static void drawWireOctahedron(void) { glutWireOctahedron (); } | |
| 451 static void drawSolidDodecahedron(void) { glutSolidDodecahedron (); } | |
| 452 static void drawWireDodecahedron(void) { glutWireDodecahedron (); } | |
| 453 static void drawSolidRhombicDodecahedron(void) { glutSolidRhombicDodecahedron (); } | |
| 454 static void drawWireRhombicDodecahedron(void) { glutWireRhombicDodecahedron (); } | |
| 455 static void drawSolidIcosahedron(void) { glutSolidIcosahedron (); } | |
| 456 static void drawWireIcosahedron(void) { glutWireIcosahedron (); } | |
| 457 static void drawSolidSierpinskiSponge(void) { glutSolidSierpinskiSponge (depth, offset, orad);} /* orad doubles as size input */ | |
| 458 static void drawWireSierpinskiSponge(void) { glutWireSierpinskiSponge (depth, offset, orad); } /* orad doubles as size input */ | |
| 459 static void drawSolidTorus(void) { glutSolidTorus(irad,orad,slices,stacks); } | |
| 460 static void drawWireTorus(void) { glutWireTorus (irad,orad,slices,stacks); } | |
| 461 static void drawSolidSphere(void) { glutSolidSphere(orad,slices,stacks); } /* orad doubles as size input */ | |
| 462 static void drawWireSphere(void) { glutWireSphere(orad,slices,stacks); } /* orad doubles as size input */ | |
| 463 static void drawSolidCone(void) { glutSolidCone(irad,orad,slices,stacks); } /* irad doubles as base input, and orad as height input */ | |
| 464 static void drawWireCone(void) { glutWireCone(irad,orad,slices,stacks); } /* irad doubles as base input, and orad as height input */ | |
| 465 static void drawSolidCylinder(void) { glutSolidCylinder(irad,orad,slices,stacks); } /* irad doubles as radius input, and orad as height input */ | |
| 466 static void drawWireCylinder(void) { glutWireCylinder(irad,orad,slices,stacks); } /* irad doubles as radius input, and orad as height input */ | |
| 467 /* per Glut manpage, it should be noted that the teapot is rendered | |
| 468 * with clockwise winding for front facing polygons... | |
| 469 * Same for the teacup and teaspoon | |
| 470 */ | |
| 471 static void drawSolidTeapot(void) | |
| 472 { glFrontFace(GL_CW); glutSolidTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */} | |
| 473 static void drawWireTeapot(void) | |
| 474 { glFrontFace(GL_CW); glutWireTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */} | |
| 475 static void drawSolidTeacup(void) | |
| 476 { glFrontFace(GL_CW); glutSolidTeacup(orad); glFrontFace(GL_CCW); /* orad doubles as size input */} | |
| 477 static void drawWireTeacup(void) | |
| 478 { glFrontFace(GL_CW); glutWireTeacup(orad); glFrontFace(GL_CCW); /* orad doubles as size input */} | |
| 479 static void drawSolidTeaspoon(void) | |
| 480 { glFrontFace(GL_CW); glutSolidTeaspoon(orad); glFrontFace(GL_CCW); /* orad doubles as size input */} | |
| 481 static void drawWireTeaspoon(void) | |
| 482 { glFrontFace(GL_CW); glutWireTeaspoon(orad); glFrontFace(GL_CCW); /* orad doubles as size input */} | |
| 483 | |
| 484 #define RADIUSFAC 0.70710678118654752440084436210485f | |
| 485 | |
| 486 static void drawSolidCuboctahedron(void) | |
| 487 { | |
| 488 GLfloat radius = RADIUSFAC*(GLfloat)orad; /* orad doubles as size */ | |
| 489 glBegin( GL_TRIANGLES ); | |
| 490 glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( radius, radius, 0.0 ); glVertex3d( 0.0, radius, radius ); glVertex3d( radius, 0.0, radius ); | |
| 491 glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( radius, radius, 0.0 ); glVertex3d( radius, 0.0,-radius ); glVertex3d( 0.0, radius,-radius ); | |
| 492 glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( radius,-radius, 0.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( 0.0,-radius, radius ); | |
| 493 glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( radius,-radius, 0.0 ); glVertex3d( 0.0,-radius,-radius ); glVertex3d( radius, 0.0,-radius ); | |
| 494 glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-radius, radius, 0.0 ); glVertex3d(-radius, 0.0, radius ); glVertex3d( 0.0, radius, radius ); | |
| 495 glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-radius, radius, 0.0 ); glVertex3d( 0.0, radius,-radius ); glVertex3d(-radius, 0.0,-radius ); | |
| 496 glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-radius,-radius, 0.0 ); glVertex3d( 0.0,-radius, radius ); glVertex3d(-radius, 0.0, radius ); | |
| 497 glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-radius,-radius, 0.0 ); glVertex3d(-radius, 0.0,-radius ); glVertex3d( 0.0,-radius,-radius ); | |
| 498 glEnd(); | |
| 499 | |
| 500 glBegin( GL_QUADS ); | |
| 501 glNormal3d( 1.0, 0.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( radius, 0.0,-radius ); | |
| 502 glNormal3d(-1.0, 0.0, 0.0 ); glVertex3d(-radius, radius, 0.0 ); glVertex3d(-radius, 0.0,-radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d(-radius, 0.0, radius ); | |
| 503 glNormal3d( 0.0, 1.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( 0.0, radius,-radius ); glVertex3d(-radius, radius, 0.0 ); glVertex3d( 0.0, radius, radius ); | |
| 504 glNormal3d( 0.0,-1.0, 0.0 ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( 0.0,-radius, radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d( 0.0,-radius,-radius ); | |
| 505 glNormal3d( 0.0, 0.0, 1.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( 0.0, radius, radius ); glVertex3d(-radius, 0.0, radius ); glVertex3d( 0.0,-radius, radius ); | |
| 506 glNormal3d( 0.0, 0.0,-1.0 ); glVertex3d( radius, 0.0,-radius ); glVertex3d( 0.0,-radius,-radius ); glVertex3d(-radius, 0.0,-radius ); glVertex3d( 0.0, radius,-radius ); | |
| 507 glEnd(); | |
| 508 } | |
| 509 | |
| 510 static void drawWireCuboctahedron(void) | |
| 511 { | |
| 512 GLfloat radius = RADIUSFAC*(GLfloat)orad; /* orad doubles as size */ | |
| 513 glBegin( GL_LINE_LOOP ); | |
| 514 glNormal3d( 1.0, 0.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( radius, 0.0,-radius ); | |
| 515 glEnd(); | |
| 516 glBegin( GL_LINE_LOOP ); | |
| 517 glNormal3d(-1.0, 0.0, 0.0 ); glVertex3d(-radius, radius, 0.0 ); glVertex3d(-radius, 0.0,-radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d(-radius, 0.0, radius ); | |
| 518 glEnd(); | |
| 519 glBegin( GL_LINE_LOOP ); | |
| 520 glNormal3d( 0.0, 1.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( 0.0, radius,-radius ); glVertex3d(-radius, radius, 0.0 ); glVertex3d( 0.0, radius, radius ); | |
| 521 glEnd(); | |
| 522 glBegin( GL_LINE_LOOP ); | |
| 523 glNormal3d( 0.0,-1.0, 0.0 ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( 0.0,-radius, radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d( 0.0,-radius,-radius ); | |
| 524 glEnd(); | |
| 525 glBegin( GL_LINE_LOOP ); | |
| 526 glNormal3d( 0.0, 0.0, 1.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( 0.0, radius, radius ); glVertex3d(-radius, 0.0, radius ); glVertex3d( 0.0,-radius, radius ); | |
| 527 glEnd(); | |
| 528 glBegin( GL_LINE_LOOP ); | |
| 529 glNormal3d( 0.0, 0.0,-1.0 ); glVertex3d( radius, 0.0,-radius ); glVertex3d( 0.0,-radius,-radius ); glVertex3d(-radius, 0.0,-radius ); glVertex3d( 0.0, radius,-radius ); | |
| 530 glEnd(); | |
| 531 } | |
| 532 | |
| 533 #undef RADIUSFAC | |
| 534 | |
| 535 /* | |
| 536 * This structure defines an entry in our function-table. | |
| 537 */ | |
| 538 typedef struct | |
| 539 { | |
| 540 const char * const name; | |
| 541 void (*solid) (void); | |
| 542 void (*wire) (void); | |
| 543 int drawSizeInfoFlag; | |
| 544 } entry; | |
| 545 | |
| 546 #define ENTRY(e,f) {#e, drawSolid##e, drawWire##e,f} | |
| 547 static const entry table [] = | |
| 548 { | |
| 549 ENTRY (Tetrahedron,GEO_NO_SIZE), | |
| 550 ENTRY (Cube,GEO_SIZE), | |
| 551 ENTRY (Octahedron,GEO_NO_SIZE), | |
| 552 ENTRY (Dodecahedron,GEO_NO_SIZE), | |
| 553 ENTRY (RhombicDodecahedron,GEO_NO_SIZE), | |
| 554 ENTRY (Icosahedron,GEO_NO_SIZE), | |
| 555 ENTRY (SierpinskiSponge,GEO_SCALE), | |
| 556 ENTRY (Teapot,GEO_SIZE), | |
| 557 ENTRY (Teacup,GEO_SIZE), | |
| 558 ENTRY (Teaspoon,GEO_SIZE), | |
| 559 ENTRY (Torus,GEO_INNER_OUTER_RAD), | |
| 560 ENTRY (Sphere,GEO_RAD), | |
| 561 ENTRY (Cone,GEO_BASE_HEIGHT), | |
| 562 ENTRY (Cylinder,GEO_RAD_HEIGHT), | |
| 563 ENTRY (Cuboctahedron,GEO_SIZE) /* This one doesn't work when in shader mode and is then skipped */ | |
| 564 }; | |
| 565 #undef ENTRY | |
| 566 | |
| 567 /*! | |
| 568 Does printf()-like work using freeglut | |
| 569 glutBitmapString(). Uses a fixed font. Prints | |
| 570 at the indicated row/column position. | |
| 571 | |
| 572 Limitation: Cannot address pixels. | |
| 573 Limitation: Renders in screen coords, not model coords. | |
| 574 */ | |
| 575 static void shapesPrintf (int row, int col, const char *fmt, ...) | |
| 576 { | |
| 577 static char buf[256]; | |
| 578 int viewport[4]; | |
| 579 void *font = GLUT_BITMAP_9_BY_15; | |
| 580 va_list args; | |
| 581 | |
| 582 va_start(args, fmt); | |
| 583 #if defined(WIN32) && !defined(__CYGWIN__) | |
| 584 (void) _vsnprintf (buf, sizeof(buf), fmt, args); | |
| 585 #else | |
| 586 (void) vsnprintf (buf, sizeof(buf), fmt, args); | |
| 587 #endif | |
| 588 va_end(args); | |
| 589 | |
| 590 glGetIntegerv(GL_VIEWPORT,viewport); | |
| 591 | |
| 592 glPushMatrix(); | |
| 593 glLoadIdentity(); | |
| 594 | |
| 595 glMatrixMode(GL_PROJECTION); | |
| 596 glPushMatrix(); | |
| 597 glLoadIdentity(); | |
| 598 | |
| 599 glOrtho(0,viewport[2],0,viewport[3],-1,1); | |
| 600 | |
| 601 glRasterPos2i | |
| 602 ( | |
| 603 glutBitmapWidth(font, ' ') * col, | |
| 604 - glutBitmapHeight(font) * row + viewport[3] | |
| 605 ); | |
| 606 glutBitmapString (font, (unsigned char*)buf); | |
| 607 | |
| 608 glPopMatrix(); | |
| 609 glMatrixMode(GL_MODELVIEW); | |
| 610 glPopMatrix(); | |
| 611 } | |
| 612 | |
| 613 /* Print info about the about the current shape and render state on the screen */ | |
| 614 static void DrawSizeInfo(int *row) | |
| 615 { | |
| 616 switch (table [function_index].drawSizeInfoFlag) | |
| 617 { | |
| 618 case GEO_NO_SIZE: | |
| 619 break; | |
| 620 case GEO_SIZE: | |
| 621 shapesPrintf ((*row)++, 1, "Size Up Down : %f", orad); | |
| 622 break; | |
| 623 case GEO_SCALE: | |
| 624 shapesPrintf ((*row)++, 1, "Scale Up Down : %f", orad); | |
| 625 break; | |
| 626 case GEO_INNER_OUTER_RAD: | |
| 627 shapesPrintf ((*row)++, 1, "Inner radius Left Right: %f", irad); | |
| 628 shapesPrintf ((*row)++, 1, "Outer radius Up Down : %f", orad); | |
| 629 break; | |
| 630 case GEO_RAD: | |
| 631 shapesPrintf ((*row)++, 1, "Radius Up Down : %f", orad); | |
| 632 break; | |
| 633 case GEO_BASE_HEIGHT: | |
| 634 shapesPrintf ((*row)++, 1, "Base Left Right: %f", irad); | |
| 635 shapesPrintf ((*row)++, 1, "Height Up Down : %f", orad); | |
| 636 break; | |
| 637 case GEO_RAD_HEIGHT: | |
| 638 shapesPrintf ((*row)++, 1, "Radius Left Right: %f", irad); | |
| 639 shapesPrintf ((*row)++, 1, "Height Up Down : %f", orad); | |
| 640 break; | |
| 641 } | |
| 642 } | |
| 643 | |
| 644 static void drawInfo() | |
| 645 { | |
| 646 int row = 1; | |
| 647 shapesPrintf (row++, 1, "Shape PgUp PgDn: %s", table [function_index].name); | |
| 648 shapesPrintf (row++, 1, "Slices +-: %d Stacks <>: %d", slices, stacks); | |
| 649 shapesPrintf (row++, 1, "nSides +-: %d nRings <>: %d", slices, stacks); | |
| 650 shapesPrintf (row++, 1, "Depth (): %d", depth); | |
| 651 DrawSizeInfo(&row); | |
| 652 if (persProject) | |
| 653 shapesPrintf (row++, 1, "Perspective projection (p)"); | |
| 654 else | |
| 655 shapesPrintf (row++, 1, "Orthographic projection (p)"); | |
| 656 if (useShader) | |
| 657 shapesPrintf (row++, 1, "Using shader (s)"); | |
| 658 else | |
| 659 shapesPrintf (row++, 1, "Using fixed function pipeline (s)"); | |
| 660 if (animateXRot) | |
| 661 shapesPrintf (row++, 1, "2D rotation (r)"); | |
| 662 else | |
| 663 shapesPrintf (row++, 1, "1D rotation (r)"); | |
| 664 shapesPrintf (row++, 1, "visualizing normals: %i (n)",visNormals); | |
| 665 } | |
| 666 | |
| 667 /* GLUT callback Handlers */ | |
| 668 static void | |
| 669 resize(int width, int height) | |
| 670 { | |
| 671 ar = (float) width / (float) height; | |
| 672 | |
| 673 glViewport(0, 0, width, height); | |
| 674 } | |
| 675 | |
| 676 static void display(void) | |
| 677 { | |
| 678 const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; | |
| 679 const double a = t*89.0; | |
| 680 const double b = (animateXRot?t:1)*67.0; | |
| 681 | |
| 682 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| 683 | |
| 684 glutSetOption(GLUT_GEOMETRY_VISUALIZE_NORMALS,visNormals); /* Normals visualized or not? */ | |
| 685 | |
| 686 if (useShader && !shaderReady) | |
| 687 initShader(); | |
| 688 | |
| 689 if (useShader && shaderReady) | |
| 690 { | |
| 691 /* setup use of shader (and vertex buffer by FreeGLUT) */ | |
| 692 gl_UseProgram (program); | |
| 693 glutSetVertexAttribCoord3(attribute_fg_coord); | |
| 694 glutSetVertexAttribNormal(attribute_fg_normal); | |
| 695 /* There is also a glutSetVertexAttribTexCoord2, which is used only when drawing the teapot, teacup or teaspoon */ | |
| 696 | |
| 697 gl_matrix_mode(GL_PROJECTION); | |
| 698 gl_load_identity(); | |
| 699 if (persProject) | |
| 700 gl_frustum(-ar, ar, -1.f, 1.f, 2.f, 100.f); | |
| 701 else | |
| 702 gl_ortho(-ar*3, ar*3, -3.f, 3.f, 2.f, 100.f); | |
| 703 gl_UniformMatrix4fv (uniform_p, 1, GL_FALSE, get_matrix(GL_PROJECTION)); | |
| 704 | |
| 705 | |
| 706 gl_matrix_mode(GL_MODELVIEW); | |
| 707 gl_load_identity(); | |
| 708 | |
| 709 gl_push_matrix(); | |
| 710 /* Not in reverse order like normal OpenGL, our util library multiplies the matrices in the order they are specified in */ | |
| 711 gl_rotatef((float)a,0,0,1); | |
| 712 gl_rotatef((float)b,1,0,0); | |
| 713 gl_translatef(0,1.2f,-6); | |
| 714 gl_UniformMatrix4fv (uniform_m , 1, GL_FALSE, get_matrix(GL_MODELVIEW)); | |
| 715 gl_UniformMatrix3fv (uniform_m_3x3_inv_transp, 1, GL_FALSE, get_inv_transpose_3x3(GL_MODELVIEW)); | |
| 716 table [function_index].solid (); | |
| 717 gl_pop_matrix(); | |
| 718 | |
| 719 gl_push_matrix(); | |
| 720 gl_rotatef((float)a,0,0,1); | |
| 721 gl_rotatef((float)b,1,0,0); | |
| 722 gl_translatef(0,-1.2f,-6); | |
| 723 gl_UniformMatrix4fv (uniform_m , 1, GL_FALSE, get_matrix(GL_MODELVIEW)); | |
| 724 gl_UniformMatrix3fv (uniform_m_3x3_inv_transp, 1, GL_FALSE, get_inv_transpose_3x3(GL_MODELVIEW)); | |
| 725 table [function_index].wire (); | |
| 726 gl_pop_matrix(); | |
| 727 | |
| 728 gl_UseProgram (0); | |
| 729 glutSetVertexAttribCoord3(-1); | |
| 730 glutSetVertexAttribNormal(-1); | |
| 731 | |
| 732 checkError ("display"); | |
| 733 } | |
| 734 else | |
| 735 { | |
| 736 /* fixed function pipeline */ | |
| 737 glMatrixMode(GL_PROJECTION); | |
| 738 glLoadIdentity(); | |
| 739 if (persProject) | |
| 740 glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); | |
| 741 else | |
| 742 glOrtho(-ar*3, ar*3, -3.0, 3.0, 2.0, 100.0); | |
| 743 glMatrixMode(GL_MODELVIEW); | |
| 744 glLoadIdentity(); | |
| 745 | |
| 746 glEnable(GL_LIGHTING); | |
| 747 | |
| 748 glColor3d(1,0,0); | |
| 749 | |
| 750 glPushMatrix(); | |
| 751 glTranslated(0,1.2,-6); | |
| 752 glRotated(b,1,0,0); | |
| 753 glRotated(a,0,0,1); | |
| 754 table [function_index].solid (); | |
| 755 glPopMatrix(); | |
| 756 | |
| 757 glPushMatrix(); | |
| 758 glTranslated(0,-1.2,-6); | |
| 759 glRotated(b,1,0,0); | |
| 760 glRotated(a,0,0,1); | |
| 761 table [function_index].wire (); | |
| 762 glPopMatrix(); | |
| 763 | |
| 764 glDisable(GL_LIGHTING); | |
| 765 glColor3d(0.1,0.1,0.4); | |
| 766 } | |
| 767 | |
| 768 if( show_info ) | |
| 769 /* print info to screen */ | |
| 770 drawInfo(); | |
| 771 else | |
| 772 /* print to command line instead */ | |
| 773 printf ( "Shape %d slides %d stacks %d\n", function_index, slices, stacks ) ; | |
| 774 | |
| 775 glutSwapBuffers(); | |
| 776 } | |
| 777 | |
| 778 | |
| 779 static void | |
| 780 key(unsigned char key, int x, int y) | |
| 781 { | |
| 782 switch (key) | |
| 783 { | |
| 784 case 27 : | |
| 785 case 'Q': | |
| 786 case 'q': glutLeaveMainLoop () ; break; | |
| 787 | |
| 788 case 'I': | |
| 789 case 'i': show_info=!show_info; break; | |
| 790 | |
| 791 case '=': | |
| 792 case '+': slices++; break; | |
| 793 | |
| 794 case '-': | |
| 795 case '_': if( slices > -1 ) slices--; break; | |
| 796 | |
| 797 case ',': | |
| 798 case '<': if( stacks > -1 ) stacks--; break; | |
| 799 | |
| 800 case '.': | |
| 801 case '>': stacks++; break; | |
| 802 | |
| 803 case '9': | |
| 804 case '(': if( depth > -1 ) depth--; break; | |
| 805 | |
| 806 case '0': | |
| 807 case ')': ++depth; break; | |
| 808 | |
| 809 case 'P': | |
| 810 case 'p': persProject=!persProject; break; | |
| 811 | |
| 812 case 'R': | |
| 813 case 'r': animateXRot=!animateXRot; break; | |
| 814 | |
| 815 case 'S': | |
| 816 case 's': | |
| 817 useShader=!useShader; | |
| 818 /* Cuboctahedron can't be shown when in shader mode, move to next */ | |
| 819 if (useShader && NUMBEROF (table)-1 == ( unsigned )function_index) | |
| 820 function_index = 0; | |
| 821 break; | |
| 822 | |
| 823 case 'N': | |
| 824 case 'n': visNormals=!visNormals; break; | |
| 825 | |
| 826 default: | |
| 827 break; | |
| 828 } | |
| 829 | |
| 830 glutPostRedisplay(); | |
| 831 } | |
| 832 | |
| 833 static void special (int key, int x, int y) | |
| 834 { | |
| 835 switch (key) | |
| 836 { | |
| 837 case GLUT_KEY_PAGE_UP: ++function_index; break; | |
| 838 case GLUT_KEY_PAGE_DOWN: --function_index; break; | |
| 839 case GLUT_KEY_UP: orad *= 2; break; | |
| 840 case GLUT_KEY_DOWN: orad /= 2; break; | |
| 841 | |
| 842 case GLUT_KEY_RIGHT: irad *= 2; break; | |
| 843 case GLUT_KEY_LEFT: irad /= 2; break; | |
| 844 | |
| 845 default: | |
| 846 break; | |
| 847 } | |
| 848 | |
| 849 if (0 > function_index) | |
| 850 function_index = NUMBEROF (table) - 1; | |
| 851 | |
| 852 if (NUMBEROF (table) <= ( unsigned )function_index) | |
| 853 function_index = 0; | |
| 854 | |
| 855 /* Cuboctahedron can't be shown when in shader mode, skip it */ | |
| 856 if (useShader && NUMBEROF (table)-1 == ( unsigned )function_index) | |
| 857 { | |
| 858 if (key==GLUT_KEY_PAGE_UP) | |
| 859 function_index = 0; | |
| 860 else | |
| 861 function_index -= 1; | |
| 862 } | |
| 863 } | |
| 864 | |
| 865 | |
| 866 static void | |
| 867 idle(void) | |
| 868 { | |
| 869 glutPostRedisplay(); | |
| 870 } | |
| 871 | |
| 872 const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; | |
| 873 const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; | |
| 874 const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; | |
| 875 const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f }; | |
| 876 | |
| 877 const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; | |
| 878 const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; | |
| 879 const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; | |
| 880 const GLfloat high_shininess[] = { 100.0f }; | |
| 881 | |
| 882 /* Program entry point */ | |
| 883 | |
| 884 int | |
| 885 main(int argc, char *argv[]) | |
| 886 { | |
| 887 glutInitWindowSize(800,600); | |
| 888 glutInitWindowPosition(40,40); | |
| 889 glutInit(&argc, argv); | |
| 890 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); | |
| 891 | |
| 892 glutCreateWindow("FreeGLUT Shapes"); | |
| 893 | |
| 894 glutReshapeFunc(resize); | |
| 895 glutDisplayFunc(display); | |
| 896 glutKeyboardFunc(key); | |
| 897 glutSpecialFunc(special); | |
| 898 glutIdleFunc(idle); | |
| 899 | |
| 900 glutSetOption ( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION ) ; | |
| 901 | |
| 902 glClearColor(1,1,1,1); | |
| 903 glEnable(GL_CULL_FACE); | |
| 904 glCullFace(GL_BACK); | |
| 905 | |
| 906 glEnable(GL_DEPTH_TEST); | |
| 907 glDepthFunc(GL_LESS); | |
| 908 | |
| 909 glEnable(GL_LIGHT0); | |
| 910 glEnable(GL_NORMALIZE); | |
| 911 glEnable(GL_COLOR_MATERIAL); | |
| 912 | |
| 913 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); | |
| 914 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); | |
| 915 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); | |
| 916 glLightfv(GL_LIGHT0, GL_POSITION, light_position); | |
| 917 | |
| 918 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); | |
| 919 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); | |
| 920 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); | |
| 921 glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess); | |
| 922 | |
| 923 initExtensionEntries(); | |
| 924 | |
| 925 glutMainLoop(); | |
| 926 | |
| 927 #ifdef _MSC_VER | |
| 928 /* DUMP MEMORY LEAK INFORMATION */ | |
| 929 _CrtDumpMemoryLeaks () ; | |
| 930 #endif | |
| 931 | |
| 932 return EXIT_SUCCESS; | |
| 933 } |
