Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 855 lines (706 sloc) 23.02 kb
3249f81 @elmindreda Initial import of 2.7 Lite.
elmindreda authored
1 //========================================================================
2 // This is a small test application for GLFW.
3 // This is an OpenGL port of the famous "PONG" game (the first computer
4 // game ever?). It is very simple, and could be improved alot. It was
5 // created in order to show off the gaming capabilities of GLFW.
6 //========================================================================
7
8 #include <GL/glfw.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12
13
14 //========================================================================
15 // Constants
16 //========================================================================
17
18 // Screen resolution
19 #define WIDTH 640
20 #define HEIGHT 480
21
22 // Player size (units)
23 #define PLAYER_XSIZE 0.05f
24 #define PLAYER_YSIZE 0.15f
25
26 // Ball size (units)
27 #define BALL_SIZE 0.02f
28
29 // Maximum player movement speed (units / second)
30 #define MAX_SPEED 1.5f
31
32 // Player movement acceleration (units / seconds^2)
33 #define ACCELERATION 4.0f
34
35 // Player movement deceleration (units / seconds^2)
36 #define DECELERATION 2.0f
37
38 // Ball movement speed (units / second)
39 #define BALL_SPEED 0.4f
40
41 // Menu options
42 #define MENU_NONE 0
43 #define MENU_PLAY 1
44 #define MENU_QUIT 2
45
46 // Game events
47 #define NOBODY_WINS 0
48 #define PLAYER1_WINS 1
49 #define PLAYER2_WINS 2
50
51 // Winner ID
52 #define NOBODY 0
53 #define PLAYER1 1
54 #define PLAYER2 2
55
56 // Camera positions
57 #define CAMERA_CLASSIC 0
58 #define CAMERA_ABOVE 1
59 #define CAMERA_SPECTATOR 2
60 #define CAMERA_DEFAULT CAMERA_CLASSIC
61
62
63 //========================================================================
64 // Textures
65 //========================================================================
66
67 #define TEX_TITLE 0
68 #define TEX_MENU 1
69 #define TEX_INSTR 2
70 #define TEX_WINNER1 3
71 #define TEX_WINNER2 4
72 #define TEX_FIELD 5
73 #define NUM_TEXTURES 6
74
75 // Texture names
76 char * tex_name[ NUM_TEXTURES ] = {
77 "pong3d_title.tga",
78 "pong3d_menu.tga",
79 "pong3d_instr.tga",
80 "pong3d_winner1.tga",
81 "pong3d_winner2.tga",
82 "pong3d_field.tga"
83 };
84
85 // OpenGL texture object IDs
86 GLuint tex_id[ NUM_TEXTURES ];
87
88
89 //========================================================================
90 // Global variables
91 //========================================================================
92
93 // Display information
94 int width, height;
95
96 // Frame information
97 double thistime, oldtime, dt, starttime;
98
99 // Camera information
100 int camerapos;
101
102 // Player information
103 struct {
104 double ypos; // -1.0 to +1.0
105 double yspeed; // -MAX_SPEED to +MAX_SPEED
106 } player1, player2;
107
108 // Ball information
109 struct {
110 double xpos, ypos;
111 double xspeed, yspeed;
112 } ball;
113
114 // And the winner is...
115 int winner;
116
117 // Lighting configuration
118 const GLfloat env_ambient[4] = {1.0f,1.0f,1.0f,1.0f};
119 const GLfloat light1_position[4] = {-3.0f,3.0f,2.0f,1.0f};
120 const GLfloat light1_diffuse[4] = {1.0f,1.0f,1.0f,0.0f};
121 const GLfloat light1_ambient[4] = {0.0f,0.0f,0.0f,0.0f};
122
123 // Object material properties
124 const GLfloat player1_diffuse[4] = {1.0f,0.3f,0.3f,1.0f};
125 const GLfloat player1_ambient[4] = {0.3f,0.1f,0.0f,1.0f};
126 const GLfloat player2_diffuse[4] = {0.3f,1.0f,0.3f,1.0f};
127 const GLfloat player2_ambient[4] = {0.1f,0.3f,0.1f,1.0f};
128 const GLfloat ball_diffuse[4] = {1.0f,1.0f,0.5f,1.0f};
129 const GLfloat ball_ambient[4] = {0.3f,0.3f,0.1f,1.0f};
130 const GLfloat border_diffuse[4] = {0.3f,0.3f,1.0f,1.0f};
131 const GLfloat border_ambient[4] = {0.1f,0.1f,0.3f,1.0f};
132 const GLfloat floor_diffuse[4] = {1.0f,1.0f,1.0f,1.0f};
133 const GLfloat floor_ambient[4] = {0.3f,0.3f,0.3f,1.0f};
134
135
136 //========================================================================
137 // LoadTextures() - Load textures from disk and upload to OpenGL card
138 //========================================================================
139
140 GLboolean LoadTextures( void )
141 {
142 int i;
143
144 // Generate texture objects
145 glGenTextures( NUM_TEXTURES, tex_id );
146
147 // Load textures
148 for( i = 0; i < NUM_TEXTURES; i ++ )
149 {
150 // Select texture object
151 glBindTexture( GL_TEXTURE_2D, tex_id[ i ] );
152
153 // Set texture parameters
154 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
155 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
156 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
157 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
158
159 // Upload texture from file to texture memory
160 if( !glfwLoadTexture2D( tex_name[ i ], 0 ) )
161 {
162 fprintf( stderr, "Failed to load texture %s\n", tex_name[ i ] );
163 return GL_FALSE;
164 }
165 }
166
167 return GL_TRUE;
168 }
169
170
171 //========================================================================
172 // DrawImage() - Draw a 2D image as a texture
173 //========================================================================
174
175 void DrawImage( int texnum, float x1, float x2, float y1, float y2 )
176 {
177 glEnable( GL_TEXTURE_2D );
178 glBindTexture( GL_TEXTURE_2D, tex_id[ texnum ] );
179 glBegin( GL_QUADS );
180 glTexCoord2f( 0.0f, 1.0f );
181 glVertex2f( x1, y1 );
182 glTexCoord2f( 1.0f, 1.0f );
183 glVertex2f( x2, y1 );
184 glTexCoord2f( 1.0f, 0.0f );
185 glVertex2f( x2, y2 );
186 glTexCoord2f( 0.0f, 0.0f );
187 glVertex2f( x1, y2 );
188 glEnd();
189 glDisable( GL_TEXTURE_2D );
190 }
191
192
193 //========================================================================
194 // GameMenu() - Game menu (returns menu option)
195 //========================================================================
196
197 int GameMenu( void )
198 {
199 int option;
200
201 // Enable sticky keys
202 glfwEnable( GLFW_STICKY_KEYS );
203
204 // Wait for a game menu key to be pressed
205 do
206 {
207 // Get window size
208 glfwGetWindowSize( &width, &height );
209
210 // Set viewport
211 glViewport( 0, 0, width, height );
212
213 // Clear display
214 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
215 glClear( GL_COLOR_BUFFER_BIT );
216
217 // Setup projection matrix
218 glMatrixMode( GL_PROJECTION );
219 glLoadIdentity();
220 glOrtho( 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f );
221
222 // Setup modelview matrix
223 glMatrixMode( GL_MODELVIEW );
224 glLoadIdentity();
225
226 // Display title
227 glColor3f( 1.0f, 1.0f, 1.0f );
228 DrawImage( TEX_TITLE, 0.1f, 0.9f, 0.0f, 0.3f );
229
230 // Display menu
231 glColor3f( 1.0f, 1.0f, 0.0f );
232 DrawImage( TEX_MENU, 0.38f, 0.62f, 0.35f, 0.5f );
233
234 // Display instructions
235 glColor3f( 0.0f, 1.0f, 1.0f );
236 DrawImage( TEX_INSTR, 0.32f, 0.68f, 0.65f, 0.85f );
237
238 // Swap buffers
239 glfwSwapBuffers();
240
241 // Check for keys
242 if( glfwGetKey( 'Q' ) || !glfwGetWindowParam( GLFW_OPENED ) )
243 {
244 option = MENU_QUIT;
245 }
246 else if( glfwGetKey( GLFW_KEY_F1 ) )
247 {
248 option = MENU_PLAY;
249 }
250 else
251 {
252 option = MENU_NONE;
253 }
254
255 // To avoid horrible busy waiting, sleep for at least 20 ms
256 glfwSleep( 0.02 );
257 }
258 while( option == MENU_NONE );
259
260 // Disable sticky keys
261 glfwDisable( GLFW_STICKY_KEYS );
262
263 return option;
264 }
265
266
267 //========================================================================
268 // NewGame() - Initialize a new game
269 //========================================================================
270
271 void NewGame( void )
272 {
273 // Frame information
274 starttime = thistime = glfwGetTime();
275
276 // Camera information
277 camerapos = CAMERA_DEFAULT;
278
279 // Player 1 information
280 player1.ypos = 0.0;
281 player1.yspeed = 0.0;
282
283 // Player 2 information
284 player2.ypos = 0.0;
285 player2.yspeed = 0.0;
286
287 // Ball information
288 ball.xpos = -1.0 + PLAYER_XSIZE;
289 ball.ypos = player1.ypos;
290 ball.xspeed = 1.0;
291 ball.yspeed = 1.0;
292 }
293
294
295 //========================================================================
296 // PlayerControl() - Player control
297 //========================================================================
298
299 void PlayerControl( void )
300 {
301 float joy1pos[ 2 ], joy2pos[ 2 ];
302
303 // Get joystick X & Y axis positions
304 glfwGetJoystickPos( GLFW_JOYSTICK_1, joy1pos, 2 );
305 glfwGetJoystickPos( GLFW_JOYSTICK_2, joy2pos, 2 );
306
307 // Player 1 control
308 if( glfwGetKey( 'A' ) || joy1pos[ 1 ] > 0.2f )
309 {
310 player1.yspeed += dt * ACCELERATION;
311 if( player1.yspeed > MAX_SPEED )
312 {
313 player1.yspeed = MAX_SPEED;
314 }
315 }
316 else if( glfwGetKey( 'Z' ) || joy1pos[ 1 ] < -0.2f )
317 {
318 player1.yspeed -= dt * ACCELERATION;
319 if( player1.yspeed < -MAX_SPEED )
320 {
321 player1.yspeed = -MAX_SPEED;
322 }
323 }
324 else
325 {
326 player1.yspeed /= exp( DECELERATION * dt );
327 }
328
329 // Player 2 control
330 if( glfwGetKey( 'K' ) || joy2pos[ 1 ] > 0.2f )
331 {
332 player2.yspeed += dt * ACCELERATION;
333 if( player2.yspeed > MAX_SPEED )
334 {
335 player2.yspeed = MAX_SPEED;
336 }
337 }
338 else if( glfwGetKey( 'M' ) || joy2pos[ 1 ] < -0.2f )
339 {
340 player2.yspeed -= dt * ACCELERATION;
341 if( player2.yspeed < -MAX_SPEED )
342 {
343 player2.yspeed = -MAX_SPEED;
344 }
345 }
346 else
347 {
348 player2.yspeed /= exp( DECELERATION * dt );
349 }
350
351 // Update player 1 position
352 player1.ypos += dt * player1.yspeed;
353 if( player1.ypos > 1.0 - PLAYER_YSIZE )
354 {
355 player1.ypos = 1.0 - PLAYER_YSIZE;
356 player1.yspeed = 0.0;
357 }
358 else if( player1.ypos < -1.0 + PLAYER_YSIZE )
359 {
360 player1.ypos = -1.0 + PLAYER_YSIZE;
361 player1.yspeed = 0.0;
362 }
363
364 // Update player 2 position
365 player2.ypos += dt * player2.yspeed;
366 if( player2.ypos > 1.0 - PLAYER_YSIZE )
367 {
368 player2.ypos = 1.0 - PLAYER_YSIZE;
369 player2.yspeed = 0.0;
370 }
371 else if( player2.ypos < -1.0 + PLAYER_YSIZE )
372 {
373 player2.ypos = -1.0 + PLAYER_YSIZE;
374 player2.yspeed = 0.0;
375 }
376 }
377
378
379 //========================================================================
380 // BallControl() - Ball control
381 //========================================================================
382
383 int BallControl( void )
384 {
385 int event;
386 double ballspeed;
387
388 // Calculate new ball speed
389 ballspeed = BALL_SPEED * (1.0 + 0.02*(thistime-starttime));
390 ball.xspeed = ball.xspeed > 0 ? ballspeed : -ballspeed;
391 ball.yspeed = ball.yspeed > 0 ? ballspeed : -ballspeed;
392 ball.yspeed *= 0.74321;
393
394 // Update ball position
395 ball.xpos += dt * ball.xspeed;
396 ball.ypos += dt * ball.yspeed;
397
398 // Did the ball hit a top/bottom wall?
399 if( ball.ypos >= 1.0 )
400 {
401 ball.ypos = 2.0 - ball.ypos;
402 ball.yspeed = -ball.yspeed;
403 }
404 else if( ball.ypos <= -1.0 )
405 {
406 ball.ypos = -2.0 - ball.ypos;
407 ball.yspeed = -ball.yspeed;
408 }
409
410 // Did the ball hit/miss a player?
411 event = NOBODY_WINS;
412
413 // Is the ball entering the player 1 goal?
414 if( ball.xpos < -1.0 + PLAYER_XSIZE )
415 {
416 // Did player 1 catch the ball?
417 if( ball.ypos > (player1.ypos-PLAYER_YSIZE) &&
418 ball.ypos < (player1.ypos+PLAYER_YSIZE) )
419 {
420 ball.xpos = -2.0 + 2.0*PLAYER_XSIZE - ball.xpos;
421 ball.xspeed = -ball.xspeed;
422 }
423 else
424 {
425 event = PLAYER2_WINS;
426 }
427 }
428
429 // Is the ball entering the player 2 goal?
430 if( ball.xpos > 1.0 - PLAYER_XSIZE )
431 {
432 // Did player 2 catch the ball?
433 if( ball.ypos > (player2.ypos-PLAYER_YSIZE) &&
434 ball.ypos < (player2.ypos+PLAYER_YSIZE) )
435 {
436 ball.xpos = 2.0 - 2.0*PLAYER_XSIZE - ball.xpos;
437 ball.xspeed = -ball.xspeed;
438 }
439 else
440 {
441 event = PLAYER1_WINS;
442 }
443 }
444
445 return event;
446 }
447
448
449 //========================================================================
450 // DrawBox() - Draw a 3D box
451 //========================================================================
452
453 #define TEX_SCALE 4.0f
454
455
456 void DrawBox( float x1, float y1, float z1, float x2, float y2, float z2 )
457 {
458 // Draw six sides of a cube
459 glBegin( GL_QUADS );
460 // Side 1 (down)
461 glNormal3f( 0.0f, 0.0f, -1.0f );
462 glTexCoord2f( 0.0f, 0.0f );
463 glVertex3f( x1,y2,z1 );
464 glTexCoord2f( TEX_SCALE, 0.0f );
465 glVertex3f( x2,y2,z1 );
466 glTexCoord2f( TEX_SCALE, TEX_SCALE );
467 glVertex3f( x2,y1,z1 );
468 glTexCoord2f( 0.0f, TEX_SCALE );
469 glVertex3f( x1,y1,z1 );
470 // Side 2 (up)
471 glNormal3f( 0.0f, 0.0f, 1.0f );
472 glTexCoord2f( 0.0f, 0.0f );
473 glVertex3f( x1,y1,z2 );
474 glTexCoord2f( TEX_SCALE, 0.0f );
475 glVertex3f( x2,y1,z2 );
476 glTexCoord2f( TEX_SCALE, TEX_SCALE );
477 glVertex3f( x2,y2,z2 );
478 glTexCoord2f( 0.0f, TEX_SCALE );
479 glVertex3f( x1,y2,z2 );
480 // Side 3 (backward)
481 glNormal3f( 0.0f, -1.0f, 0.0f );
482 glTexCoord2f( 0.0f, 0.0f );
483 glVertex3f( x1,y1,z1 );
484 glTexCoord2f( TEX_SCALE, 0.0f );
485 glVertex3f( x2,y1,z1 );
486 glTexCoord2f( TEX_SCALE, TEX_SCALE );
487 glVertex3f( x2,y1,z2 );
488 glTexCoord2f( 0.0f, TEX_SCALE );
489 glVertex3f( x1,y1,z2 );
490 // Side 4 (forward)
491 glNormal3f( 0.0f, 1.0f, 0.0f );
492 glTexCoord2f( 0.0f, 0.0f );
493 glVertex3f( x1,y2,z2 );
494 glTexCoord2f( TEX_SCALE, 0.0f );
495 glVertex3f( x2,y2,z2 );
496 glTexCoord2f( TEX_SCALE, TEX_SCALE );
497 glVertex3f( x2,y2,z1 );
498 glTexCoord2f( 0.0f, TEX_SCALE );
499 glVertex3f( x1,y2,z1 );
500 // Side 5 (left)
501 glNormal3f( -1.0f, 0.0f, 0.0f );
502 glTexCoord2f( 0.0f, 0.0f );
503 glVertex3f( x1,y1,z2 );
504 glTexCoord2f( TEX_SCALE, 0.0f );
505 glVertex3f( x1,y2,z2 );
506 glTexCoord2f( TEX_SCALE, TEX_SCALE );
507 glVertex3f( x1,y2,z1 );
508 glTexCoord2f( 0.0f, TEX_SCALE );
509 glVertex3f( x1,y1,z1 );
510 // Side 6 (right)
511 glNormal3f( 1.0f, 0.0f, 0.0f );
512 glTexCoord2f( 0.0f, 0.0f );
513 glVertex3f( x2,y1,z1 );
514 glTexCoord2f( TEX_SCALE, 0.0f );
515 glVertex3f( x2,y2,z1 );
516 glTexCoord2f( TEX_SCALE, TEX_SCALE );
517 glVertex3f( x2,y2,z2 );
518 glTexCoord2f( 0.0f, TEX_SCALE );
519 glVertex3f( x2,y1,z2 );
520 glEnd();
521 }
522
523
524 //========================================================================
525 // UpdateDisplay() - Draw graphics (all game related OpenGL stuff goes
526 // here)
527 //========================================================================
528
529 void UpdateDisplay( void )
530 {
531 // Get window size
532 glfwGetWindowSize( &width, &height );
533
534 // Set viewport
535 glViewport( 0, 0, width, height );
536
537 // Clear display
538 glClearColor( 0.02f, 0.02f, 0.02f, 0.0f );
539 glClearDepth( 1.0f );
540 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
541
542 // Setup projection matrix
543 glMatrixMode( GL_PROJECTION );
544 glLoadIdentity();
545 gluPerspective(
546 55.0f, // Angle of view
547 (GLfloat)width/(GLfloat)height, // Aspect
548 1.0f, // Near Z
549 100.0f // Far Z
550 );
551
552 // Setup modelview matrix
553 glMatrixMode( GL_MODELVIEW );
554 glLoadIdentity();
555 switch( camerapos )
556 {
557 default:
558 case CAMERA_CLASSIC:
559 gluLookAt(
560 0.0f, 0.0f, 2.5f,
561 0.0f, 0.0f, 0.0f,
562 0.0f, 1.0f, 0.0f
563 );
564 break;
565 case CAMERA_ABOVE:
566 gluLookAt(
567 0.0f, 0.0f, 2.5f,
568 (float)ball.xpos, (float)ball.ypos, 0.0f,
569 0.0f, 1.0f, 0.0f
570 );
571 break;
572 case CAMERA_SPECTATOR:
573 gluLookAt(
574 0.0f, -2.0, 1.2f,
575 (float)ball.xpos, (float)ball.ypos, 0.0f,
576 0.0f, 0.0f, 1.0f
577 );
578 break;
579 }
580
581 // Enable depth testing
582 glEnable( GL_DEPTH_TEST );
583 glDepthFunc( GL_LEQUAL );
584
585 // Enable lighting
586 glEnable( GL_LIGHTING );
587 glLightModelfv( GL_LIGHT_MODEL_AMBIENT, env_ambient );
588 glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
589 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
590 glLightfv( GL_LIGHT1, GL_POSITION, light1_position );
591 glLightfv( GL_LIGHT1, GL_DIFFUSE, light1_diffuse );
592 glLightfv( GL_LIGHT1, GL_AMBIENT, light1_ambient );
593 glEnable( GL_LIGHT1 );
594
595 // Front face is counter-clock-wise
596 glFrontFace( GL_CCW );
597
598 // Enable face culling (not necessary, but speeds up rendering)
599 glCullFace( GL_BACK );
600 glEnable( GL_CULL_FACE );
601
602 // Draw Player 1
603 glMaterialfv( GL_FRONT, GL_DIFFUSE, player1_diffuse );
604 glMaterialfv( GL_FRONT, GL_AMBIENT, player1_ambient );
605 DrawBox( -1.f, (GLfloat)player1.ypos-PLAYER_YSIZE, 0.f,
606 -1.f+PLAYER_XSIZE, (GLfloat)player1.ypos+PLAYER_YSIZE, 0.1f );
607
608 // Draw Player 2
609 glMaterialfv( GL_FRONT, GL_DIFFUSE, player2_diffuse );
610 glMaterialfv( GL_FRONT, GL_AMBIENT, player2_ambient );
611 DrawBox( 1.f-PLAYER_XSIZE, (GLfloat)player2.ypos-PLAYER_YSIZE, 0.f,
612 1.f, (GLfloat)player2.ypos+PLAYER_YSIZE, 0.1f );
613
614 // Draw Ball
615 glMaterialfv( GL_FRONT, GL_DIFFUSE, ball_diffuse );
616 glMaterialfv( GL_FRONT, GL_AMBIENT, ball_ambient );
617 DrawBox( (GLfloat)ball.xpos-BALL_SIZE, (GLfloat)ball.ypos-BALL_SIZE, 0.f,
618 (GLfloat)ball.xpos+BALL_SIZE, (GLfloat)ball.ypos+BALL_SIZE, BALL_SIZE*2 );
619
620 // Top game field border
621 glMaterialfv( GL_FRONT, GL_DIFFUSE, border_diffuse );
622 glMaterialfv( GL_FRONT, GL_AMBIENT, border_ambient );
623 DrawBox( -1.1f, 1.0f, 0.0f, 1.1f, 1.1f, 0.1f );
624 // Bottom game field border
625 glColor3f( 0.0f, 0.0f, 0.7f );
626 DrawBox( -1.1f, -1.1f, 0.0f, 1.1f, -1.0f, 0.1f );
627 // Left game field border
628 DrawBox( -1.1f, -1.0f, 0.0f, -1.0f, 1.0f, 0.1f );
629 // Left game field border
630 DrawBox( 1.0f, -1.0f, 0.0f, 1.1f, 1.0f, 0.1f );
631
632 // Enable texturing
633 glEnable( GL_TEXTURE_2D );
634 glBindTexture( GL_TEXTURE_2D, tex_id[ TEX_FIELD ] );
635
636 // Game field floor
637 glMaterialfv( GL_FRONT, GL_DIFFUSE, floor_diffuse );
638 glMaterialfv( GL_FRONT, GL_AMBIENT, floor_ambient );
639 DrawBox( -1.01f, -1.01f, -0.01f, 1.01f, 1.01f, 0.0f );
640
641 // Disable texturing
642 glDisable( GL_TEXTURE_2D );
643
644 // Disable face culling
645 glDisable( GL_CULL_FACE );
646
647 // Disable lighting
648 glDisable( GL_LIGHTING );
649
650 // Disable depth testing
651 glDisable( GL_DEPTH_TEST );
652 }
653
654
655 //========================================================================
656 // GameOver()
657 //========================================================================
658
659 void GameOver( void )
660 {
661 // Enable sticky keys
662 glfwEnable( GLFW_STICKY_KEYS );
663
664 // Until the user presses ESC or SPACE
665 while( !glfwGetKey( GLFW_KEY_ESC ) && !glfwGetKey( ' ' ) &&
666 glfwGetWindowParam( GLFW_OPENED ) )
667 {
668 // Draw display
669 UpdateDisplay();
670
671 // Setup projection matrix
672 glMatrixMode( GL_PROJECTION );
673 glLoadIdentity();
674 glOrtho( 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f );
675
676 // Setup modelview matrix
677 glMatrixMode( GL_MODELVIEW );
678 glLoadIdentity();
679
680 // Enable blending
681 glEnable( GL_BLEND );
682
683 // Dim background
684 glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA );
685 glColor4f( 0.3f, 0.3f, 0.3f, 0.3f );
686 glBegin( GL_QUADS );
687 glVertex2f( 0.0f, 0.0f );
688 glVertex2f( 1.0f, 0.0f );
689 glVertex2f( 1.0f, 1.0f );
690 glVertex2f( 0.0f, 1.0f );
691 glEnd();
692
693 // Display winner text
694 glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_COLOR );
695 if( winner == PLAYER1 )
696 {
697 glColor4f( 1.0f, 0.5f, 0.5f, 1.0f );
698 DrawImage( TEX_WINNER1, 0.35f, 0.65f, 0.46f, 0.54f );
699 }
700 else if( winner == PLAYER2 )
701 {
702 glColor4f( 0.5f, 1.0f, 0.5f, 1.0f );
703 DrawImage( TEX_WINNER2, 0.35f, 0.65f, 0.46f, 0.54f );
704 }
705
706 // Disable blending
707 glDisable( GL_BLEND );
708
709 // Swap buffers
710 glfwSwapBuffers();
711 }
712
713 // Disable sticky keys
714 glfwDisable( GLFW_STICKY_KEYS );
715 }
716
717
718 //========================================================================
719 // GameLoop() - Game loop
720 //========================================================================
721
722 void GameLoop( void )
723 {
724 int playing, event;
725
726 // Initialize a new game
727 NewGame();
728
729 // Enable sticky keys
730 glfwEnable( GLFW_STICKY_KEYS );
731
732 // Loop until the game ends
733 playing = GL_TRUE;
734 while( playing && glfwGetWindowParam( GLFW_OPENED ) )
735 {
736 // Frame timer
737 oldtime = thistime;
738 thistime = glfwGetTime();
739 dt = thistime - oldtime;
740
741 // Get user input and update player positions
742 PlayerControl();
743
744 // Move the ball, and check if a player hits/misses the ball
745 event = BallControl();
746
747 // Did we have a winner?
748 switch( event )
749 {
750 case PLAYER1_WINS:
751 winner = PLAYER1;
752 playing = GL_FALSE;
753 break;
754 case PLAYER2_WINS:
755 winner = PLAYER2;
756 playing = GL_FALSE;
757 break;
758 default:
759 break;
760 }
761
762 // Did the user press ESC?
763 if( glfwGetKey( GLFW_KEY_ESC ) )
764 {
765 playing = GL_FALSE;
766 }
767
768 // Did the user change camera view?
769 if( glfwGetKey( '1' ) )
770 {
771 camerapos = CAMERA_CLASSIC;
772 }
773 else if( glfwGetKey( '2' ) )
774 {
775 camerapos = CAMERA_ABOVE;
776 }
777 else if( glfwGetKey( '3' ) )
778 {
779 camerapos = CAMERA_SPECTATOR;
780 }
781
782 // Draw display
783 UpdateDisplay();
784
785 // Swap buffers
786 glfwSwapBuffers();
787 }
788
789 // Disable sticky keys
790 glfwDisable( GLFW_STICKY_KEYS );
791
792 // Show winner
793 GameOver();
794 }
795
796
797 //========================================================================
798 // main() - Program entry point
799 //========================================================================
800
801 int main( void )
802 {
803 int menuoption;
804
805 // Initialize GLFW
806 if( !glfwInit() )
807 {
808 fprintf( stderr, "Failed to initialize GLFW\n" );
809 exit( EXIT_FAILURE );
810 }
811
812 // Open OpenGL window
813 if( !glfwOpenWindow( WIDTH, HEIGHT, 0,0,0,0, 16,0, GLFW_FULLSCREEN ) )
814 {
815 fprintf( stderr, "Failed to open GLFW window\n" );
816 glfwTerminate();
817 exit( EXIT_FAILURE );
818 }
819
820 glfwSwapInterval( 1 );
821
822 // Load all textures
823 if( !LoadTextures() )
824 {
825 glfwTerminate();
826 exit( EXIT_FAILURE );
827 }
828
829 // Main loop
830 do
831 {
832 // Get menu option
833 menuoption = GameMenu();
834
835 // If the user wants to play, let him...
836 if( menuoption == MENU_PLAY )
837 {
838 GameLoop();
839 }
840 }
841 while( menuoption != MENU_QUIT );
842
843 // Unload all textures
844 if( glfwGetWindowParam( GLFW_OPENED ) )
845 {
846 glDeleteTextures( NUM_TEXTURES, tex_id );
847 }
848
849 // Terminate GLFW
850 glfwTerminate();
851
852 exit( EXIT_SUCCESS );
853 }
854
Something went wrong with that request. Please try again.