child window now only used for keyboard callbacks and setting focus in
[freeglut] / progs / demos / One / one.c
1 /*
2  * one.c
3  *
4  * Hey! This was the original file where freeglut development started. Just
5  * note what I have written here at the time. And see the creation date :)
6  *
7  * : This is a wrapper. I still have to figure out
8  * : how to build shared libraries under *nix :)
9  *
10  * Copyright (c) 1999 by Pawel W. Olszta
11  * Written by Pawel W. Olszta, <olszta@sourceforge.net>
12  * Creation date: czw gru  2 11:58:41 CET 1999
13  */
14
15 #ifdef HAVE_CONFIG_H
16 #include <config.h>
17 #endif
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <GL/freeglut.h>
23
24 int g_LeaveGameMode = 0;
25 int g_InGameMode = 0;
26 int g_mainwin, g_sw1, g_sw2;
27
28 /*
29  * Call this function to have some text drawn at given coordinates
30  */
31 void PrintText( int nX, int nY, char* pszText )
32 {
33     int lines;
34     char *p;
35
36     /*
37      * Prepare the OpenGL state
38      */
39     glDisable( GL_LIGHTING );
40     glDisable( GL_DEPTH_TEST );
41     glMatrixMode( GL_PROJECTION );
42     glPushMatrix();
43     glLoadIdentity();
44
45     /*
46      * Have an orthogonal projection matrix set
47      */
48     glOrtho( 0, glutGet( GLUT_WINDOW_WIDTH ),
49              0, glutGet( GLUT_WINDOW_HEIGHT ),
50              -1, +1
51     );
52
53     /*
54      * Now the matrix mode
55      */
56     glMatrixMode( GL_MODELVIEW );
57     glPushMatrix();
58     glLoadIdentity();
59
60     /*
61      * Now the main text
62      */
63     glColor3ub( 0, 0, 0 );
64     glRasterPos2i( nX, nY );
65
66     for( p=pszText, lines=0; *p; p++ )
67     {
68         if( *p == '\n' )
69         {
70             lines++;
71             glRasterPos2i( nX, nY-(lines*18) );
72         }
73
74         glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18,  *p );
75     }
76
77     /*
78      * Revert to the old matrix modes
79      */
80     glMatrixMode( GL_PROJECTION );
81     glPopMatrix();
82
83     glMatrixMode( GL_MODELVIEW );
84     glPopMatrix();
85
86     /*
87      * Restore the old OpenGL states
88      */
89     glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
90     glEnable( GL_DEPTH_TEST );
91     glEnable( GL_LIGHTING );
92 }
93
94 /*
95  * This is the display routine for our sample FreeGLUT windows
96  */
97 static float g_fTime = 0.0f;
98
99 void SampleDisplay( void )
100 {
101     int win = glutGetWindow();
102
103     if (win==g_sw1)
104     {
105         /*
106          * Clear the screen
107          */
108         glClearColor(0.7f,0.7f,0.7f,1);
109         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
110         glutPostWindowRedisplay(g_mainwin);
111     }
112     else if (win==g_sw2)
113     {
114         /*
115         * Clear the screen
116         */
117         glClearColor(0.3f,0.3f,0.3f,1);
118         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
119         glutPostWindowRedisplay(g_mainwin);
120     }
121     else
122     {
123         /*
124          * Clear the screen
125          */
126         glClearColor( 0, 0.5, 1, 1 );
127         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
128
129         /*
130          * Have the cube rotated
131          */
132         glMatrixMode( GL_MODELVIEW );
133         glPushMatrix();
134
135         glRotatef( g_fTime, 0, 0, 1 );
136         glRotatef( g_fTime, 0, 1, 0 );
137         glRotatef( g_fTime, 1, 0, 0 );
138
139         /*
140          * And then drawn...
141          */
142         glColor3f( 1, 1, 0 );
143         /* glutWireCube( 20.0 ); */
144         glutWireTeapot( 20.0 );
145         /* glutWireSpher( 15.0, 15, 15 ); */
146         /* glColor3f( 0, 1, 0 ); */
147         /* glutWireCube( 30.0 ); */
148         /* glutSolidCone( 10, 20, 10, 2 ); */
149
150         /*
151          * Don't forget about the model-view matrix
152          */
153         glPopMatrix( );
154
155         /*
156          * Draw a silly text
157          */
158         if( g_InGameMode == 0 )
159             PrintText( 20, 20, "Hello there cruel world!" );
160         else
161             PrintText( 20, 20, "Press ESC to leave the game mode!" );
162     }
163
164     /*
165      * And swap this context's buffers
166      */
167     glutSwapBuffers( );
168     glutPostWindowRedisplay(win);
169 }
170
171 /*
172  * This is a sample idle function
173  */
174 void SampleIdle( void )
175 {
176     g_fTime += 0.5f;
177
178     if( g_LeaveGameMode == 1 )
179     {
180         glutLeaveGameMode( );
181         g_LeaveGameMode = 0;
182         g_InGameMode = 0;
183     }
184 }
185
186 void SampleEntry(int state)
187 {
188     int window = glutGetWindow () ;
189     printf ( "Window %d Entry Callback: %d\n", window, state ) ;
190 }
191
192 /*
193  * The reshape function
194  */
195 void SampleReshape( int nWidth, int nHeight )
196 {
197     GLfloat fAspect = (GLfloat) nHeight / (GLfloat) nWidth;
198     GLfloat fPos[ 4 ] = { 0.0f, 0.0f, 10.0f, 0.0f };
199     GLfloat fCol[ 4 ] = { 0.5f, 1.0f,  0.0f, 1.0f };
200
201     /*
202      * Update the viewport first
203      */
204     glViewport( 0, 0, nWidth, nHeight );
205
206     /*
207      * Then the projection matrix
208      */
209     glMatrixMode( GL_PROJECTION );
210     glLoadIdentity();
211     glFrustum( -1.0, 1.0, -fAspect, fAspect, 1.0, 80.0 );
212
213     /*
214      * Move back the camera a bit
215      */
216     glMatrixMode( GL_MODELVIEW );
217     glLoadIdentity( );
218     glTranslatef( 0.0, 0.0, -40.0f );
219
220     /*
221      * Enable some features...
222      */
223     glEnable( GL_CULL_FACE );
224     glEnable( GL_DEPTH_TEST );
225     glEnable( GL_NORMALIZE );
226
227     /*
228      * Set up some lighting
229      */
230     glLightfv( GL_LIGHT0, GL_POSITION, fPos );
231     glEnable( GL_LIGHTING );
232     glEnable( GL_LIGHT0 );
233
234     /*
235      * Set up a sample material
236      */
237     glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fCol );
238 }
239
240 /*
241  * A sample keyboard callback
242  */
243 void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY )
244 {
245     printf( "SampleKeyboard(): keypress '%c' at (%i,%i)\n",
246             cChar, nMouseX, nMouseY );
247 }
248
249 /*
250  * A sample keyboard callback (for game mode window)
251  */
252 void SampleGameModeKeyboard( unsigned char cChar, int nMouseX, int nMouseY )
253 {
254     if( cChar == 27 )
255         g_LeaveGameMode = 1;
256 }
257
258
259 /*
260  * A sample special callback
261  */
262 void SampleSpecial( int nSpecial, int nMouseX, int nMouseY )
263 {
264     printf( "SampleSpecial(): special keypress %i at (%i,%i)\n",
265             nSpecial, nMouseX, nMouseY );
266 }
267
268 /*
269  * A sample menu callback
270  */
271 void SampleMenu( int menuID )
272 {
273     /*
274      * Just print something funny
275      */
276     printf( "SampleMenu() callback executed, menuID is %i\n", menuID );
277 }
278
279 /*
280  * The sample's entry point
281  */
282 int main( int argc, char** argv )
283 {
284     int menuID, subMenuA, subMenuB;
285
286     glutInitDisplayString( "stencil~2 rgb double depth>=16 samples" );
287     glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
288     glutInitWindowPosition( 100, 100 );
289
290     glutInit( &argc, argv );
291
292     glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);
293
294     subMenuA = glutCreateMenu( SampleMenu );
295     glutAddMenuEntry( "Sub menu A1 (01)", 1 );
296     glutAddMenuEntry( "Sub menu A2 (02)", 2 );
297     glutAddMenuEntry( "Sub menu A3 (03)", 3 );
298
299     subMenuB = glutCreateMenu( SampleMenu );
300     glutAddMenuEntry( "Sub menu B1 (04)", 4 );
301     glutAddMenuEntry( "Sub menu B2 (05)", 5 );
302     glutAddMenuEntry( "Sub menu B3 (06)", 6 );
303     glutAddSubMenu( "Going to sub menu A", subMenuA );
304
305     menuID = glutCreateMenu( SampleMenu );
306     glutAddMenuEntry( "Entry one",   1 );
307     glutAddMenuEntry( "Entry two",   2 );
308     glutAddMenuEntry( "Entry three", 3 );
309     glutAddMenuEntry( "Entry four",  4 );
310     glutAddMenuEntry( "Entry five",  5 );
311     glutAddSubMenu( "Enter sub menu A", subMenuA );
312     glutAddSubMenu( "Enter sub menu B", subMenuB );
313
314     glutCreateWindow( "Hello world!" );
315     glutDisplayFunc( SampleDisplay );
316     glutReshapeFunc( SampleReshape );
317     glutKeyboardFunc( SampleKeyboard );
318     glutSpecialFunc( SampleSpecial );
319     glutIdleFunc( SampleIdle );
320     glutEntryFunc( SampleEntry );
321     glutAttachMenu( GLUT_LEFT_BUTTON );
322
323     glutInitWindowPosition( 200, 200 );
324     g_mainwin = glutCreateWindow( "I am not Jan B." );
325     glutDisplayFunc( SampleDisplay );
326     glutReshapeFunc( SampleReshape );
327     glutKeyboardFunc( SampleKeyboard );
328     glutSpecialFunc( SampleSpecial );
329     glutIdleFunc( SampleIdle );
330     glutAttachMenu( GLUT_LEFT_BUTTON );
331     glutSetMenu(subMenuA);
332     glutAttachMenu( GLUT_RIGHT_BUTTON );
333
334     g_sw1=glutCreateSubWindow(g_mainwin,200,0,100,100);
335     glutDisplayFunc( SampleDisplay );
336     glutSetMenu(subMenuB);
337     glutAttachMenu( GLUT_LEFT_BUTTON);
338
339     g_sw2=glutCreateSubWindow(g_sw1,50,0,50,50);
340     glutDisplayFunc( SampleDisplay );
341     glutSetMenu(menuID);
342     glutAttachMenu( GLUT_RIGHT_BUTTON );
343
344     printf( "Testing game mode string parsing, don't panic!\n" );
345     glutGameModeString( "320x240:32@100" );
346     glutGameModeString( "640x480:16@72" );
347     glutGameModeString( "1024x768" );
348     glutGameModeString( ":32@120" );
349     glutGameModeString( "Toudi glupcze, Danwin bedzie moj!" );
350     
351     glutGameModeString( "640x480:37@300" );    /* this one should fail */
352     glutEnterGameMode();
353
354     glutGameModeString( "800x600" );    /* this one is likely to succeed */
355     glutEnterGameMode();
356
357     if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE))
358         g_InGameMode = 1;
359     glutDisplayFunc( SampleDisplay );
360     glutReshapeFunc( SampleReshape );
361     glutKeyboardFunc( SampleGameModeKeyboard );
362     glutIdleFunc( SampleIdle );
363
364     printf( "current window is %ix%i at (%i,%i)\n",
365         glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT ),
366         glutGet( GLUT_WINDOW_X ), glutGet( GLUT_WINDOW_Y )
367     );
368
369     /*
370      * Enter the main FreeGLUT processing loop
371      */
372     glutMainLoop();
373
374     printf( "glutMainLoop() termination works fine!\n" );
375
376     /*
377      * This is never reached in FreeGLUT. Is that good?
378      */
379     return EXIT_SUCCESS;
380 }
381
382 /*** END OF FILE ***/