diff options
Diffstat (limited to 'tests/glfw/pong3d.c')
-rw-r--r-- | tests/glfw/pong3d.c | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/tests/glfw/pong3d.c b/tests/glfw/pong3d.c new file mode 100644 index 00000000..1d1afd1f --- /dev/null +++ b/tests/glfw/pong3d.c @@ -0,0 +1,854 @@ +//======================================================================== +// This is a small test application for GLFW. +// This is an OpenGL port of the famous "PONG" game (the first computer +// game ever?). It is very simple, and could be improved alot. It was +// created in order to show off the gaming capabilities of GLFW. +//======================================================================== + +#include <GL/glfw.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + + +//======================================================================== +// Constants +//======================================================================== + +// Screen resolution +#define WIDTH 640 +#define HEIGHT 480 + +// Player size (units) +#define PLAYER_XSIZE 0.05f +#define PLAYER_YSIZE 0.15f + +// Ball size (units) +#define BALL_SIZE 0.02f + +// Maximum player movement speed (units / second) +#define MAX_SPEED 1.5f + +// Player movement acceleration (units / seconds^2) +#define ACCELERATION 4.0f + +// Player movement deceleration (units / seconds^2) +#define DECELERATION 2.0f + +// Ball movement speed (units / second) +#define BALL_SPEED 0.4f + +// Menu options +#define MENU_NONE 0 +#define MENU_PLAY 1 +#define MENU_QUIT 2 + +// Game events +#define NOBODY_WINS 0 +#define PLAYER1_WINS 1 +#define PLAYER2_WINS 2 + +// Winner ID +#define NOBODY 0 +#define PLAYER1 1 +#define PLAYER2 2 + +// Camera positions +#define CAMERA_CLASSIC 0 +#define CAMERA_ABOVE 1 +#define CAMERA_SPECTATOR 2 +#define CAMERA_DEFAULT CAMERA_CLASSIC + + +//======================================================================== +// Textures +//======================================================================== + +#define TEX_TITLE 0 +#define TEX_MENU 1 +#define TEX_INSTR 2 +#define TEX_WINNER1 3 +#define TEX_WINNER2 4 +#define TEX_FIELD 5 +#define NUM_TEXTURES 6 + +// Texture names +char * tex_name[ NUM_TEXTURES ] = { + "pong3d_title.tga", + "pong3d_menu.tga", + "pong3d_instr.tga", + "pong3d_winner1.tga", + "pong3d_winner2.tga", + "pong3d_field.tga" +}; + +// OpenGL texture object IDs +GLuint tex_id[ NUM_TEXTURES ]; + + +//======================================================================== +// Global variables +//======================================================================== + +// Display information +int width, height; + +// Frame information +double thistime, oldtime, dt, starttime; + +// Camera information +int camerapos; + +// Player information +struct { + double ypos; // -1.0 to +1.0 + double yspeed; // -MAX_SPEED to +MAX_SPEED +} player1, player2; + +// Ball information +struct { + double xpos, ypos; + double xspeed, yspeed; +} ball; + +// And the winner is... +int winner; + +// Lighting configuration +const GLfloat env_ambient[4] = {1.0f,1.0f,1.0f,1.0f}; +const GLfloat light1_position[4] = {-3.0f,3.0f,2.0f,1.0f}; +const GLfloat light1_diffuse[4] = {1.0f,1.0f,1.0f,0.0f}; +const GLfloat light1_ambient[4] = {0.0f,0.0f,0.0f,0.0f}; + +// Object material properties +const GLfloat player1_diffuse[4] = {1.0f,0.3f,0.3f,1.0f}; +const GLfloat player1_ambient[4] = {0.3f,0.1f,0.0f,1.0f}; +const GLfloat player2_diffuse[4] = {0.3f,1.0f,0.3f,1.0f}; +const GLfloat player2_ambient[4] = {0.1f,0.3f,0.1f,1.0f}; +const GLfloat ball_diffuse[4] = {1.0f,1.0f,0.5f,1.0f}; +const GLfloat ball_ambient[4] = {0.3f,0.3f,0.1f,1.0f}; +const GLfloat border_diffuse[4] = {0.3f,0.3f,1.0f,1.0f}; +const GLfloat border_ambient[4] = {0.1f,0.1f,0.3f,1.0f}; +const GLfloat floor_diffuse[4] = {1.0f,1.0f,1.0f,1.0f}; +const GLfloat floor_ambient[4] = {0.3f,0.3f,0.3f,1.0f}; + + +//======================================================================== +// LoadTextures() - Load textures from disk and upload to OpenGL card +//======================================================================== + +GLboolean LoadTextures( void ) +{ + int i; + + // Generate texture objects + glGenTextures( NUM_TEXTURES, tex_id ); + + // Load textures + for( i = 0; i < NUM_TEXTURES; i ++ ) + { + // Select texture object + glBindTexture( GL_TEXTURE_2D, tex_id[ i ] ); + + // Set texture parameters + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + // Upload texture from file to texture memory + if( !glfwLoadTexture2D( tex_name[ i ], 0 ) ) + { + fprintf( stderr, "Failed to load texture %s\n", tex_name[ i ] ); + return GL_FALSE; + } + } + + return GL_TRUE; +} + + +//======================================================================== +// DrawImage() - Draw a 2D image as a texture +//======================================================================== + +void DrawImage( int texnum, float x1, float x2, float y1, float y2 ) +{ + glEnable( GL_TEXTURE_2D ); + glBindTexture( GL_TEXTURE_2D, tex_id[ texnum ] ); + glBegin( GL_QUADS ); + glTexCoord2f( 0.0f, 1.0f ); + glVertex2f( x1, y1 ); + glTexCoord2f( 1.0f, 1.0f ); + glVertex2f( x2, y1 ); + glTexCoord2f( 1.0f, 0.0f ); + glVertex2f( x2, y2 ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex2f( x1, y2 ); + glEnd(); + glDisable( GL_TEXTURE_2D ); +} + + +//======================================================================== +// GameMenu() - Game menu (returns menu option) +//======================================================================== + +int GameMenu( void ) +{ + int option; + + // Enable sticky keys + glfwEnable( GLFW_STICKY_KEYS ); + + // Wait for a game menu key to be pressed + do + { + // Get window size + glfwGetWindowSize( &width, &height ); + + // Set viewport + glViewport( 0, 0, width, height ); + + // Clear display + glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + glClear( GL_COLOR_BUFFER_BIT ); + + // Setup projection matrix + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f ); + + // Setup modelview matrix + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Display title + glColor3f( 1.0f, 1.0f, 1.0f ); + DrawImage( TEX_TITLE, 0.1f, 0.9f, 0.0f, 0.3f ); + + // Display menu + glColor3f( 1.0f, 1.0f, 0.0f ); + DrawImage( TEX_MENU, 0.38f, 0.62f, 0.35f, 0.5f ); + + // Display instructions + glColor3f( 0.0f, 1.0f, 1.0f ); + DrawImage( TEX_INSTR, 0.32f, 0.68f, 0.65f, 0.85f ); + + // Swap buffers + glfwSwapBuffers(); + + // Check for keys + if( glfwGetKey( 'Q' ) || !glfwGetWindowParam( GLFW_OPENED ) ) + { + option = MENU_QUIT; + } + else if( glfwGetKey( GLFW_KEY_F1 ) ) + { + option = MENU_PLAY; + } + else + { + option = MENU_NONE; + } + + // To avoid horrible busy waiting, sleep for at least 20 ms + glfwSleep( 0.02 ); + } + while( option == MENU_NONE ); + + // Disable sticky keys + glfwDisable( GLFW_STICKY_KEYS ); + + return option; +} + + +//======================================================================== +// NewGame() - Initialize a new game +//======================================================================== + +void NewGame( void ) +{ + // Frame information + starttime = thistime = glfwGetTime(); + + // Camera information + camerapos = CAMERA_DEFAULT; + + // Player 1 information + player1.ypos = 0.0; + player1.yspeed = 0.0; + + // Player 2 information + player2.ypos = 0.0; + player2.yspeed = 0.0; + + // Ball information + ball.xpos = -1.0 + PLAYER_XSIZE; + ball.ypos = player1.ypos; + ball.xspeed = 1.0; + ball.yspeed = 1.0; +} + + +//======================================================================== +// PlayerControl() - Player control +//======================================================================== + +void PlayerControl( void ) +{ + float joy1pos[ 2 ], joy2pos[ 2 ]; + + // Get joystick X & Y axis positions + glfwGetJoystickPos( GLFW_JOYSTICK_1, joy1pos, 2 ); + glfwGetJoystickPos( GLFW_JOYSTICK_2, joy2pos, 2 ); + + // Player 1 control + if( glfwGetKey( 'A' ) || joy1pos[ 1 ] > 0.2f ) + { + player1.yspeed += dt * ACCELERATION; + if( player1.yspeed > MAX_SPEED ) + { + player1.yspeed = MAX_SPEED; + } + } + else if( glfwGetKey( 'Z' ) || joy1pos[ 1 ] < -0.2f ) + { + player1.yspeed -= dt * ACCELERATION; + if( player1.yspeed < -MAX_SPEED ) + { + player1.yspeed = -MAX_SPEED; + } + } + else + { + player1.yspeed /= exp( DECELERATION * dt ); + } + + // Player 2 control + if( glfwGetKey( 'K' ) || joy2pos[ 1 ] > 0.2f ) + { + player2.yspeed += dt * ACCELERATION; + if( player2.yspeed > MAX_SPEED ) + { + player2.yspeed = MAX_SPEED; + } + } + else if( glfwGetKey( 'M' ) || joy2pos[ 1 ] < -0.2f ) + { + player2.yspeed -= dt * ACCELERATION; + if( player2.yspeed < -MAX_SPEED ) + { + player2.yspeed = -MAX_SPEED; + } + } + else + { + player2.yspeed /= exp( DECELERATION * dt ); + } + + // Update player 1 position + player1.ypos += dt * player1.yspeed; + if( player1.ypos > 1.0 - PLAYER_YSIZE ) + { + player1.ypos = 1.0 - PLAYER_YSIZE; + player1.yspeed = 0.0; + } + else if( player1.ypos < -1.0 + PLAYER_YSIZE ) + { + player1.ypos = -1.0 + PLAYER_YSIZE; + player1.yspeed = 0.0; + } + + // Update player 2 position + player2.ypos += dt * player2.yspeed; + if( player2.ypos > 1.0 - PLAYER_YSIZE ) + { + player2.ypos = 1.0 - PLAYER_YSIZE; + player2.yspeed = 0.0; + } + else if( player2.ypos < -1.0 + PLAYER_YSIZE ) + { + player2.ypos = -1.0 + PLAYER_YSIZE; + player2.yspeed = 0.0; + } +} + + +//======================================================================== +// BallControl() - Ball control +//======================================================================== + +int BallControl( void ) +{ + int event; + double ballspeed; + + // Calculate new ball speed + ballspeed = BALL_SPEED * (1.0 + 0.02*(thistime-starttime)); + ball.xspeed = ball.xspeed > 0 ? ballspeed : -ballspeed; + ball.yspeed = ball.yspeed > 0 ? ballspeed : -ballspeed; + ball.yspeed *= 0.74321; + + // Update ball position + ball.xpos += dt * ball.xspeed; + ball.ypos += dt * ball.yspeed; + + // Did the ball hit a top/bottom wall? + if( ball.ypos >= 1.0 ) + { + ball.ypos = 2.0 - ball.ypos; + ball.yspeed = -ball.yspeed; + } + else if( ball.ypos <= -1.0 ) + { + ball.ypos = -2.0 - ball.ypos; + ball.yspeed = -ball.yspeed; + } + + // Did the ball hit/miss a player? + event = NOBODY_WINS; + + // Is the ball entering the player 1 goal? + if( ball.xpos < -1.0 + PLAYER_XSIZE ) + { + // Did player 1 catch the ball? + if( ball.ypos > (player1.ypos-PLAYER_YSIZE) && + ball.ypos < (player1.ypos+PLAYER_YSIZE) ) + { + ball.xpos = -2.0 + 2.0*PLAYER_XSIZE - ball.xpos; + ball.xspeed = -ball.xspeed; + } + else + { + event = PLAYER2_WINS; + } + } + + // Is the ball entering the player 2 goal? + if( ball.xpos > 1.0 - PLAYER_XSIZE ) + { + // Did player 2 catch the ball? + if( ball.ypos > (player2.ypos-PLAYER_YSIZE) && + ball.ypos < (player2.ypos+PLAYER_YSIZE) ) + { + ball.xpos = 2.0 - 2.0*PLAYER_XSIZE - ball.xpos; + ball.xspeed = -ball.xspeed; + } + else + { + event = PLAYER1_WINS; + } + } + + return event; +} + + +//======================================================================== +// DrawBox() - Draw a 3D box +//======================================================================== + +#define TEX_SCALE 4.0f + + +void DrawBox( float x1, float y1, float z1, float x2, float y2, float z2 ) +{ + // Draw six sides of a cube + glBegin( GL_QUADS ); + // Side 1 (down) + glNormal3f( 0.0f, 0.0f, -1.0f ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( x1,y2,z1 ); + glTexCoord2f( TEX_SCALE, 0.0f ); + glVertex3f( x2,y2,z1 ); + glTexCoord2f( TEX_SCALE, TEX_SCALE ); + glVertex3f( x2,y1,z1 ); + glTexCoord2f( 0.0f, TEX_SCALE ); + glVertex3f( x1,y1,z1 ); + // Side 2 (up) + glNormal3f( 0.0f, 0.0f, 1.0f ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( x1,y1,z2 ); + glTexCoord2f( TEX_SCALE, 0.0f ); + glVertex3f( x2,y1,z2 ); + glTexCoord2f( TEX_SCALE, TEX_SCALE ); + glVertex3f( x2,y2,z2 ); + glTexCoord2f( 0.0f, TEX_SCALE ); + glVertex3f( x1,y2,z2 ); + // Side 3 (backward) + glNormal3f( 0.0f, -1.0f, 0.0f ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( x1,y1,z1 ); + glTexCoord2f( TEX_SCALE, 0.0f ); + glVertex3f( x2,y1,z1 ); + glTexCoord2f( TEX_SCALE, TEX_SCALE ); + glVertex3f( x2,y1,z2 ); + glTexCoord2f( 0.0f, TEX_SCALE ); + glVertex3f( x1,y1,z2 ); + // Side 4 (forward) + glNormal3f( 0.0f, 1.0f, 0.0f ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( x1,y2,z2 ); + glTexCoord2f( TEX_SCALE, 0.0f ); + glVertex3f( x2,y2,z2 ); + glTexCoord2f( TEX_SCALE, TEX_SCALE ); + glVertex3f( x2,y2,z1 ); + glTexCoord2f( 0.0f, TEX_SCALE ); + glVertex3f( x1,y2,z1 ); + // Side 5 (left) + glNormal3f( -1.0f, 0.0f, 0.0f ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( x1,y1,z2 ); + glTexCoord2f( TEX_SCALE, 0.0f ); + glVertex3f( x1,y2,z2 ); + glTexCoord2f( TEX_SCALE, TEX_SCALE ); + glVertex3f( x1,y2,z1 ); + glTexCoord2f( 0.0f, TEX_SCALE ); + glVertex3f( x1,y1,z1 ); + // Side 6 (right) + glNormal3f( 1.0f, 0.0f, 0.0f ); + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( x2,y1,z1 ); + glTexCoord2f( TEX_SCALE, 0.0f ); + glVertex3f( x2,y2,z1 ); + glTexCoord2f( TEX_SCALE, TEX_SCALE ); + glVertex3f( x2,y2,z2 ); + glTexCoord2f( 0.0f, TEX_SCALE ); + glVertex3f( x2,y1,z2 ); + glEnd(); +} + + +//======================================================================== +// UpdateDisplay() - Draw graphics (all game related OpenGL stuff goes +// here) +//======================================================================== + +void UpdateDisplay( void ) +{ + // Get window size + glfwGetWindowSize( &width, &height ); + + // Set viewport + glViewport( 0, 0, width, height ); + + // Clear display + glClearColor( 0.02f, 0.02f, 0.02f, 0.0f ); + glClearDepth( 1.0f ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + // Setup projection matrix + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + gluPerspective( + 55.0f, // Angle of view + (GLfloat)width/(GLfloat)height, // Aspect + 1.0f, // Near Z + 100.0f // Far Z + ); + + // Setup modelview matrix + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + switch( camerapos ) + { + default: + case CAMERA_CLASSIC: + gluLookAt( + 0.0f, 0.0f, 2.5f, + 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f + ); + break; + case CAMERA_ABOVE: + gluLookAt( + 0.0f, 0.0f, 2.5f, + (float)ball.xpos, (float)ball.ypos, 0.0f, + 0.0f, 1.0f, 0.0f + ); + break; + case CAMERA_SPECTATOR: + gluLookAt( + 0.0f, -2.0, 1.2f, + (float)ball.xpos, (float)ball.ypos, 0.0f, + 0.0f, 0.0f, 1.0f + ); + break; + } + + // Enable depth testing + glEnable( GL_DEPTH_TEST ); + glDepthFunc( GL_LEQUAL ); + + // Enable lighting + glEnable( GL_LIGHTING ); + glLightModelfv( GL_LIGHT_MODEL_AMBIENT, env_ambient ); + glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE ); + glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE ); + glLightfv( GL_LIGHT1, GL_POSITION, light1_position ); + glLightfv( GL_LIGHT1, GL_DIFFUSE, light1_diffuse ); + glLightfv( GL_LIGHT1, GL_AMBIENT, light1_ambient ); + glEnable( GL_LIGHT1 ); + + // Front face is counter-clock-wise + glFrontFace( GL_CCW ); + + // Enable face culling (not necessary, but speeds up rendering) + glCullFace( GL_BACK ); + glEnable( GL_CULL_FACE ); + + // Draw Player 1 + glMaterialfv( GL_FRONT, GL_DIFFUSE, player1_diffuse ); + glMaterialfv( GL_FRONT, GL_AMBIENT, player1_ambient ); + DrawBox( -1.f, (GLfloat)player1.ypos-PLAYER_YSIZE, 0.f, + -1.f+PLAYER_XSIZE, (GLfloat)player1.ypos+PLAYER_YSIZE, 0.1f ); + + // Draw Player 2 + glMaterialfv( GL_FRONT, GL_DIFFUSE, player2_diffuse ); + glMaterialfv( GL_FRONT, GL_AMBIENT, player2_ambient ); + DrawBox( 1.f-PLAYER_XSIZE, (GLfloat)player2.ypos-PLAYER_YSIZE, 0.f, + 1.f, (GLfloat)player2.ypos+PLAYER_YSIZE, 0.1f ); + + // Draw Ball + glMaterialfv( GL_FRONT, GL_DIFFUSE, ball_diffuse ); + glMaterialfv( GL_FRONT, GL_AMBIENT, ball_ambient ); + DrawBox( (GLfloat)ball.xpos-BALL_SIZE, (GLfloat)ball.ypos-BALL_SIZE, 0.f, + (GLfloat)ball.xpos+BALL_SIZE, (GLfloat)ball.ypos+BALL_SIZE, BALL_SIZE*2 ); + + // Top game field border + glMaterialfv( GL_FRONT, GL_DIFFUSE, border_diffuse ); + glMaterialfv( GL_FRONT, GL_AMBIENT, border_ambient ); + DrawBox( -1.1f, 1.0f, 0.0f, 1.1f, 1.1f, 0.1f ); + // Bottom game field border + glColor3f( 0.0f, 0.0f, 0.7f ); + DrawBox( -1.1f, -1.1f, 0.0f, 1.1f, -1.0f, 0.1f ); + // Left game field border + DrawBox( -1.1f, -1.0f, 0.0f, -1.0f, 1.0f, 0.1f ); + // Left game field border + DrawBox( 1.0f, -1.0f, 0.0f, 1.1f, 1.0f, 0.1f ); + + // Enable texturing + glEnable( GL_TEXTURE_2D ); + glBindTexture( GL_TEXTURE_2D, tex_id[ TEX_FIELD ] ); + + // Game field floor + glMaterialfv( GL_FRONT, GL_DIFFUSE, floor_diffuse ); + glMaterialfv( GL_FRONT, GL_AMBIENT, floor_ambient ); + DrawBox( -1.01f, -1.01f, -0.01f, 1.01f, 1.01f, 0.0f ); + + // Disable texturing + glDisable( GL_TEXTURE_2D ); + + // Disable face culling + glDisable( GL_CULL_FACE ); + + // Disable lighting + glDisable( GL_LIGHTING ); + + // Disable depth testing + glDisable( GL_DEPTH_TEST ); +} + + +//======================================================================== +// GameOver() +//======================================================================== + +void GameOver( void ) +{ + // Enable sticky keys + glfwEnable( GLFW_STICKY_KEYS ); + + // Until the user presses ESC or SPACE + while( !glfwGetKey( GLFW_KEY_ESC ) && !glfwGetKey( ' ' ) && + glfwGetWindowParam( GLFW_OPENED ) ) + { + // Draw display + UpdateDisplay(); + + // Setup projection matrix + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f ); + + // Setup modelview matrix + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Enable blending + glEnable( GL_BLEND ); + + // Dim background + glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ); + glColor4f( 0.3f, 0.3f, 0.3f, 0.3f ); + glBegin( GL_QUADS ); + glVertex2f( 0.0f, 0.0f ); + glVertex2f( 1.0f, 0.0f ); + glVertex2f( 1.0f, 1.0f ); + glVertex2f( 0.0f, 1.0f ); + glEnd(); + + // Display winner text + glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_COLOR ); + if( winner == PLAYER1 ) + { + glColor4f( 1.0f, 0.5f, 0.5f, 1.0f ); + DrawImage( TEX_WINNER1, 0.35f, 0.65f, 0.46f, 0.54f ); + } + else if( winner == PLAYER2 ) + { + glColor4f( 0.5f, 1.0f, 0.5f, 1.0f ); + DrawImage( TEX_WINNER2, 0.35f, 0.65f, 0.46f, 0.54f ); + } + + // Disable blending + glDisable( GL_BLEND ); + + // Swap buffers + glfwSwapBuffers(); + } + + // Disable sticky keys + glfwDisable( GLFW_STICKY_KEYS ); +} + + +//======================================================================== +// GameLoop() - Game loop +//======================================================================== + +void GameLoop( void ) +{ + int playing, event; + + // Initialize a new game + NewGame(); + + // Enable sticky keys + glfwEnable( GLFW_STICKY_KEYS ); + + // Loop until the game ends + playing = GL_TRUE; + while( playing && glfwGetWindowParam( GLFW_OPENED ) ) + { + // Frame timer + oldtime = thistime; + thistime = glfwGetTime(); + dt = thistime - oldtime; + + // Get user input and update player positions + PlayerControl(); + + // Move the ball, and check if a player hits/misses the ball + event = BallControl(); + + // Did we have a winner? + switch( event ) + { + case PLAYER1_WINS: + winner = PLAYER1; + playing = GL_FALSE; + break; + case PLAYER2_WINS: + winner = PLAYER2; + playing = GL_FALSE; + break; + default: + break; + } + + // Did the user press ESC? + if( glfwGetKey( GLFW_KEY_ESC ) ) + { + playing = GL_FALSE; + } + + // Did the user change camera view? + if( glfwGetKey( '1' ) ) + { + camerapos = CAMERA_CLASSIC; + } + else if( glfwGetKey( '2' ) ) + { + camerapos = CAMERA_ABOVE; + } + else if( glfwGetKey( '3' ) ) + { + camerapos = CAMERA_SPECTATOR; + } + + // Draw display + UpdateDisplay(); + + // Swap buffers + glfwSwapBuffers(); + } + + // Disable sticky keys + glfwDisable( GLFW_STICKY_KEYS ); + + // Show winner + GameOver(); +} + + +//======================================================================== +// main() - Program entry point +//======================================================================== + +int main( void ) +{ + int menuoption; + + // Initialize GLFW + if( !glfwInit() ) + { + fprintf( stderr, "Failed to initialize GLFW\n" ); + exit( EXIT_FAILURE ); + } + + // Open OpenGL window + if( !glfwOpenWindow( WIDTH, HEIGHT, 0,0,0,0, 16,0, GLFW_FULLSCREEN ) ) + { + fprintf( stderr, "Failed to open GLFW window\n" ); + glfwTerminate(); + exit( EXIT_FAILURE ); + } + + glfwSwapInterval( 1 ); + + // Load all textures + if( !LoadTextures() ) + { + glfwTerminate(); + exit( EXIT_FAILURE ); + } + + // Main loop + do + { + // Get menu option + menuoption = GameMenu(); + + // If the user wants to play, let him... + if( menuoption == MENU_PLAY ) + { + GameLoop(); + } + } + while( menuoption != MENU_QUIT ); + + // Unload all textures + if( glfwGetWindowParam( GLFW_OPENED ) ) + { + glDeleteTextures( NUM_TEXTURES, tex_id ); + } + + // Terminate GLFW + glfwTerminate(); + + exit( EXIT_SUCCESS ); +} + |