top of page

Football Game


#include <math.h>                        
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <iostream>    
#include <gl/freeglut.h>
#include <iostream>

#ifdef WIN32
#include "gltools.h"
#include <windows.h>        // Must have for Windows platform builds
#include <gl\gl.h>            // Microsoft OpenGL headers (version 1.1 by themselves)
#include <gl\glu.h>            // OpenGL Utilities
#include "glm.h"

#endif

//note that this needs gltools.h and gltools.cpp to be included in the shared directory

//can define any number of textures here - we just have 5 images
//these are just integers so you can use them as such
#define SKYBOX_SIZE -390.0f
#define PI 3.142    
#define IMAGE1      0 //10 points
#define IMAGE2      1 //30 points
#define IMAGE3      2 //Grass
#define IMAGE4      3 //Stone brick texture
#define TEXTURE_BALL 4 //Football map
#define IMAGE5      5 //20 points
#define SKYBOX_MAP  6 //Sky Box
#define IMAGE7      7 //Orange Plant
#define IMAGE8      8 //Yellow Plant
#define TEXTURE_COUNT 9
GLuint  textures[TEXTURE_COUNT];


//camera
GLfloat cameraX = 0.0;
GLfloat cameraY = 100;
GLfloat cameraZ = 500.0;
GLfloat skyRotatex;

bool repeatOn = false;
bool repeatWallOn = false;
bool moveCamera = false;
bool ballshotPress = false;
bool followBallPress = false;

    
//below is simply a character array to hold the file names
//note that you may need to replace the below with the full directory root depending on where you put your image files
//if you put them where the exe is then you just need the name as below
const char *textureFiles[TEXTURE_COUNT] = { "targetGreen.tga", "targetRed.tga","grass_diff.tga","stone.tga","FootballCompleteMap.tga", "targetBlue.tga", "stormydays_large.tga", "orangeFlowerFinal5.tga", "yellowFlowerFinal.tga", };


//for lighting or materials if you want to experiment with these

GLfloat mKa[4] = { 0.11f,0.11f,0.11f,1.0f }; //ambient
GLfloat mKd[4] = { 0.43f,0.43f,0.43f,1.0f }; //diffuse
GLfloat mKs[4] = { 1.0f,1.0f,1.0f,1.0f }; //specular
GLfloat mKe[4] = { 0.5f,0.5f,0.0f,1.0f }; //emission

                                          //spot position and direction
GLfloat     lightPos[] = { 0.0, 100.0, 300.0, 0.0f };
GLfloat  spotDir[] = { 50.0, 25.0, 0.0 };

GLfloat     lightPos2[] = { 50.0, 100.0, 300.0, 0.0f };
GLfloat  spotDir2[] = { 50.0, 15.0, 0.0 };

GLfloat     lightPos3[] = { -50.0, 100.0, 300.0, 0.0f };
GLfloat  spotDir3[] = { 50.0, 15.0, 0.0 };


// Useful lighting colour values
GLfloat  whiteLightBright[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat  redLight[] = { 1.0f, 0.0f, 0.0f, 1.0f };
GLfloat  greenLight[] = { 0.0f, 1.0f, 0.0f, 1.0f };
GLfloat  blueLight[] = { 0.0f, 1.0f, 1.0f, 1.0f };
GLfloat  whiteLightLessBright[] = { 0.8f, 0.8f, 0.8f, 1.0f };

 

//we need these for the texture loader
//they are to do with the image format and size
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
// this is a pointer to memory where the image bytes will be held 
GLbyte *pBytes0;

//end of intialisation 

//------------------------------------//
void drawTexturedQuad(int image)
{
    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(1.0, 1.0, 1.0);
    glEnable(GL_TEXTURE_2D);
    //bind the texture 
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-50.0, -50.0, 0.0);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(50.0, -50.0, 0.0);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(50.0, 50.0, 0.0);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-50.0, 50.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);

}

GLUquadricObj *quadricFootball;
void drawFootBall(GLfloat x, GLfloat y, GLfloat z, GLfloat r) {
    glPushMatrix();
    glFrontFace(GL_CCW);
    glTranslatef(x, y, z);
    // Create and texture the ball
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BALL]);
    // glDisable(GL_LIGHTING);
    glColor3f(0.5, 0.5, 0.5);
    quadricFootball = gluNewQuadric();
    gluQuadricDrawStyle(quadricFootball, GLU_FILL);
    gluQuadricNormals(quadricFootball, GLU_SMOOTH);
    gluQuadricOrientation(quadricFootball, GLU_OUTSIDE);
    gluQuadricTexture(quadricFootball, GL_TRUE);
    gluSphere(quadricFootball, r, 50, 35);
    glDisable(GL_TEXTURE_2D);
    glPopMatrix();
}

void drawTexturedSurface(int image)
{
    //add some lighting normals for each vertex
    //draw the texture on the front
    //draw face up and then rotated
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(1.0, 1.0, 1.0);
    glEnable(GL_TEXTURE_2D);
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(-4.0, -4.0);//repeated texture
    glVertex3f(-800.0, -800.0, 0.0);
    glTexCoord2f(4.0, -4.0);
    glVertex3f(800.0, -800.0, 0.0);
    glTexCoord2f(4.0, 4.0);
    glVertex3f(800.0, 800.0, 0.0);
    glTexCoord2f(-4.0, 4.0);
    glVertex3f(-800.0, 800.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);

}

void drawTexturedSurfaceNoTiling(int image)
{
    //add some lighting normals for each vertex
    //draw the texture on the front
    //draw face up and then rotated
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable(GL_TEXTURE_2D);
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0, 0);//repeated texture
    glVertex3f(-800.0, -800.0, 0.0);
    glTexCoord2f(1, 0);
    glVertex3f(800.0, -800.0, 0.0);
    glTexCoord2f(1, 1);
    glVertex3f(800.0, 800.0, 0.0);
    glTexCoord2f(0, 1);
    glVertex3f(-800.0, 800.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);

}
GLfloat cubeVertexData[108] =
{//object vertex coordinates for cube made from triangles
    // Data layout for each line below is:
    // positionX, positionY, positionZ
    //wind counter-clockwise
    //1
    SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE,  SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE,  SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE,  SKYBOX_SIZE,
    SKYBOX_SIZE,  SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE,  SKYBOX_SIZE,  SKYBOX_SIZE,
    //2
    SKYBOX_SIZE, SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE, SKYBOX_SIZE,  SKYBOX_SIZE,
    SKYBOX_SIZE, SKYBOX_SIZE,  SKYBOX_SIZE,
    -SKYBOX_SIZE, SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, SKYBOX_SIZE,  SKYBOX_SIZE,
    //3
    -SKYBOX_SIZE,  SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE,  SKYBOX_SIZE,  SKYBOX_SIZE,
    -SKYBOX_SIZE,  SKYBOX_SIZE,  SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE,  SKYBOX_SIZE,
    //4
    -SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE,  SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE,  SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE,  SKYBOX_SIZE,
    //5
    SKYBOX_SIZE,  SKYBOX_SIZE, SKYBOX_SIZE,
    -SKYBOX_SIZE,  SKYBOX_SIZE, SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE, SKYBOX_SIZE,
    SKYBOX_SIZE, -SKYBOX_SIZE, SKYBOX_SIZE,
    -SKYBOX_SIZE,  SKYBOX_SIZE, SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE, SKYBOX_SIZE,
    //6
    SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE,  SKYBOX_SIZE, -SKYBOX_SIZE,
    SKYBOX_SIZE,  SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE, -SKYBOX_SIZE, -SKYBOX_SIZE,
    -SKYBOX_SIZE,  SKYBOX_SIZE, -SKYBOX_SIZE


};

//the texture coordinates - work will skybox texture of this shape +--
GLfloat textureCoordsSkyBox[72] = {
    //face 1
    0.75,0.33,      //    0,1,
    0.75,0.67,     //    1,1,
    0.5,0.33,     //    0,0,
    0.5,0.33,     //    0,0,
    0.75,0.67,    //    1,0,
    0.5,0.67,   //    1,1,

                //face 2
                0.5,1.0, //    1,1,
                0.25,1, //    0,1,
                0.5,0.67, //    1,0,
                0.5,0.67, //    1,0,
                0.25,1.0, //    0,1,
                0.25,0.67, //    1,1,
                           //face 3
                           0,0.67,//    1,1,
                           0,0.33,//    0,1,
                           0.25,0.67,//    1,0,
                           0.25,0.67,//    1,0,
                           0,0.33,//    0,1,
                           0.25,0.33,//    0,0,
                                     //face 4
                                     0.25,0.0,//    0,1,
                                     0.5,0.0,//    1,1,
                                     0.25,0.33,//    0,0,
                                     0.25,0.33,//    0,0,
                                     0.5,0.0,//    1,1,
                                     0.5,0.33,//    0,0,
                                              //face 5
                                              0.5,0.67,//    1,0,
                                              0.25,0.67,//    0,0,
                                              0.5,0.33,//    1,1,
                                              0.5,0.33,//    1,1,
                                              0.25,0.67,//    0,0,
                                              0.25,0.33,//    0,1,
                                                        //face 6
                                                        0.75,0.33,//    1,1,
                                                        1.0,0.33,//    0,1,
                                                        0.75,0.67,//    1,0,
                                                        0.75,0.67,//    1,0,
                                                        1.0,0.33,//    0,1,
                                                        1.0,0.67//    0,0


};

//the lighting normals - all facing out from each face
GLfloat gCubeVertexdataNormals[108] ={
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f,

    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,

    -1.0f, 0.0f, 0.0f,
    -1.0f, 0.0f, 0.0f,
    -1.0f, 0.0f, 0.0f,
    -1.0f, 0.0f, 0.0f,
    -1.0f, 0.0f, 0.0f,
    -1.0f, 0.0f, 0.0f,

    0.0f, -1.0f, 0.0f,
    0.0f, -1.0f, 0.0f,
    0.0f, -1.0f, 0.0f,
    0.0f, -1.0f, 0.0f,
    0.0f, -1.0f, 0.0f,
    0.0f, -1.0f, 0.0f,

    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,

    0.0f, 0.0f, -1.0f,
    0.0f, 0.0f, -1.0f,
    0.0f, 0.0f, -1.0f,
    0.0f, 0.0f, -1.0f,
    0.0f, 0.0f, -1.0f,
    0.0f, 0.0f, -1.0f

};

// Called to draw scene
void drawSkyBox(int image)
{
        //  glFrontFace(GL_CCW);

    glEnable(GL_TEXTURE_2D);
    //    glFrontFace(GL_CW); //texture the inside
    glColor3f(0.8, 0.8, 0.8);
    glBindTexture(GL_TEXTURE_2D, textures[image]);//bind your texture here

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, 0, gCubeVertexdataNormals);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, cubeVertexData);
    //   glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordsSkyBox);
    // draw a cube - type - start number - number of vertices to draw (so 3 for single triangle)
    glDrawArrays(GL_TRIANGLES, 0, 36);
    // deactivate vertex arrays after drawing
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
/*
void drawTenPoints(GLfloat x, GLfloat y, GLfloat z)
{

    glColor3f(1.0, 0.0, 0.0);
    const unsigned char text[100] = "10";
    glRasterPos3f((x - 15), (y - 10), z);
    

    glutBitmapString(GLUT_BITMAP_HELVETICA_18, text);
    glEnable(GL_LINE_LOOP);
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
        for (int i = 0; i <= 300; i++) {
        double angle = 2 * PI * i / 300;        
        glVertex3f(x + (45 * cos(i * angle / 20)),
            y + (45 * sin(i * angle / 20)), z);
    }

    glEnd();
    glFlush();
}

void drawTwentyPoints(GLfloat x, GLfloat y, GLfloat z)
{

    glColor3f(0, 1.0, 1.0);
    const unsigned char text[100] = "20";
    glRasterPos3f((x - 15), (y - 10), z);


    glutBitmapString(GLUT_BITMAP_HELVETICA_18, text);
    glEnable(GL_LINE_LOOP);
    glColor3f(0, 1.0, 1.0);
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i <= 300; i++) {
        double angle = 2 * PI * i / 300;
        glVertex3f(x + (35 * cos(i * angle / 20)),
            y + (35 * sin(i * angle / 20)), z);
    }

    glEnd();
    glFlush();
}

void drawThirtyPoints(GLfloat x, GLfloat y, GLfloat z)
{

    glColor3f(0, 0, 1.0);
    const unsigned char text[100] = "30";
    glRasterPos3f((x - 15), (y - 10), z);


    glutBitmapString(GLUT_BITMAP_HELVETICA_18, text);
    glEnable(GL_LINE_LOOP);
    glColor3f(0, 0.3, 1.0);
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i <= 300; i++) {
        double angle = 2 * PI * i / 300;
        glVertex3f(x + (25 * cos(i * angle / 20)),
            y + (25 * sin(i * angle / 20)), z);
    }

    glEnd();
    glFlush();
}

*/

void drawTenPoints(int image)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //the code for applying the texture

    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable(GL_TEXTURE_2D);
    //bind the texture 
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0, 0.0);//repeated texture
    glVertex3f(-45.0, -45.0, 0.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(45.0, -45.0, 0.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(45.0, 45.0, 0.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-45.0, 45.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

}

void drawTwentyPoints(int image)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //the code for applying the texture

    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable(GL_TEXTURE_2D);
    //bind the texture 
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0, 0.0);//repeated texture
    glVertex3f(-35.0, -35.0, 0.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(35.0, -35.0, 0.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(35.0, 35.0, 0.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-35.0, 35.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

}

void drawThirtyPoints(int image)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //the code for applying the texture

    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable(GL_TEXTURE_2D);
    //bind the texture 
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0, 0.0);//repeated texture
    glVertex3f(-25.0, -25.0, 0.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(25.0, -25.0, 0.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(25.0, 25.0, 0.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-25.0, 25.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

}

void drawPlants(int image)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //the code for applying the texture

    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    // glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable(GL_TEXTURE_2D);
    //bind the texture 
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 1.0f, 0.0f);
    glTexCoord2f(0.0, 0.0);//repeated texture
    glVertex3f(-25.0, -25.0, 0.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(25.0, -25.0, 0.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(25.0, 25.0, 0.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-25.0, 25.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

}

 

void setOrthographicProjection() {
    // switch to projection mode
    glMatrixMode(GL_PROJECTION);
    // save the previous matrix which contains the
    //set up for the perspective projection
    glPushMatrix();
    // reset matrix
    glLoadIdentity();
    // set a 2D orthographic projection
    gluOrtho2D(0, 1280, 0, 720);
    // invert the y axis, down is positive
    glScalef(1, -1, 1);
    // move the origin from the bottom left corner
    // to the upper left corner
    glTranslatef(0, -720, 0);
    //set for drawing again
    glMatrixMode(GL_MODELVIEW);
}
//reset your project with this - it simply pops back the previous projection
void resetPerspectiveProjection() {
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

void RenderScene(void)
{
    static float fBallRot = 0.0f;        
    glLoadIdentity();

    gluLookAt(cameraX, cameraY, cameraZ,//eye
        0.0, 0.0, 0.0,//centre
        0.0, 1.0, 0.0);//up

    // Clear the window with current clearing colour
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);

    glPushMatrix();
    glScalef(1, 1, 1);
    glRotatef(skyRotatex, 0.0f, 1.0f, 0.0f);    //SKYBOX
    if (skyRotatex > 360.0) {
        skyRotatex = 0;
    }
    skyRotatex -= 1.0f;
    drawSkyBox(SKYBOX_MAP);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.0, 0.0, -400.0);        //floor
    glRotatef(-90.0, 1.0, 0.0, 0.0);
    if (repeatOn) {
        drawTexturedSurface(IMAGE3);
    }
    else {
        drawTexturedSurfaceNoTiling(IMAGE3);
    }
    glPopMatrix();


    glPushMatrix();
    glTranslatef(0.0, 0.0, -170);            // back wall
    glScalef(1, 0.3, 1);
    if (repeatOn && repeatWallOn) {
        drawTexturedSurface(IMAGE4);
    }
    else {
        drawTexturedSurfaceNoTiling(IMAGE4);
    }
    glPopMatrix();
    

    glPushMatrix();
    glScalef(1, 0.3, 1);
    glTranslatef(-350, 0, 0);            // left wall
    glRotatef(90, 0.0, 1.0, 0.0);

    if (repeatOn && repeatWallOn) {
        drawTexturedSurface(IMAGE4);
    }
    else {
        drawTexturedSurfaceNoTiling(IMAGE4);
    }
    glPopMatrix();

    glPushMatrix();
    glScalef(1, 0.3, 1);
    glTranslatef(350, 0, 0);            // right wall
    glRotatef(-90, 0.0, 1.0, 0.0);

    if (repeatOn && repeatWallOn) {
        drawTexturedSurface(IMAGE4);
    }
    else {
        drawTexturedSurfaceNoTiling(IMAGE4);
    }
    glPopMatrix();        
                                                     //plants
    
    glPushMatrix();
    glTranslatef(300, 25, 100);
    drawPlants(IMAGE8);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(300, 25, 0);
    drawPlants(IMAGE7);
    glPopMatrix();    
    

    glPushMatrix();
    glTranslatef(-300, 25, 100);
    drawPlants(IMAGE8);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-300, 25, 0);
    drawPlants(IMAGE7);
    glPopMatrix();

    

    
    
    //Points
    glPushMatrix();
    glTranslatef(-100, 100, -169);            // 10 points
    drawTenPoints(IMAGE1);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(200, 150, -169);            // 10 points
    drawTenPoints(IMAGE1);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-300, 180, -169);            // 10 points
    drawTenPoints(IMAGE1);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(100, 200, -169);            // 20 points
    drawTwentyPoints(IMAGE5);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-300, 35, -169);            // 20 points
    drawTwentyPoints(IMAGE5);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(300, 65, -169);            // 20 points
    drawTwentyPoints(IMAGE5);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(200, 30, -169);            // 30 points
    drawThirtyPoints(IMAGE2);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-200, 80, -169);            // 30 points
    drawThirtyPoints(IMAGE2);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0, 200, -169);            // 30 points
    drawThirtyPoints(IMAGE2);
    glPopMatrix();

    glPushMatrix();                                        //football        
    if (ballshotPress == true) {
        glMatrixMode(GL_MODELVIEW);
        
        fBallRot -= 5.0f;

        if (fBallRot > -400.0) {

            glTranslatef(0.0, 0.0, fBallRot);
            fBallRot -= 15.0f;
            }
        ballshotPress == false;
    }
    drawFootBall(0, 25.0, 250, 20.0);            
    glPopMatrix();

    
    glLoadIdentity(); 
    setOrthographicProjection();        //2D HUD view

    glPushMatrix();
    const unsigned char text[100] =  "SCORE:";
    glRasterPos3f(1000, 25, 0);
    glutBitmapString(GLUT_BITMAP_HELVETICA_18, text);
    glPopMatrix();

    glPushMatrix();
    glColor3f(1.0, 1.0, 1.0);
    glBegin(GL_LINES);
    glVertex2d(30.0, 40.0);
    glVertex2d(120.0, 40.0);
    glEnd();
    // draw/update all your 2D stuff positioned in pixels NOT world coordinates
    glPopMatrix();    
    resetPerspectiveProjection();

}

 

// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
    //textures

    GLuint texture;
    // allocate a texture name
    glGenTextures(1, &texture);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    //make sure any TGA has no alpha channel - photoshop is a good converter to targa (TGA)
    //the gltLoadTGA method is found in gltools.cpp and is from the OpenGL SuperBible book
    //there are quite a few ways of loading images
    // Load textures in a for loop
    glGenTextures(TEXTURE_COUNT, textures);
    //this puts the texture into OpenGL texture memory
    //    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    for (int iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
    {
        // Bind to next texture object
        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);

        // Load texture data, set filter and wrap modes
        //note that gltLoadTGA is in the glm.cpp file and not a built-in openGL function
        pBytes0 = gltLoadTGA(textureFiles[iLoop], &iWidth, &iHeight,
            &iComponents, &eFormat);

        glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes0);

        //set up texture parameters

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        //below are good if we were tiling a repeated pattern

        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_WRAP_S, GL_CLAMP_TO_EDGE);
        //   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        //try these too
          glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
          glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

        //modulate the texture and vertex colours
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        //    glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
        free(pBytes0);
    }

    //enable textures
    glEnable(GL_TEXTURE_2D);


    glEnable(GL_DEPTH_TEST);    // Hidden surface removal    
    glFrontFace(GL_CCW);// Counter clock-wise polygons face out
    glEnable(GL_CULL_FACE);        // Do not calculate inside

                                //    glCullFace(GL_FRONT_AND_BACK);

                                // Enable lighting
    glEnable(GL_LIGHTING);
    glEnable(GL_POINT_SMOOTH);
    // Setup and enable light 0
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, whiteLightBright);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLightBright);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
    glLightfv(GL_LIGHT0, GL_SPECULAR, mKs);
    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 60.0f);
    glEnable(GL_LIGHT0);

    glLightfv(GL_LIGHT1, GL_DIFFUSE, whiteLightBright);
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos2);
    glLightfv(GL_LIGHT1, GL_SPECULAR, mKs);
    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 60.0f);
    glEnable(GL_LIGHT1);

    glLightfv(GL_LIGHT2, GL_DIFFUSE, whiteLightBright);
    glLightfv(GL_LIGHT2, GL_POSITION, lightPos3);
    glLightfv(GL_LIGHT2, GL_SPECULAR, mKs);
    glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 60.0f);
    glEnable(GL_LIGHT2);

    // Enable colour tracking
    glEnable(GL_COLOR_MATERIAL);

    // Set Material properties to follow glColor values
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    // All materials hereafter have full specular reflectivity
    // with a high shine
    glMaterialfv(GL_FRONT, GL_SPECULAR, mKs);
    glMateriali(GL_FRONT, GL_SHININESS, 128);

    // Black blue background clear colour
    glClearColor(0.0f, 0.0f, 0.03f, 1.0f);
}


void TimerFunc(int value)
{
    //move camera
    if (moveCamera) {
        cameraZ = cameraZ - 2;
        if (cameraZ > 350.0) {
            cameraY = cameraY + 0.3;
        }
    }

    glutSwapBuffers();
    glutPostRedisplay();
    glutTimerFunc(25, TimerFunc, 1);
}

void ChangeSize(int w, int h)
{
    GLfloat fAspect;

    // Prevent a divide by zero
    if (h == 0)
        h = 1;

    // Set Viewport to window dimensions
    glViewport(0, 0, w, h);

    // Calculate aspect ratio of the window
    fAspect = (GLfloat)w / (GLfloat)h;

    // Set the perspective coordinate system
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // field of view of 45 degrees, near and far planes 1.0 and 1000
    //that znear and zfar should typically have a ratio of 1000:1 to make sorting out z depth easier for the GPU
    gluPerspective(55.0f, fAspect, 1.0, 1000.0);
    // Modelview matrix reset
    glMatrixMode(GL_MODELVIEW);
    //pull the eye position back to view the scene

}

void ProcessMenu(int choice) {

    switch (choice)
    {
    case 1:
        repeatOn = !repeatOn;
        break;
    case 2:
        repeatWallOn = !repeatWallOn;
        break;
    case 3:
        moveCamera = !moveCamera;
        if (!moveCamera) {
            cameraX = 0.0;
            cameraY = 100.0;
            cameraZ = 500.0;
        }
        break;

    default:
        break;
    }

    glutPostRedisplay();
}

void keyPress(unsigned char key, int x, int y) {
    key = toupper(key);

    if (key == 32) //space for shooting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
    {
        ballshotPress = true;        
    }

    if (key == 70) //F for follow the ball                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
    {
        followBallPress = true;
    }

}

void keyArrowPress(int key, int x, int y) {
    switch (key)
    {
    case GLUT_KEY_UP: {
    }
    case GLUT_KEY_DOWN: {
    }
    case GLUT_KEY_LEFT: {
    }
    case GLUT_KEY_RIGHT: {
    }
    }
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(1280, 720);// a 16:9 ratio
    glutCreateWindow("Coursework 2 w1498469 Jaime M. Da Cunha");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    glutTimerFunc(25, TimerFunc, 1);
    glutKeyboardFunc(keyPress);
    glutSpecialFunc(keyArrowPress);
    int nMenu;
    // Create the Menu (right click on window)
    nMenu = glutCreateMenu(ProcessMenu);
    
    glutAddMenuEntry("Toggle camera movement", 3);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    SetupRC();
    glutMainLoop();
    return 0;
}

bottom of page