Make Android work again - adapt to recent changes and fix use of GL-nonES function
[freeglut] / progs / test-shapes-gles1 / test-shapes-gles1.c
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 &nbsp;</tt> Quit
14       -    <tt>q Q &nbsp;</tt> Quit
15       -    <tt>i I &nbsp;</tt> Show info
16       -    <tt>p P &nbsp;</tt> Toggle perspective or orthographic projection
17       -    <tt>= + &nbsp;</tt> Increase \a slices
18       -    <tt>- _ &nbsp;</tt> Decreate \a slices
19       -    <tt>, < &nbsp;</tt> Decreate \a stacks
20       -    <tt>. > &nbsp;</tt> Increase \a stacks
21       -    <tt>9 ( &nbsp;</tt> Decreate \a depth  (Sierpinski Sponge)
22       -    <tt>0 ) &nbsp;</tt> Increase \a depth  (Sierpinski Sponge)
23       -    <tt>up&nbsp; &nbsp;</tt> Increase "outer radius"
24       -    <tt>down&nbsp;</tt> Decrease "outer radius"
25       -    <tt>left&nbsp;</tt> Decrease "inner radius"
26       -    <tt>right</tt> Increase "inner radius"
27       -    <tt>PgUp&nbsp;</tt> Next shape-drawing function
28       -    <tt>PgDn&nbsp;</tt> Prev shape-drawing function
29
30     \author  Written by Nigel Stewart November 2003
31
32     \author  Portions Copyright (C) 2004, the OpenGLUT project contributors. <br>
33              OpenGLUT branched from freeglut in February, 2004.
34  
35     \image   html openglut_shapes.png OpenGLUT Geometric Shapes Demonstration
36     \include demos/shapes/shapes.c
37 */
38
39 #include <GL/freeglut.h>
40 #include <GL/freeglut_ext.h>
41
42 #include <stdarg.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45
46 #ifdef _MSC_VER
47 /* DUMP MEMORY LEAKS */
48 #include <crtdbg.h>
49 #endif
50
51 /*
52  * This macro is only intended to be used on arrays, of course.
53  */
54 #define NUMBEROF(x) ((sizeof(x))/(sizeof(x[0])))
55
56 #define glRotated glRotatef
57 #define glTranslated glTranslatef
58
59 /*
60  * These global variables control which object is drawn,
61  * and how it is drawn.  No object uses all of these
62  * variables.
63  */
64 static int function_index;
65 static int slices = 16;
66 static int stacks = 16;
67 static double irad = .25;
68 static double orad = 1.0;   /* doubles as size for objects other than Torus */
69 static int depth = 4;
70 static double offset[ 3 ] = { 0, 0, 0 };
71 static GLboolean show_info = GL_TRUE;
72 static float ar;
73 static GLboolean persProject = GL_TRUE;
74 static GLboolean animateXRot = GL_FALSE;
75
76 /*
77  * These one-liners draw particular objects, fetching appropriate
78  * information from the above globals.  They are just thin wrappers
79  * for the FreeGLUT objects.
80  */
81 static void drawSolidTetrahedron(void)         { glutSolidTetrahedron ();                        }
82 static void drawWireTetrahedron(void)          { glutWireTetrahedron ();                         }
83 static void drawSolidCube(void)                { glutSolidCube(orad);                            }  /* orad doubles as size input */
84 static void drawWireCube(void)                 { glutWireCube(orad);                             }  /* orad doubles as size input */
85 static void drawSolidOctahedron(void)          { glutSolidOctahedron ();                         }
86 static void drawWireOctahedron(void)           { glutWireOctahedron ();                          }
87 static void drawSolidDodecahedron(void)        { glutSolidDodecahedron ();                       }
88 static void drawWireDodecahedron(void)         { glutWireDodecahedron ();                        }
89 static void drawSolidRhombicDodecahedron(void) { glutSolidRhombicDodecahedron ();                }
90 static void drawWireRhombicDodecahedron(void)  { glutWireRhombicDodecahedron ();                 }
91 static void drawSolidIcosahedron(void)         { glutSolidIcosahedron ();                        }
92 static void drawWireIcosahedron(void)          { glutWireIcosahedron ();                         }
93 static void drawSolidSierpinskiSponge(void)    { glutSolidSierpinskiSponge (depth, offset, orad);}  /* orad doubles as size input */
94 static void drawWireSierpinskiSponge(void)     { glutWireSierpinskiSponge (depth, offset, orad); }  /* orad doubles as size input */
95 static void drawSolidTorus(void)               { glutSolidTorus(irad,orad,slices,stacks);        }
96 static void drawWireTorus(void)                { glutWireTorus (irad,orad,slices,stacks);        }
97 static void drawSolidSphere(void)              { glutSolidSphere(orad,slices,stacks);            }  /* orad doubles as size input */
98 static void drawWireSphere(void)               { glutWireSphere(orad,slices,stacks);             }  /* orad doubles as size input */
99 static void drawSolidCone(void)                { glutSolidCone(orad,orad,slices,stacks);         }  /* orad doubles as size input */
100 static void drawWireCone(void)                 { glutWireCone(orad,orad,slices,stacks);          }  /* orad doubles as size input */
101 static void drawSolidCylinder(void)            { glutSolidCylinder(orad,orad,slices,stacks);     }  /* orad doubles as size input */
102 static void drawWireCylinder(void)             { glutWireCylinder(orad,orad,slices,stacks);      }  /* orad doubles as size input */
103 static void drawSolidTeapot(void)
104 {   glFrontFace(GL_CW);    glutSolidTeapot(orad);   glFrontFace(GL_CCW);    /* orad doubles as size input */}
105 static void drawWireTeapot(void)
106 {   glFrontFace(GL_CW);    glutWireTeapot(orad);    glFrontFace(GL_CCW);    /* orad doubles as size input */}
107
108 /*
109  * This structure defines an entry in our function-table.
110  */
111 typedef struct
112 {
113     const char * const name;
114     void (*solid) (void);
115     void (*wire)  (void);
116 } entry;
117
118 #define ENTRY(e) {#e, drawSolid##e, drawWire##e}
119 static const entry table [] =
120 {
121     ENTRY (Tetrahedron),
122     ENTRY (Cube),
123     ENTRY (Octahedron),
124     ENTRY (Dodecahedron),
125     ENTRY (RhombicDodecahedron),
126     ENTRY (Icosahedron),
127     ENTRY (SierpinskiSponge),
128     ENTRY (Teapot),
129     ENTRY (Torus),
130     ENTRY (Sphere),
131     ENTRY (Cone),
132     ENTRY (Cylinder),
133     /* ENTRY (Cuboctahedron) */
134 };
135 #undef ENTRY
136
137 /*!
138     Does printf()-like work using freeglut
139     glutBitmapString().  Uses a fixed font.  Prints
140     at the indicated row/column position.
141
142     Limitation: Cannot address pixels.
143     Limitation: Renders in screen coords, not model coords.
144 */
145 static void shapesPrintf (int row, int col, const char *fmt, ...)
146 {
147 }
148
149 /* GLUT callback Handlers */
150
151 static void
152 resize(int width, int height)
153 {
154     ar = (float) width / (float) height;
155
156     glViewport(0, 0, width, height);
157 }
158
159 static void display(void)
160 {
161     const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
162     const double a = t*90.0;
163     const double b = (animateXRot?t:1)*60.0;
164
165     glMatrixMode(GL_PROJECTION);
166     glLoadIdentity();
167     glFrustumf(-ar, ar, -1.0, 1.0, 2.0, 100.0);
168     glMatrixMode(GL_MODELVIEW);
169     glLoadIdentity();
170
171     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
172
173     glEnable(GL_LIGHTING);
174
175     glColor4f(1,0,0,1);
176
177     glPushMatrix();
178         glTranslated(0,1.2,-6);
179         glRotated(b,1,0,0);
180         glRotated(a,0,0,1);
181         table [function_index].solid ();
182     glPopMatrix();
183
184     glPushMatrix();
185         glTranslated(0,-1.2,-6);
186         glRotated(b,1,0,0);
187         glRotated(a,0,0,1);
188         table [function_index].wire ();
189     glPopMatrix();
190
191     glDisable(GL_LIGHTING);
192     glColor4f(0.1,0.1,0.4,1.0);
193
194     glutSwapBuffers();
195 }
196
197
198 static void
199 key(unsigned char key, int x, int y)
200 {
201     switch (key)
202     {
203     case 27 :
204     case 'Q':
205     case 'q': glutLeaveMainLoop () ;      break;
206
207     case 'I':
208     case 'i': show_info = ( show_info == GL_TRUE ) ? GL_FALSE : GL_TRUE; break;
209
210     case '=':
211     case '+': slices++; printf("%d,%d\n", slices, stacks); break;
212
213     case '-':
214     case '_': if( slices > -1 ) slices--; break;
215
216     case ',':
217     case '<': if( stacks > -1 ) stacks--; break;
218
219     case '.':
220     case '>': stacks++;                   break;
221
222     case '9': 
223     case '(': if( depth > -1 ) depth--;   break;
224
225     case '0': 
226     case ')': ++depth;                    break;
227
228     case 'P':
229     case 'p': persProject=!persProject;   break;
230
231     case 'R':
232     case 'r': animateXRot=!animateXRot;   break;
233
234     default:
235         break;
236     }
237
238     glutPostRedisplay();
239 }
240
241 static void special (int key, int x, int y)
242 {
243     switch (key)
244     {
245     case GLUT_KEY_PAGE_UP:    ++function_index; break;
246     case GLUT_KEY_PAGE_DOWN:  --function_index; break;
247     case GLUT_KEY_UP:         orad *= 2;        break;
248     case GLUT_KEY_DOWN:       orad /= 2;        break;
249
250     case GLUT_KEY_RIGHT:      irad *= 2;        break;
251     case GLUT_KEY_LEFT:       irad /= 2;        break;
252
253     default:
254         break;
255     }
256
257     if (0 > function_index)
258         function_index = NUMBEROF (table) - 1;
259
260     if (NUMBEROF (table) <= ( unsigned )function_index)
261         function_index = 0;
262 }
263
264
265 static void
266 idle(void)
267 {
268     glutPostRedisplay();
269 }
270
271 static void
272 onMouseClick(int button, int state, int x, int y) {
273   if (state == GLUT_DOWN)
274     special(GLUT_KEY_PAGE_UP, 0, 0);
275 }
276
277 const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
278 const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
279 const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
280 const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
281
282 const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
283 const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
284 const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
285 const GLfloat high_shininess[] = { 100.0f };
286
287 /* Program entry point */
288
289 void init_context() {
290     printf("init_context\n"); fflush(stdout);
291     glClearColor(1,1,1,1);
292     glEnable(GL_CULL_FACE);
293     glCullFace(GL_BACK);
294
295     glEnable(GL_DEPTH_TEST);
296     glDepthFunc(GL_LESS);
297
298     glEnable(GL_LIGHT0);
299     glEnable(GL_NORMALIZE);
300     glEnable(GL_COLOR_MATERIAL);
301
302     glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
303     glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
304     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
305     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
306
307     glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
308     glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
309     glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
310     glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
311 }
312
313 int
314 main(int argc, char *argv[])
315 {
316     glutInitWindowSize(640,480);
317     glutInitWindowPosition(40,40);
318     glutInit(&argc, argv);
319     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
320
321     glutCreateWindow("FreeGLUT Shapes");
322
323     glutReshapeFunc(resize);
324     glutDisplayFunc(display);
325     glutKeyboardFunc(key);
326     glutSpecialFunc(special);
327     glutIdleFunc(idle);
328     glutMouseFunc(onMouseClick);
329     glutInitContextFunc(init_context);
330
331     glutSetOption ( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION ) ;
332
333     glutMainLoop();
334
335 #ifdef _MSC_VER
336     /* DUMP MEMORY LEAK INFORMATION */
337     _CrtDumpMemoryLeaks () ;
338 #endif
339
340     return EXIT_SUCCESS;
341 }