Code:
#include <math.h>
#include "gl/freeglut.h"
#include "loadTGA.h"
#include <mmsystem.h>
#include "vector3D.h"
#include "Camera.h"
#include "Draw.h"
#include "Projectile.h"
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
// realtime loop control
long timelastcall;
// realtime loop control - frequency
float frequency;
// The number of frames
int frameCount;
// Number of frames per second
float fps;
// currentTime - previousTime is the time elapsed
// between every call of the Idle function
int currentTime, previousTime;
// Pointer to a font style..
// Fonts supported by GLUT are: GLUT_BITMAP_8_BY_13,
// GLUT_BITMAP_9_BY_15, GLUT_BITMAP_TIMES_ROMAN_10,
// GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10,
// GLUT_BITMAP_HELVETICA_12, and GLUT_BITMAP_HELVETICA_18.
void *font_style;
void printw (float x, float y, float z, char* format, ...);
Camera * theCamera;
Draw * draw;
bool myKeys[255];
float angle;
// The projectiles
CProjectile* theProjectiles;
const static int MAXPROJECTILES = 100;
int m_iProjectileIndex;
bool inits();
enum {
TOP = 0,
GROUND,
LEFT,
RIGHT,
BACK,
FRONT,
CRATE,
};
typedef struct {
bool mLButtonUp;
bool mRButtonUp;
bool middleButtonUp;
int mX, mY;
} SMouse;
typedef struct {
float mEyeX, mEyeY, mEyeZ;
float mLookX, mLookY, mLookZ;
float mUpX, mUpY, mUpZ;
float mPitch, mRoll, mYaw;
} SCamera;
TextureImage Texture[8];
SCamera camera;
SMouse mouse;
void init (void) {
glClearColor (0.0, 0.0, 0.0, 0.0); // set background colour to black
//glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
glShadeModel (GL_SMOOTH);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45.0, 1.45, 1.0, 1000.0);
glMatrixMode (GL_MODELVIEW);
theCamera = new Camera( Camera::LAND_CAM );
theCamera->SetPosition( 0.0, 0.0, 0.0 ); //0, 2, -5
theCamera->SetDirection( 0.0, 0.0, 1.0 ); //0, 0, 1
loadTGA (&Texture[0], "Images/top.tga");
glEnable (GL_TEXTURE_2D);
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);
loadTGA (&Texture[1], "Images/ground.tga");
glEnable (GL_TEXTURE_2D);
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);
loadTGA (&Texture[2], "Images/left.tga");
glEnable (GL_TEXTURE_2D);
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);
loadTGA (&Texture[3], "Images/right.tga");
glEnable (GL_TEXTURE_2D);
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);
loadTGA (&Texture[4], "Images/front.tga");
glEnable (GL_TEXTURE_2D);
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);
loadTGA (&Texture[5], "Images/back.tga");
glEnable (GL_TEXTURE_2D);
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);
loadTGA (&Texture[6], "Images/crate.tga");
glEnable (GL_TEXTURE_2D);
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);
}
bool inits(void)
{
// The number of frames
frameCount = 0;
// Number of frames per second
fps = 0;
// currentTime - previousTime is the time elapsed
// between every call of the Idle function
currentTime = 0, previousTime = 0;
// Pointer to a font style..
// Fonts supported by GLUT are: GLUT_BITMAP_8_BY_13,
// GLUT_BITMAP_9_BY_15, GLUT_BITMAP_TIMES_ROMAN_10,
// GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10,
// GLUT_BITMAP_HELVETICA_12, and GLUT_BITMAP_HELVETICA_18.
//GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_24;
font_style = GLUT_BITMAP_TIMES_ROMAN_24;
frequency = 30.0f;
return true;
}
void drawFPS()
{
// Load the identity matrix so that FPS string being drawn
// won't get animates
glLoadIdentity ();
printw (25.0, 25.0, 0, "FPS: %4.2f", fps);
}
void calculateFPS()
{
// Increase frame count
frameCount++;
// Get the number of milliseconds since glutInit called
// (or first call to glutGet(GLUT ELAPSED TIME)).
currentTime = glutGet(GLUT_ELAPSED_TIME);
// Calculate time passed
int timeInterval = currentTime - previousTime;
if(timeInterval > 1000)
{
// calculate the number of frames per second
fps = frameCount / (timeInterval / 1000.0f);
// Set time
previousTime = currentTime;
// Reset frame count
frameCount = 0;
}
}
void printw (float x, float y, float z, char* format, ...)
{
va_list args; // Variable argument list
int len; // String length
int i; // Iterator
char * text; // Text
// Initialize a variable argument list
va_start(args, format);
// Return the number of characters in the string referenced the list of arguments.
// _vscprintf doesn't count terminating '\0' (that's why +1)
len = _vscprintf(format, args) + 1;
// Allocate memory for a string of the specified size
text = (char *)malloc(len * sizeof(char));
// Write formatted output using a pointer to the list of arguments
vsprintf_s(text, len, format, args);
// End using variable argument list
va_end(args);
// Specify the raster position for pixel operations.
glRasterPos3f (x, y, z);
// Draw the characters one by one
for (i = 0; text[i] != '\0'; i++)
glutBitmapCharacter(font_style, text[i]);
// Free the allocated memory for the string
free(text);
}
void rescale (GLsizei w, GLsizei h) {
glViewport (0, 0, w, h);
}
void onMouseClick (int button, int state, int x, int y) {
switch (button) {
case GLUT_LEFT_BUTTON:
mouse.mLButtonUp = state;
mouse.mX = x;
mouse.mY = y;
if (mouse.mLButtonUp)
{
// Add codes to manage the bullets shot out
// and the remaining bullets
}
break;
case GLUT_RIGHT_BUTTON:
//mouse.mRButtonUp = state;
//mouse.mX = x;
//mouse.mY = y;
break;
case GLUT_MIDDLE_BUTTON:
break;
}
}
void MouseMove (int x, int y)
{
int diffX = x - mouse.mX;
int diffY = y - mouse.mY;
//Update on y axis
theCamera->Pitch( diffY * 3.142f / 180.0f );
////Update on x and z axis
angle += (float) diffX * 3.142f / 180.0f;
if (angle > 6.284f)
angle -= 6.284f;
else if (angle < -6.284f)
angle += 6.284f;
theCamera->Yaw( -angle );
mouse.mX = x;
mouse.mY = y;
//Checking mouse boundary. // 800 is the window width. You may need to change this to suit your program.
if (mouse.mX > 800-20 || mouse.mX < 20) //800
{
mouse.mX = (800 >> 1);
glutWarpPointer(mouse.mX, mouse.mY);
}
// 600 is the window height. You may need to change this to suit your program.
if (mouse.mY > 600-20 || mouse.mY < 20) //600
{
mouse.mY = (600 >> 1);
glutWarpPointer(mouse.mX, mouse.mY);
}
}
void KeyboardDown(unsigned char key, int x, int y){
myKeys[key]= true;
}
void KeyboardUp(unsigned char key, int x, int y){
myKeys[key]= false;
}
void Squating(bool mode, float timeDiff)
{
if (mode)
{
theCamera ->Squat(1.0f);
}
}
void Jump(bool mode, float timeDiff)
{
if(mode)
{
theCamera ->Jump(1.0f);
}
}
void moveForward(bool mode, float timeDiff)
{
int walk = 0;
if (mode )
{
theCamera->Walk( 1.0f );
}
else
{
theCamera->Walk( -1.0f );
}
}
void moveSideWay(bool mode, float timeDiff)
{
if (mode)
{
theCamera->Strafe( -1.0f );
}
else
{
theCamera->Strafe( 1.0f );
}
}
void update()
{
if(myKeys['w'] == true)
moveForward(true, 1.0f);
if(myKeys['a'] == true)
moveSideWay(true, 1.0f);
if(myKeys['s'] == true)
moveForward(false, 1.0f);
if(myKeys['d'] == true)
moveSideWay(false, 1.0f);
if(myKeys['k'] == true)
Jump(true, 1.0f);
if(myKeys['l'] == true)
Squating(true, 1.0f);
}
/*
void orientMe(float ang)
{
theCameraDirection.x += sin(ang);
theCameraDirection.z += -cos(ang);
}
*/
void skybox()
{
//front
glBindTexture(GL_TEXTURE_2D, Texture[FRONT].id);
glBegin(GL_QUADS);
glTexCoord2f(0,1);glVertex3f(201, 201, 200);
glTexCoord2f(1,1);glVertex3f(-201, 201, 200);
glTexCoord2f(1,0);glVertex3f(-201, -201, 200);
glTexCoord2f(0,0);glVertex3f(201,-201, 200);
glEnd();
//left
glBindTexture(GL_TEXTURE_2D, Texture[LEFT].id);
glBegin(GL_QUADS);
glTexCoord2f(1,1);glVertex3f(200, 201, 201); //0, 1
glTexCoord2f(1,0);glVertex3f(200, -201, 201); //0, 0
glTexCoord2f(0,0);glVertex3f(200, -201, -201); //1, 0
glTexCoord2f(0,1);glVertex3f(200, 201, -201); //1, 1
glEnd();
//right
glBindTexture(GL_TEXTURE_2D, Texture[RIGHT].id);
glBegin(GL_QUADS);
glTexCoord2f(0,1);glVertex3f(-200, 201, 201);
glTexCoord2f(0,0);glVertex3f(-200, -201, 201);
glTexCoord2f(1,0);glVertex3f(-200, -201, -201);
glTexCoord2f(1,1);glVertex3f(-200, 201, -201);
glEnd();
//top
glBindTexture(GL_TEXTURE_2D, Texture[TOP].id);
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex3f(201, 200, 201); //0, 0
glTexCoord2f(1,0);glVertex3f(-201, 200, 201);//1, 0
glTexCoord2f(1,1);glVertex3f(-201, 200, -201);//1, 1
glTexCoord2f(0,1);glVertex3f(201, 200, -201);//0, 1
glEnd();
//back
glBindTexture(GL_TEXTURE_2D, Texture[BACK].id);
glBegin(GL_QUADS);
glTexCoord2f(1,1);glVertex3f(201, 201, -200); //0, 1 ,// 1, 1
glTexCoord2f(0,1);glVertex3f(-201, 201, -200); //1, 1 , //0, 1
glTexCoord2f(0,0);glVertex3f(-201, -201, -200);//0, 0, //0, 0
glTexCoord2f(1,0);glVertex3f(201, -201, -200); //1, 0,// 1, 0
glEnd();
//bottom
glBindTexture(GL_TEXTURE_2D, Texture[GROUND].id);
glBegin(GL_QUADS);
glTexCoord2f(0, 1);glVertex3f(201, -200, 201);
glTexCoord2f(1,1);glVertex3f(-201, -200, 201);
glTexCoord2f(1,0);glVertex3f(-201, -200, -201);
glTexCoord2f(0,0);glVertex3f(201, -200, -201);
glEnd();
}
void drawCrate()
{
//front
glBindTexture(GL_TEXTURE_2D, Texture[CRATE].id);
glBegin(GL_QUADS);
glTexCoord2f(0,1);glVertex3f(10, 10, 10);
glTexCoord2f(1,1);glVertex3f(-10, 10, 10);
glTexCoord2f(1,0);glVertex3f(-10, -10, 10);
glTexCoord2f(0,0);glVertex3f(10,-10, 10);
glEnd();
//left
glBindTexture(GL_TEXTURE_2D, Texture[CRATE].id);
glBegin(GL_QUADS);
glTexCoord2f(1,1);glVertex3f(10, 10, 10); //0, 1
glTexCoord2f(1,0);glVertex3f(10, -10, 10); //0, 0
glTexCoord2f(0,0);glVertex3f(10, -10, -10); //1, 0
glTexCoord2f(0,1);glVertex3f(10, 10, -10); //1, 1
glEnd();
//right
glBindTexture(GL_TEXTURE_2D, Texture[CRATE].id);
glBegin(GL_QUADS);
glTexCoord2f(0,1);glVertex3f(-10, 10, 10);
glTexCoord2f(0,0);glVertex3f(-10, -10, 10);
glTexCoord2f(1,0);glVertex3f(-10, -10, -10);
glTexCoord2f(1,1);glVertex3f(-10, 10, -10);
glEnd();
//top
glBindTexture(GL_TEXTURE_2D, Texture[CRATE].id);
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex3f(10, 10, 10); //0, 0
glTexCoord2f(1,0);glVertex3f(-10, 10, 10);//1, 0
glTexCoord2f(1,1);glVertex3f(-10, 10, -10);//1, 1
glTexCoord2f(0,1);glVertex3f(10, 10, -10);//0, 1
glEnd();
//back
glBindTexture(GL_TEXTURE_2D, Texture[CRATE].id);
glBegin(GL_QUADS);
glTexCoord2f(1,1);glVertex3f(10, 10, -10); //0, 1 ,// 1, 1
glTexCoord2f(0,1);glVertex3f(-10, 10, -10); //1, 1 , //0, 1
glTexCoord2f(0,0);glVertex3f(-10, -10, -10);//0, 0, //0, 0
glTexCoord2f(1,0);glVertex3f(10, -10, -10); //1, 0,// 1, 0
glEnd();
//bottom
glBindTexture(GL_TEXTURE_2D, Texture[CRATE].id);
glBegin(GL_QUADS);
glTexCoord2f(0, 1);glVertex3f(10, -10, 10);
glTexCoord2f(1,1);glVertex3f(-10, -10, 10);
glTexCoord2f(1,0);glVertex3f(-10, -10, -10);
glTexCoord2f(0,0);glVertex3f(10, -10, -10);
glEnd();
}
void renderScene()
{
glPushMatrix();
glScalef(1, 0.25, 1);
glTranslatef(0, 190, -190);
skybox();
glPopMatrix();
glPushMatrix();
glTranslatef(188,7.5 , -100);
drawCrate();
glPopMatrix();
glPushMatrix();
glTranslatef(-188,7.5 , -100);
drawCrate();
glPopMatrix();
glPushMatrix();
glTranslatef(188,7.5 , -160);
drawCrate();
glPopMatrix();
glPushMatrix();
glTranslatef(-188,7.5 , -160);
drawCrate();
glPopMatrix();
}
void MyDisplay (void) {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSetCursor(GLUT_CURSOR_NONE); //hide cursor
theCamera->SetHUD( false );
glLoadIdentity ();
theCamera->Update();
//for (int i=0; i<MAXPROJECTILES; i++)
//{
// if (theProjectiles[i].GetStatus())
// printf("Displaying projectile #%d\n", i);
// theProjectiles[i].Update( );
//}
if ((timeGetTime()-timelastcall)>1000/frequency)
{
// Calculate the framerate
calculateFPS();
timelastcall=timeGetTime();
update();
}
glPushMatrix();
//glScalef(1, 0.25, 1);
//glTranslatef(0, 190, -190);
renderScene();
glPopMatrix();
void printw (float x, float y, float z, char* format, ...);
bool inits();
// Enable 2D text display and HUD
theCamera->SetHUD( true );
// Display framerate
glColor3f(0.0f,1.0f,0.0f);
drawFPS();
//draw circle
draw ->drawCircle(10, 10);
draw ->drawCircle(15, 15);
glBegin(GL_LINES);
glVertex2i( 350, 300 );
glVertex2i( 450, 300 );
glEnd();
glBegin(GL_LINES);
glVertex2i( 400, 250 );
glVertex2i( 400, 350 );
glEnd();
//draw health bar in words
glColor3f(1.0f,1.0f,0.0f);
printw (550.0, 100.0, 0, "Ammo: ___/100"); //25
//printw (550.0, 130.0, 0, "Health: ___/100");//25
printw (620.0, 30.0, 0, "Health");
//draw health bar in square
draw ->drawHealthBar();
//draw MiniMap
int height = 100 * 1.333/1.5;
glColor3f(1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, Texture[GROUND].id);
glPushMatrix();
glTranslatef(75.0,520.0,0.0);
glRotatef( -1*atan2(theCamera->GetDirection().x, theCamera->GetDirection().z) * 180/3.142,
0, 0, 1);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex2f(-50,50);
glTexCoord2f(1,0); glVertex2f(50,50);
glTexCoord2f(1,1); glVertex2f(50,-50);
glTexCoord2f(0,1); glVertex2f(-50,-50);
glEnd();
glPopMatrix();
glDisable(GL_BLEND);
glPopMatrix();
//draw player icon in minimap
glPushMatrix();
glColor3f(1.0f,1.0f,0.5f);
glTranslatef(65.0, 510.0,0.0);
glPushMatrix();
glRotatef( atan2(theCamera->GetDirection().x, theCamera->GetDirection().z) * 180/3.142,
0, 0, 1);
glBegin(GL_TRIANGLES);
glVertex2f( 0.0f, -10.0f );
glVertex2f( 5.0f, 10.0f );
glVertex2f( -5.0f, 10.0f );
glEnd();
glPopMatrix();
glPopMatrix();
glColor3f(1, 1, 1);
glDisable(GL_TEXTURE_2D);
theCamera->SetHUD( false );
// Flush off any entity which is not drawn yet, so that we maintain the frame rate.
glFlush();
glutSwapBuffers ();
glutPostRedisplay ();
}
void main (int argc, char * argv[]) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (50, 50);
glutCreateWindow ("Image");
glutDisplayFunc (MyDisplay);
glutReshapeFunc (rescale); // to be called when window size has changed
glutPassiveMotionFunc(MouseMove);
glutMouseFunc(onMouseClick);// for mouse click
glutKeyboardFunc(KeyboardDown);
glutKeyboardUpFunc(KeyboardUp);
init ();
inits();
glutMainLoop ();
}
Vector3D.h