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