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