//***********************************************************
//FILE: Pong.cpp *
// *
//AUTHOR: Yee Hsu *
// *
//DATE: 4/29/02 *
// *
//CLASS: CSc630 *
// *
//USAGE COMMENTS: This is the source file for Pong.cpp *
// Should be compiled using VC++ *
// *
//LIBARIES: *
// <GL/glut.h> - for OpenGL and glut tool kits *
// <stdio.h> - standard input/output *
// <Windows.h> - Windows header file. for strlen *
// <ctype.h> - *
// <gl/glaux.h>- glut tool kit *
// *
//FUNCTIONS/METHODS DECLARED: *
// void init(); *
// void addMenuFeatures(void); *
// void loadTexture(char*); *
// void showIntro(void); *
// void display(void); *
// void keyboard(unsigned char, int, int); *
// void reshape(int, int); *
// void animate(void); *
// void helpMenu(int); *
// void arrowKeys(int key, int x, int y); *
// *
//GENERAL COMMENTS: *
// 3D Pong game created for CSc 630 Project2. Early *
// stage of the game development. Once executed it only *
// shows the introduction of the game and the basic *
// structure of the game design. *
//***********************************************************
#include "pong.h"
//***********************************************************
//FUNCTION: int main(int argc, char** argv) *
// Driver of the program *
//***********************************************************
int main(int argc, char *argv[])
{
// setup and init
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
mainwin = glutCreateWindow("3D Pong");
glutFullScreen();
init();
// callback routines
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(animate);
glutSpecialFunc(arrowKeys);
// menu
addMenuFeatures();
glutMainLoop();
return 0;
}
//***********************************************************
//FUNCTION: void myInit(void) *
// Initializes the main program and load textures for *
// introduction object *
//***********************************************************
void init(void)
{
// intro textures
loadTexture("side1.bmp"); // 6 sides of the cube
loadTexture("side2.bmp"); //
loadTexture("side3.bmp"); // stored into array
loadTexture("side4.bmp"); // variable texture[6];
loadTexture("side5.bmp"); // from:
loadTexture("side6.bmp"); // texture[0]...texture[5]
loadTexture("background1.bmp"); // background: texture[6]
// arena map 1 textures
loadTexture("field.bmp"); // ground: texture[7]
loadTexture("stadium.bmp"); // 4 sides: texture[8]
loadTexture("sky.bmp"); // background: texture[9]
// arena map 2 textures
loadTexture("tile.bmp"); // temple: texture[10]
loadTexture("dirtground.bmp"); // ground: texture[11]
loadTexture("acropolis.bmp"); // background: texture[12]
// arena map 3 textures
loadTexture("moon.bmp"); // sphere: texture[13]
loadTexture("earth.bmp"); // texture[14]
loadTexture("pluto.bmp"); // texture[15]
loadTexture("sun.bmp"); // texture[16]
loadTexture("mercury.bmp"); // texture[17]
loadTexture("uranus.bmp"); // texture[18]
loadTexture("jupiter.bmp"); // texture[19]
loadTexture("saturn.bmp"); // texture[20]
loadTexture("mars.bmp"); // texture[21]
loadTexture("matrix.bmp"); // field: texture[22]
loadTexture("starfield.bmp"); // background: texture[23]
// arena map 4 textures
loadTexture("rotary.bmp"); // rotary: texture[24]
loadTexture("flare.bmp"); // background: texture[25]
// gameover textures
loadTexture("gameover.bmp"); // background: texture[26]
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
// set color and depth
glClearColor(1.0, 1.0, 1.0, 0.0);
glClearDepth(1.0);
// fog
GLfloat fogColor[] = {0.8, 0.8, 0.8, 1.0};
glFogi(GL_FOG_MODE, GL_LINEAR);
glHint(GL_FOG_HINT, GL_NICEST);
glFogf(GL_FOG_START, 25.0);
glFogf(GL_FOG_END, 100.0);
glFogfv(GL_FOG_COLOR, fogColor);
// setup enviornment
glShadeModel(GL_SMOOTH);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// enable environment effects
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
// init intro background flag points
for (int x = 0; x < GRID_POINTS; x++)
{
for (int y = 0; y < GRID_POINTS; y++)
{
points[x][y][0] = GLfloat ((x/5.0f)-4.5f);
points[x][y][1] = GLfloat ((y/5.0f)-4.5f);
points[x][y][2] = GLfloat (sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
}
}
PlaySound("Warcraft3.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
}
//***********************************************************
//FUNCTION: void display(void) *
// Draws paddles and displays introduction to game *
//***********************************************************
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
if (startgame) // game in progress
{
glPushMatrix();
glTranslatef(0.0, 0.0, pz + mapz_offset); // perimeter zooming
glRotatef(-pr, 1.0, 0.0, 0.0); // perimeter rotation
// draw top paddle [2nd player]
glPushMatrix();
glTranslatef(x2, PADDLE_POS, 0.0);
glScalef(5.0, 0.5, 0.5);
glutSolidCube(1.0);
glPopMatrix();
// draw ball
glPushMatrix();
glTranslatef(bx, by, 0.0);
glutSolidSphere(0.6, 8, 4);
glPopMatrix();
// draw bottom paddle [1st player]
glPushMatrix();
glTranslatef(x1, -PADDLE_POS, 0.0);
glScalef(5.0, 0.5, 0.5);
glutSolidCube(1.0);
glPopMatrix();
// draw perimeters
glPushMatrix();
glBegin(GL_LINE_LOOP);
glColor3f(0.0, 0.0, 0.0);
glVertex2f( BORDER_X, BORDER_Y);
glVertex2f(-BORDER_X, BORDER_Y);
glVertex2f(-BORDER_X, -BORDER_Y);
glVertex2f( BORDER_X, -BORDER_Y);
glEnd();
glPopMatrix();
// draw map
glPushMatrix();
selectMap();
glPopMatrix();
glPopMatrix();
}
else if (gameover) // display epilogue
{
showBackground(texture[26]);
showEnd();
}
else // display game intro
{
showFlag(texture[6]); // background
showIntro(); // cube
}
glPopMatrix();
glFlush();
glutSwapBuffers();
(fullscreen ? NULL : displayFPS());
}
//***********************************************************
//FUNCTION: void keyboard(unsigned char key, int x, int y) *
// Allows the user to input keyboard commands *
//***********************************************************
void keyboard(unsigned char key, int x, int y)
{
static bool bMode = true;
static bool bFog = false;
switch (toupper(key))
{
case VK_INSTRUCT: // get instructions
if (startgame)
PlaySound("Instruction.wav", NULL, SND_ASYNC | SND_FILENAME);
MessageBox(NULL, "Instruction Menu\t\t\t\t\n\n"
"I \t - Get instructions\n"
"S \t - Start 3D Pong\n"
"C \t - Change Map\n"
"F \t - Toggle on/off full screen\n"
"D \t - Toggle fog\n"
"M \t - Toggle polygon/wireframe\n"
"P \t - Toggle pause\n"
"A \t - Get credits about 3D Pong\n"
"Q \t - Quit 3D Pong\n"
"\n"
"1st player control: \n"
"Left arrow \t - Move Left\n"
"Right arrow \t - Move Right\n"
"\n"
"CPU AI / 2nd player control: \n"
"Z \t - Move Left\n"
"X \t - Move Right\n"
"\n"
,
"Help Instructions", MB_OK | MB_ICONINFORMATION);
break;
case VK_FULLSCRN: // toggle fullscreen
if (startgame)
PlaySound("Toggle.wav", NULL, SND_ASYNC | SND_FILENAME);
if (fullscreen)
{
fullscreen = false;
glutSetWindow(mainwin);
glutPositionWindow(64, 64);
glutReshapeWindow(640, 480);
}
else
{
fullscreen = true;
glutFullScreen();
}
break;
case VK_STARTG:
case VK_NOVICE: // starts the game
gameInit(SPEED_NOVICE);
dLevel = VK_NOVICE;
break;
case VK_SO_SO:
gameInit(SPEED_SO_SO);
dLevel = VK_SO_SO;
break;
case VK_ADVANCED:
gameInit(SPEED_ADVANCED);
dLevel = VK_ADVANCED;
break;
case VK_P2_L: // player2 left movement
if (x2 > -BORDER_X)
x2 -= PADDLE_VEL;
break;
case VK_P2_R: // player2 right movement
if (x2 < BORDER_X)
x2 += PADDLE_VEL;
break;
case VK_CH_MAP: // changes the map
if (startgame)
{
PlaySound("Map.wav", NULL, SND_ASYNC | SND_FILENAME);
nMap = (nMap + 1) % MAX_MAP;
}
else
{
MessageBox(NULL, "\n3D Pong\t\t\t\t\t\n"
"\n"
"Map changes allowed only when game is in progress."
,
"Arena changes", MB_OK | MB_ICONINFORMATION);
}
break;
case VK_FOG:
bFog = !bFog;
if (startgame)
PlaySound("Fog1.wav", NULL, SND_ASYNC | SND_FILENAME);
if (bFog)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
break;
case VK_MODE:
bMode = !bMode;
if (startgame)
PlaySound("Polymode1.wav", NULL, SND_ASYNC | SND_FILENAME);
if (bMode)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
polyMode = GLU_FILL;
texMode = GL_TRUE;
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
polyMode = GLU_LINE;
texMode = GL_FALSE;
}
break;
case VK_PAUSEG: // toggle pause
pausegame = !pausegame;
if (startgame)
PlaySound("Pause1.wav", NULL, SND_ASYNC | SND_FILENAME);
if (pausegame)
glutIdleFunc(NULL);
else
glutIdleFunc(animate);
break;
case VK_ABOUT: // get game info
if (startgame)
PlaySound("About.wav", NULL, SND_ASYNC | SND_FILENAME);
MessageBox(NULL, "\n3D Pong\t\t\t\n"
"\n"
"Copyright Spring 2002\n"
"All rights reserved.\n"
"\n"
"App. Version 2.0c\n"
"\n"
"Credits:\n"
"- Yee Hsu\n"
,
"About 3D Pong", MB_OK | MB_ICONINFORMATION);
break;
case VK_QUIT: // quits app
case VK_ESC:
PlaySound("Quit.wav", NULL, SND_ASYNC | SND_FILENAME);
Sleep(500);
exit(0);
break;
default:
break;
}
glutPostRedisplay();
}
//***********************************************************
//FUNCTION: void reshape(int w, int h) *
// Maintains object and game in perspective view *
//***********************************************************
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluPerspective(60.0f,(GLfloat)h / (GLfloat)w,0.1f,500.0f);
else
gluPerspective(60.0f,(GLfloat)w / (GLfloat)h,0.1f,500.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
//***********************************************************
//FUNCTION: void animate(void) *
// Animation of introduction 3D object and game play *
//***********************************************************
void animate(void)
{
if (!startgame)
{
static int wiggle_count = 0;
xr += (GLfloat) 0.3f; // cube animation
yr += (GLfloat) 0.2f;
zr += (GLfloat) 0.4f;
// animate intro background flag effect
if (wiggle_count == 2)
{
for (int y = 0; y < GRID_POINTS; y++)
{
GLfloat hold = points[0][y][2];
for (int x = 0; x < GRID_POINTS-1; x++)
{
points[x][y][2] = points[x+1][y][2];
}
points[GRID_POINTS-1][y][2] = hold;
}
wiggle_count = 0;
}
wiggle_count++;
}
else if (startgame && !gameover)
{
// this statements simulates the computer AI that
// controls the 2nd player [top paddle]. Comment
// it out to disable the AI so 2nd player can
// manually control it. [Z = left, X = right]
// AI is currently invincible.
x2 = bx;
//x1 = bx; // AI controls 1st player
bx += xv; // ball animation
by += yv;
collisionDetection(); // collision dectection
}
glutPostRedisplay();
}
//***********************************************************
//FUNCTION: void addMenuFeatures(void) *
// Adds mouse menu features *
//***********************************************************
void addMenuFeatures(void)
{
helpSubMenu = glutCreateMenu(helpMenu);
glutAddMenuEntry("3D Pong Instruction", IDM_INSTRUCT);
glutAddMenuEntry("About 3D Pong", IDM_ABOUT);
gameSubMenu = glutCreateMenu(helpMenu);
glutAddMenuEntry("Novice Player", IDM_NOVICE);
glutAddMenuEntry("Intermediate Player", IDM_SO_SO);
glutAddMenuEntry("Advanced Player", IDM_ADVANCED);
toggleSubMenu = glutCreateMenu(helpMenu);
glutAddMenuEntry("Fog", IDM_FOG);
glutAddMenuEntry("Polygon/Wireframe", IDM_MODE);
glutAddMenuEntry("Pause", IDM_PAUSE);
glutAddMenuEntry("Screen", IDM_FSCR);
mainMenu = glutCreateMenu(helpMenu);
glutAddSubMenu("Help", helpSubMenu);
glutAddSubMenu("Start", gameSubMenu);
glutAddSubMenu("Toggle ...", toggleSubMenu);
glutAddMenuEntry("Change Map", IDM_CHANGE_MAP);
glutAddMenuEntry("Quit", IDM_QUIT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
//***********************************************************
//FUNCTION: void helpMenu(int id) *
// Help menu callback function *
//***********************************************************
void helpMenu(int id)
{
switch (id)
{
case IDM_INSTRUCT:
keyboard(VK_INSTRUCT, 0, 0);
break;
case IDM_NOVICE:
keyboard(VK_NOVICE, 0, 0);
break;
case IDM_SO_SO:
keyboard(VK_SO_SO, 0, 0);
break;
case IDM_ADVANCED:
keyboard(VK_ADVANCED, 0, 0);
break;
case IDM_CHANGE_MAP:
keyboard(VK_CH_MAP, 0, 0);
break;
case IDM_PAUSE:
keyboard(VK_PAUSEG, 0, 0);
break;
case IDM_FSCR:
keyboard(VK_FULLSCRN, 0, 0);
break;
case IDM_FOG:
keyboard(VK_FOG, 0, 0);
break;
case IDM_MODE:
keyboard(VK_MODE, 0, 0);
break;
case IDM_ABOUT:
keyboard(VK_ABOUT, 0, 0);
break;
case IDM_QUIT:
keyboard(VK_QUIT, 0, 0);
break;
default:
break;
}
}
//***********************************************************
//FUNCTION: void loadTexture(char *filename) *
// Loads textures for texture mapping *
//***********************************************************
void loadTexture(char *filename)
{
static unsigned int texture_id = 0;
AUX_RGBImageRec *TextureImage = NULL;
TextureImage = auxDIBImageLoad(filename);
glGenTextures(1, &texture[texture_id]);
glBindTexture(GL_TEXTURE_2D, texture[texture_id]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage->sizeX,
TextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
free(TextureImage->data); // prevents memory leak
free(TextureImage);
texture_id++;
}
//***********************************************************
//FUNCTION: void showBackground() *
// Shows background image *
//***********************************************************
void showBackground(const GLuint tex)
{
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-90.0f, -90.0f, -90.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 90.0f, -90.0f, -90.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 90.0f, 90.0f, -90.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-90.0f, 90.0f, -90.0f);
glEnd();
}
//***********************************************************
//FUNCTION: void showIntro() *
// Shows introduction before game play begins *
//***********************************************************
void showIntro()
{
static GLfloat r = 0.0f, g = 0.0f, b = 0.0f;
// lighting
GLfloat light_color[] = {0.0, 0.0, 0.0, 0.0};
GLfloat diffuse_light[] = {1.0, 1.0, 1.0, 0.0};
GLfloat ambient_light[] = {0.5, 0.5, 0.5, 0.0};
GLfloat light_pos[] = {0.0, 0.0, 0.0, 9.9};
r += (GLfloat) 0.005;
if ((light_color[0] = r) >= 1.0) { r = 1.0; g += 0.005;}
if ((light_color[1] = g) >= 1.0) { g = 1.0; b += 0.005;}
if ((light_color[2] = b) >= 1.0) { r = g = b = 0.000;}
glMaterialfv(GL_FRONT, GL_AMBIENT, light_color);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
// blending
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
// rotates the cube
glRotatef(xr,1.0f,0.0f,0.0f);
glRotatef(yr,0.0f,1.0f,0.0f);
glRotatef(zr,0.0f,0.0f,1.0f);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_QUADS);
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_QUADS);
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[4]);
glBegin(GL_QUADS);
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[5]);
glBegin(GL_QUADS);
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glDisable(GL_BLEND);
}
void showEnd(void)
{
static GLfloat angle = 0.0f;
// enable env mapping
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glPushMatrix();
glTranslatef(0.0, 0.0, -7.0);
glRotatef(angle * 1.3f, 1.0f, 0.0f, 0.0f);
glRotatef(angle * 1.1f, 0.0f, 1.0f, 0.0f);
glRotatef(angle * 1.2f, 0.0f, 0.0f, 1.0f);
angle += (GLfloat) 0.5f;
glutSolidSphere(4.0, 16, 8);
glPopMatrix();
// disable env mapping
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
void selectMap(void)
{
switch (nMap)
{
case 0:
mapz_offset = (GLfloat) 0.0f;
drawArena1();
showBackground(texture[9]);
break;
case 1:
mapz_offset = (GLfloat) -9.0f;
drawArena2();
showBackground(texture[12]);
break;
case 2:
mapz_offset = (GLfloat) -5.0f;
drawArena3();
showBackground(texture[23]);
break;
case 3:
mapz_offset = (GLfloat) -3.0f;
drawArena4();
showBackground(texture[25]);
break;
default:
// in case an error occurs [unlikely],
// forces the map to be changed
nMap = (nMap + 1) % MAX_MAP;
break;
}
}
// stadium
void drawArena1(void)
{
// lighting
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat diffuse_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat ambient_light[] = {0.6, 0.6, 0.6, 1.0};
GLfloat light_pos[] = {0.0, 0.0, 0.0, 9.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, white_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
// field
glBindTexture(GL_TEXTURE_2D, texture[7]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 10, BORDER_Y + 3, -5);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 10, BORDER_Y + 3, -5);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, -BORDER_Y - 3, -5);
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, -BORDER_Y - 3, -5);
glEnd();
// top side
glBindTexture(GL_TEXTURE_2D, texture[8]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, BORDER_Y + 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, BORDER_Y + 3, -5 );
glEnd();
// left side
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-BORDER_X - 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, -BORDER_Y - 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f(-BORDER_X - 10, BORDER_Y + 3, -5 );
glEnd();
// bottom side
glBegin(GL_LINE_LOOP);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, -BORDER_Y - 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, -BORDER_Y - 3, -5 );
glEnd();
// right side
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f( BORDER_X + 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f( BORDER_X + 10, -BORDER_Y - 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, BORDER_Y + 3, -5 );
glEnd();
}
// temple
void drawArena2(void)
{
// lighting
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat diffuse_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat ambient_light[] = {0.5, 0.5, 0.5, 1.0};
GLfloat light_pos[] = {0.0, 0.0, 0.0, 9.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, white_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
const int NUM_STEP = 4;
glBindTexture(GL_TEXTURE_2D, texture[10]);
// draws the stairs under the perimeter
for (int i = 1; i < NUM_STEP; i++)
{
// top face
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + i, BORDER_Y + i, -i);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - i, BORDER_Y + i, -i);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - i, -BORDER_Y - i, -i);
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + i, -BORDER_Y - i, -i);
glEnd();
// back face
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + i, BORDER_Y + i, -i);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - i, BORDER_Y + i, -i);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - i, BORDER_Y + i, -(i+1));
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + i, BORDER_Y + i, -(i+1));
glEnd();
// left face
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-BORDER_X - i, BORDER_Y + i, -i);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - i, BORDER_Y + i, -(i+1));
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - i, -BORDER_Y - i, -(i+1));
glTexCoord2f(0.0f, 1.0f); glVertex3f(-BORDER_X - i, -BORDER_Y - i, -i);
glEnd();
// front face
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-BORDER_X - i, -BORDER_Y - i, -i);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - i, -BORDER_Y - i, -(i+1));
glTexCoord2f(1.0f, 1.0f); glVertex3f( BORDER_X + i, -BORDER_Y - i, -(i+1));
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + i, -BORDER_Y - i, -i);
glEnd();
// right face
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + i, -BORDER_Y - i, -i);
glTexCoord2f(1.0f, 0.0f); glVertex3f( BORDER_X + i, -BORDER_Y - i, -(i+1));
glTexCoord2f(1.0f, 1.0f); glVertex3f( BORDER_X + i, BORDER_Y + i, -(i+1));
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + i, BORDER_Y + i, -i);
glEnd();
}
// init the quadric object
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, polyMode);
gluQuadricNormals(qobj, GLU_SMOOTH);
gluQuadricTexture(qobj, texMode);
// top right pillar
glPushMatrix();
glTranslatef( BORDER_X + (2 * NUM_STEP), BORDER_Y, -NUM_STEP);
gluCylinder(qobj, 3.0, 3.0, 15.0, 15, 5);
glTranslatef(0.0, 0.0, 15.0);
glScalef(7.0, 7.0, 3.0);
glutSolidCube(1.0);
glPopMatrix();
// top left pillar
glPushMatrix();
glTranslatef(-BORDER_X - (2 * NUM_STEP), BORDER_Y, -NUM_STEP);
gluCylinder(qobj, 3.0, 3.0, 15.0, 15, 5);
glTranslatef(0.0, 0.0, 15.0);
glScalef(7.0, 7.0, 3.0);
glutSolidCube(1.0);
glPopMatrix();
// bottom left pillar
glPushMatrix();
glTranslatef(-BORDER_X - (2 * NUM_STEP), -BORDER_Y, -NUM_STEP);
gluCylinder(qobj, 3.0, 3.0, 15.0, 15, 5);
glTranslatef(0.0, 0.0, 15.0);
glScalef(7.0, 7.0, 3.0);
glutSolidCube(1.0);
glPopMatrix();
// bottom right pillar
glPushMatrix();
glTranslatef( BORDER_X + (2 * NUM_STEP), -BORDER_Y, -NUM_STEP);
gluCylinder(qobj, 3.0, 3.0, 15.0, 15, 5);
glTranslatef(0.0, 0.0, 15.0);
glScalef(7.0, 7.0, 3.0);
glutSolidCube(1.0);
glPopMatrix();
// draws the ground
glBindTexture(GL_TEXTURE_2D, texture[11]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 50, BORDER_Y + 50, -NUM_STEP);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 50, BORDER_Y + 50, -NUM_STEP);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 50, -BORDER_Y - 50, -NUM_STEP);
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 50, -BORDER_Y - 50, -NUM_STEP);
glEnd();
// deletes the object to prevent memory leak
gluDeleteQuadric(qobj);
}
// spheres
void drawArena3(void)
{
// lighting
GLfloat lmodel_ambient[] = {0.9, 0.9, 0.9, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
// init the quadric object
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, polyMode);
gluQuadricNormals(qobj, GLU_SMOOTH);
gluQuadricTexture(qobj, texMode);
// multiple random sphere placements
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[16]);
glTranslatef(30.0, 25.0, 15.0);
gluSphere(qobj, 5.0, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[18]);
glTranslatef(25.0, 10.0, 0.7);
gluSphere(qobj, 3.0, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[20]);
glTranslatef(-25.0, 10.0, 0.7);
gluSphere(qobj, 4.0, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[20]);
glTranslatef(-25.0, 10.0, 0.7);
glRotatef(45.0, -25.0, 10.0, 0.7);
gluDisk(qobj, 5.0, 7.0, 25.0, 25.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[19]);
glTranslatef(-25.0, -20.0, 5.0);
gluSphere(qobj, 5.0, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[21]);
glTranslatef(-28.0, -5.0, 10.0);
gluSphere(qobj, 1.0, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[17]);
glTranslatef(17.0, -8.0, 15.0);
gluSphere(qobj, 1.5, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[15]);
glTranslatef(17.0, -8.0, 15.0);
gluDisk(qobj, 2.0, 2.5, 25.0, 25.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[13]);
glTranslatef(23.0, -13.0, 15.0);
gluSphere(qobj, 2.5, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[15]);
glTranslatef(-32.0, -27.0, 15.0);
gluSphere(qobj, 3.5, 15.0, 15.0);
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[14]);
glTranslatef(-23.0, 22.0, 15.0);
gluSphere(qobj, 5.0, 15.0, 15.0);
glPopMatrix();
// field
glBindTexture(GL_TEXTURE_2D, texture[22]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X, BORDER_Y, -1);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X, BORDER_Y, -1);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X, -BORDER_Y, -1);
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X, -BORDER_Y, -1);
glEnd();
// deletes the object to prevent memory leak
gluDeleteQuadric(qobj);
}
// cylinder
void drawArena4(void)
{
static GLfloat rot = 0.0f;
// lighting
GLfloat lmodel_ambient[] = {0.9, 0.9, 0.9, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
// init the quadric object
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, polyMode);
gluQuadricNormals(qobj, GLU_SMOOTH);
gluQuadricTexture(qobj, texMode);
// rotates the rotary
glRotatef(rot, 0.0, 1.0, 0.0);
rot = rot + (GLfloat) 0.1f;
// draws the rotary
glPushMatrix();
glTranslatef(0.0, BORDER_Y, 0.0);
glRotatef(90.0f, 1.0, 0.0, 0.0);
glBindTexture(GL_TEXTURE_2D, texture[24]);
gluCylinder(qobj, 12.0, 12.0, 50.0, 30, 10);
glPopMatrix();
// prevents memory leak
gluDeleteQuadric(qobj);
}
// field with avi
void drawArena5(void)
{
// lighting
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat diffuse_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat ambient_light[] = {0.6, 0.6, 0.6, 1.0};
GLfloat light_pos[] = {0.0, 0.0, 0.0, 9.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, white_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);
// field
glBindTexture(GL_TEXTURE_2D, texture[10]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 10, BORDER_Y + 3, -5);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 10, BORDER_Y + 3, -5);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, -BORDER_Y - 3, -5);
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, -BORDER_Y - 3, -5);
glEnd();
// display board
glPushMatrix();
glTranslatef(-10, 30, 5);
glBindTexture(GL_TEXTURE_2D, texture[13]);
gluCube(0.5, 0.5, 5);
glTranslatef(20, 0, 0);
gluCube(0.5, 0.5, 5);
// AVI movie
glTranslatef(-10, -1, 7);
glRotatef(90.0, 1.0, 0, 0);
pAVI.GrabAVIFrame(texture[14]);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 12, 8, 0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-12, 8, 0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-12, -8, 0);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 12, -8, 0);
glEnd();
glPopMatrix();
// top side
glBindTexture(GL_TEXTURE_2D, texture[11]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, BORDER_Y + 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, BORDER_Y + 3, -5 );
glEnd();
// left side
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-BORDER_X - 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, -BORDER_Y - 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f(-BORDER_X - 10, BORDER_Y + 3, -5 );
glEnd();
// bottom side
glBegin(GL_LINE_LOOP);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-BORDER_X - 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-BORDER_X - 10, -BORDER_Y - 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, -BORDER_Y - 3, -5 );
glEnd();
// right side
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f( BORDER_X + 20, BORDER_Y + 20, +15);
glTexCoord2f(1.0f, 0.0f); glVertex3f( BORDER_X + 20, -BORDER_Y - 20, +15);
glTexCoord2f(1.0f, 1.0f); glVertex3f( BORDER_X + 10, -BORDER_Y - 3, -5 );
glTexCoord2f(0.0f, 1.0f); glVertex3f( BORDER_X + 10, BORDER_Y + 3, -5 );
glEnd();
}
// space rotary
void drawArena6()
{
static GLfloat rot1 = 0.0f;
static GLfloat rot2 = 0.0f;
static GLfloat rot3 = 0.0f;
// init the quadric object
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, polyMode);
gluQuadricNormals(qobj, GLU_SMOOTH);
gluQuadricTexture(qobj, texMode);
// small rotary
glPushMatrix();
glRotatef(rot1, 0.0, 1.0, 0.0);
rot1 = rot1 + (GLfloat) 0.1f;
glRotatef(90, 1, 0, 0);
glTranslatef(0, 0, 15);
glBindTexture(GL_TEXTURE_2D, texture[15]);
gluCylinder(qobj, 12.0, 12.0, 5.0, 20, 10);
gluCylinder(qobj, 13.0, 13.0, 5.0, 20, 10);
gluDisk(qobj, 12.0, 13.0, 20, 1);
glTranslatef(0, 0, 5);
gluDisk(qobj, 12.0, 13.0, 20, 1);
glPopMatrix();
// two circling spheres
glPushMatrix();
glRotatef(rot3, 0.0, 1.0, 0.0);
rot3 = rot3 + (GLfloat) 2.0f;
// enable blend and env mapping
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_SRC_COLOR);
glRotatef(90, 1, 0, 0);
glTranslatef(0, 30, 0);
glBindTexture(GL_TEXTURE_2D, texture[15]);
gluSphere(qobj, 5, 10, 10);
glTranslatef(0, -60, 0);
gluSphere(qobj, 5, 10, 10);
// disable blend and env mapping
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glPopMatrix();
// big rotary
glPushMatrix();
glRotatef(rot2, 0.0, 1.0, 0.0);
rot2 = rot2 - (GLfloat) 0.5f;
glRotatef(90, 1, 0, 0);
glTranslatef(0, 0, -20);
glBindTexture(GL_TEXTURE_2D, texture[15]);
gluCylinder(qobj, 10.0, 10.0, 10.0, 20, 10);
gluCylinder(qobj, 15.0, 15.0, 10.0, 20, 10);
gluDisk(qobj, 10.0, 15.0, 20, 1);
glTranslatef(0, 0, 10);
gluDisk(qobj, 10.0, 15.0, 20, 1);
glTranslatef(22, 0, -5);
gluCube(10, 1, 1);
glTranslatef(-44, 0, 0);
gluCube(10, 1, 1);
glTranslatef(22, 22, 0);
glRotatef(90, 0, 0, 1);
gluCube(10, 1, 1);
glTranslatef(-44, 0, 0);
gluCube(10, 1, 1);
glPopMatrix();
gluDeleteQuadric(qobj);
}
//***********************************************************
//FUNCTION: void arrowKeys(int key, int x, int y) *
// Arrow keys are used for game play *
//***********************************************************
void arrowKeys(int key, int x, int y)
{
const GLfloat PROT_FACTOR = 1.00F;
const GLfloat ZOOM_FACTOR = 0.15F;
switch (key)
{
case GLUT_KEY_LEFT: // player1 left movement
if (x1 > -BORDER_X)
x1 -= PADDLE_VEL;
break;
case GLUT_KEY_RIGHT: // player1 right movement
if (x1 < BORDER_X)
x1 += PADDLE_VEL;
break;
case GLUT_KEY_UP: // rotate and zoom in
if (pr < 85.0f)
{
pr += PROT_FACTOR;
pz += ZOOM_FACTOR;
}
break;
case GLUT_KEY_DOWN: // rotate and zoom out
if (pr > 0.0f)
{
pr -= PROT_FACTOR;
pz -= ZOOM_FACTOR;
}
break;
default:
break;
}
}
void gameInit(const GLfloat difficulty_speed)
{
// restart game
startgame = true;
gameover = false;
bx = (GLfloat) 0.0F;
by = (GLfloat) 0.0F;
srand(time(NULL));
// attach a random (x,y) speed on the ball
xv = (GLfloat) (((GLfloat) (rand() % 10)) / 100);
yv = (GLfloat) (((GLfloat) (rand() % 10)) / 100);
// append the difficulty speed
xv += difficulty_speed;
yv += difficulty_speed;
// append random direction (velocity) of the ball
xv = (((rand() % 2) == 1) ? xv : -xv);
yv = (((rand() % 2) == 1) ? yv : -yv);
}
void collisionDetection(void)
{
char score[128];
static int score_p1 = 0, score_p2 = 0;
// bounce the ball if it collides with the
// left or right walls [left and right side of screen]
//
if (bx > BORDER_X || bx < -BORDER_X)
{
PlaySound("Bounce.wav", NULL, SND_ASYNC | SND_FILENAME);
xv = -xv;
}
// test the ball if it collides with the top or bottom wall
if (by > PADDLE_POS - 1 || by < -PADDLE_POS + 1)
{
// bounce the ball if it collides with the
// top or bottom paddle
//
if ((bx > x1 - 3.5 && bx < x1 + 3.5 && by < 0) ||
(bx > x2 - 3.5 && bx < x2 + 3.5 && by > 0))
{
PlaySound("Bounce.wav", NULL, SND_ASYNC | SND_FILENAME);
yv = -yv;
}
else
{
// someone lost the match, display current score
PlaySound("Out.wav", NULL, SND_ASYNC | SND_FILENAME);
memset(score, '0', sizeof(score));
if(by > PADDLE_POS-1) // if P1 wins
{
score_p1++;
sprintf(score, "You win!\t\t\t\n\n");
sprintf(score, "%sComputer: \t%d\n", score, score_p2);
sprintf(score, "%sPlayer 1:\t\t%d\n", score, score_p1);
MessageBox(NULL, score, "Score", MB_OK | MB_ICONINFORMATION);
keyboard(dLevel, 0, 0);
}
else if (by < -PADDLE_POS+1) // if P2 wins [computer]
{
score_p2++;
sprintf(score, "Computer wins!\t\t\n\n");
sprintf(score, "%sComputer: \t%d\n", score, score_p2);
sprintf(score, "%sPlayer 1:\t\t%d\n", score, score_p1);
MessageBox(NULL, score, "Score", MB_OK | MB_ICONINFORMATION);
keyboard(dLevel, 0, 0);
}
// gameover, reset score and enter epilogue
if (score_p1 >= MAX_SCORE || score_p2 >= MAX_SCORE)
{
score_p1 = score_p2 = 0;
gameover = true;
startgame = false;
PlaySound("Gameover.wav", NULL, SND_FILENAME | SND_ASYNC);
}
}
}
}
void showFlag(const GLuint tex)
{
GLfloat float_x, float_y, float_xb, float_yb;
glLoadIdentity();
glTranslatef(0.0f,0.0f,-4.5f);
glBindTexture(GL_TEXTURE_2D, tex);
// draws the background with with a flag effect
glBegin(GL_QUADS);
for (int x = 0; x < GRID_POINTS-1; x++)
{
for (int y = 0; y < GRID_POINTS-1; y++)
{
float_x = GLfloat(x) / ((GLfloat)(GRID_POINTS-1));
float_y = GLfloat(y) / ((GLfloat)(GRID_POINTS-1));
float_xb = GLfloat(x+1) / ((GLfloat)(GRID_POINTS-1));
float_yb = GLfloat(y+1) / ((GLfloat)(GRID_POINTS-1));
glTexCoord2f(float_x, float_y);
glVertex3f(points[x][y][0],points[x][y][1],points[x][y][2]);
glTexCoord2f(float_x, float_yb);
glVertex3f(points[x][y+1][0],points[x][y+1][1],points[x][y+1][2]);
glTexCoord2f(float_xb, float_yb);
glVertex3f(points[x+1][y+1][0],points[x+1][y+1][1],points[x+1][y+1][2]);
glTexCoord2f(float_xb, float_y);
glVertex3f(points[x+1][y][0],points[x+1][y][1],points[x+1][y][2]);
}
}
glEnd();
}
//***********************************************************
//FUNCTION: void displayFPS(void) *
// Determines the Frames Per Second (FPS) when graphics *
// are rendered to the screen. Handy for determining *
// hardware performance over 3D graphics acceleration. *
// *
// Standard FPS range: 30-60 fps *
//***********************************************************
void displayFPS(void)
{
static float framesPerSecond = 0.0f;
static float lastTime = 0.0f;
static char strFrameRate[32] = {0};
float currentTime = GetTickCount() * 0.001f;
++framesPerSecond;
if (currentTime - lastTime > 1.0f)
{
lastTime = currentTime;
sprintf(strFrameRate, "3D Pong [FPS: %d]", int(framesPerSecond));
glutSetWindowTitle(strFrameRate);
framesPerSecond = 0;
}
}
void gluCube(const GLfloat l, const GLfloat w, const GLfloat h)
{
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-l, -w, h); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( l, -w, h); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( l, w, h); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-l, w, h); // Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-l, -w, -h); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-l, w, -h); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( l, w, -h); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( l, -w, -h); // Bottom Left Of The Texture and Quad
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-l, w, -h); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-l, w, h); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( l, w, h); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( l, w, -h); // Top Right Of The Texture and Quad
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-l, -w, -h); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( l, -w, -h); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( l, -w, h); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-l, -w, h); // Bottom Right Of The Texture and Quad
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( l, -w, -h); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( l, w, -h); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( l, w, h); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( l, -w, h); // Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-l, -w, -h); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-l, -w, h); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-l, w, h); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-l, w, -h); // Top Left Of The Texture and Quad
glEnd();
}
// flip the RED and BLUE bits of the movie
void AVI_Player::flipIt(void* buffer) const
{
void* b = buffer; // Pointer To The Buffer
__asm // Assembler Code To Follow
{
mov ecx, 256*256 // Counter Set To Dimensions Of Our Memory Block
mov ebx, b // Points ebx To Our Data (b)
label: // Label Used For Looping
mov al,[ebx+0] // Loads Value At ebx Into al
mov ah,[ebx+2] // Loads Value At ebx+2 Into ah
mov [ebx+2],al // Stores Value In al At ebx+2
mov [ebx+0],ah // Stores Value In ah At ebx
add ebx,3 // Moves Through The Data By 3 Bytes
dec ecx // Decreases Our Loop Counter
jnz label // If Not Zero Jump Back To Label
}
}
AVI_Player::AVI_Player()
{
this->data = 0;
this->frame = 0;
this->hdc = CreateCompatibleDC(0);
this->hdd = DrawDibOpen(); // Grab A Device Context For Our Dib
}
void AVI_Player::OpenAVI(const LPCSTR szFile)
{
AVIFileInit(); // Opens The AVIFile Library
// Opens The AVI Stream
if (AVIStreamOpenFromFile(&pavi, szFile, streamtypeVIDEO, 0, OF_READ, NULL) !=0)
{
// An Error Occurred Opening The Stream
MessageBox (HWND_DESKTOP, "Failed To Open The AVI Stream", "Error", MB_OK | MB_ICONEXCLAMATION);
}
AVIStreamInfo(pavi, &psi, sizeof(psi)); // Reads Information About The Stream Into psi
width=psi.rcFrame.right-psi.rcFrame.left; // Width Is Right Side Of Frame Minus Left
height=psi.rcFrame.bottom-psi.rcFrame.top; // Height Is Bottom Of Frame Minus Top
lastframe=AVIStreamLength(pavi); // The Last Frame Of The Stream
mpf=AVIStreamSampleToTime(pavi,lastframe)/lastframe; // Calculate Rough Milliseconds Per Frame
bmih.biSize = sizeof (BITMAPINFOHEADER); // Size Of The BitmapInfoHeader
bmih.biPlanes = 1; // Bitplanes
bmih.biBitCount = 24; // Bits Format We Want (24 Bit, 3 Bytes)
bmih.biWidth = 256; // Width We Want (256 Pixels)
bmih.biHeight = 256; // Height We Want (256 Pixels)
bmih.biCompression = BI_RGB; // Requested Mode = RGB
hBitmap = CreateDIBSection (hdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS, (void**)(&data), NULL, NULL);
SelectObject (hdc, hBitmap); // Select hBitmap Into Our Device Context (hdc)
pgf=AVIStreamGetFrameOpen(pavi, NULL); // Create The PGETFRAME Using Our Request Mode
if (pgf==NULL)
{
// An Error Occurred Opening The Frame
MessageBox (HWND_DESKTOP, "Failed To Open The AVI Frame", "Error", MB_OK | MB_ICONEXCLAMATION);
}
}
AVI_Player::~AVI_Player()
{
DeleteObject(hBitmap); // Delete The Device Dependant Bitmap Object
DrawDibClose(hdd); // Closes The DrawDib Device Context
AVIStreamGetFrameClose(pgf); // Deallocates The GetFrame Resources
AVIStreamRelease(pavi); // Release The Stream
AVIFileExit(); // Release The File
}
void AVI_Player::GrabAVIFrame(const GLuint tex)
{
this->UpdateAVI();
LPBITMAPINFOHEADER lpbi; // Holds The Bitmap Header Information
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, this->frame); // Grab Data From The AVI Stream
pdata=(char *)lpbi+lpbi->biSize+lpbi->biClrUsed * sizeof(RGBQUAD); // Pointer To Data Returned By AVIStreamGetFrame
// Convert Data To Requested Bitmap Format
DrawDibDraw (hdd, hdc, 0, 0, 256, 256, lpbi, pdata, 0, 0, width, height, 0);
flipIt(data); // Swap The Red And Blue Bytes (GL Compatability)
// Update The Texture
glBindTexture(GL_TEXTURE_2D, tex);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, data);
}
void AVI_Player::UpdateAVI()
{
DWORD milliseconds;
static DWORD tickCount, lastTickCount;
tickCount = GetTickCount(); // Get The Tick Count
milliseconds = tickCount - lastTickCount;
next+=milliseconds; // Increase next Based On The Timer
frame=next/mpf; // Calculate The Current Frame
if (frame>=lastframe) // Are We At Or Past The Last Frame?
{
frame=0; // Reset The Frame Back To Zero (Start Of Video)
next=0; // Reset The Animation Timer (next)
}
lastTickCount = tickCount; // Set Last Count To Current Count
}