diff --git a/217CR Resit Assignment - Basic Project.vcxproj b/217CR Resit Assignment - Basic Project.vcxproj index 0f1669a..234f8bd 100644 --- a/217CR Resit Assignment - Basic Project.vcxproj +++ b/217CR Resit Assignment - Basic Project.vcxproj @@ -99,10 +99,12 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + Library Files\include Console true + Library Files @@ -138,7 +140,18 @@ + + + + + + + + + + + diff --git a/217CR Resit Assignment - Basic Project.vcxproj.filters b/217CR Resit Assignment - Basic Project.vcxproj.filters index 82c46ea..d455c8e 100644 --- a/217CR Resit Assignment - Basic Project.vcxproj.filters +++ b/217CR Resit Assignment - Basic Project.vcxproj.filters @@ -18,5 +18,30 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + \ No newline at end of file diff --git a/Cube.cpp b/Cube.cpp new file mode 100644 index 0000000..962eee7 --- /dev/null +++ b/Cube.cpp @@ -0,0 +1,47 @@ +#include "Cube.h" + +//We can either hard code the values in GameObject (like in Cube()) +//or +//We can use the GameEngine constructors to fill the values ( like in Cube(x, y, z, size)) +Cube::Cube() +{ + x = 0.0f; + y = 0.0f; + z = 0.0f; + + r = 1.0f; + g = 0.0f; + b = 1.0f; + + size = 1.0f; +} + +Cube::Cube(float _x, float _y, float _z, float _size) + :GameObject(_x, _y, _z) //note the use of GameObject constructor +{ + size = _size; +} + +Cube::Cube(float _x, float _y, float _z, + float _r, float _g, float _b, + float _size): + GameObject(_x, _y, _z, _r, _g, _b) //note the use of GameObject constructor +{ + size = _size; +} + +//Position and colour a cube in the scene +void Cube::Draw() +{ + glPushMatrix(); + glTranslatef(x, y, z); + glColor3f(r, g, b); + glutSolidCube(size); + //glutWireCube(size) - if you'd rather see through it + glPopMatrix(); +} + +void Cube::Update(float deltaTime) +{ + //Cubes are static at the moment so nothing changes for them +} diff --git a/Cube.h b/Cube.h new file mode 100644 index 0000000..f071b25 --- /dev/null +++ b/Cube.h @@ -0,0 +1,24 @@ +#pragma once + +#include "GameObject.h" + +//A basic cube class derived from a game object +class Cube: public GameObject +{ +public: + // -- variables -- + float size; + + // -- constructors/destructors -- + Cube(); //default constructor - aka no values passed in (position at 0,0,0 - colour magenta - size 1) + Cube(float _x, float _y, float _z, float _size); //pass in a position and size + Cube(float _x, float _y, float _z, + float _r, float _g, float _b, + float _size); //pass in a position, colour and size + ~Cube() {}; //default destructor + + // -- functions -- + //Need to give definions to GameObject's pure virtual functions + virtual void Draw(); + virtual void Update(float deltaTime); +}; \ No newline at end of file diff --git a/GameObject.cpp b/GameObject.cpp new file mode 100644 index 0000000..f011446 --- /dev/null +++ b/GameObject.cpp @@ -0,0 +1,41 @@ +#include "GameObject.h" + +std::map GameObject::keys; +std::map GameObject::specialKeys; + +GameObject::GameObject() +{ + x = 0.0f; + y = 0.0f; + z = 0.0f; + + r = 1.0f; + g = 0.0f; + b = 1.0f; +} + +GameObject::GameObject(float _x, float _y, float _z) +{ + x = _x; + y = _y; + z = _z; + + r = 1.0f; + g = 1.0f; + b = 1.0f; +} + +GameObject::GameObject(float _x, float _y, float _z, float _r, float _g, float _b) +{ + x = _x; + y = _y; + z = _z; + + r = _r; + g = _g; + b = _b; +} + +GameObject::~GameObject() +{ +} diff --git a/GameObject.h b/GameObject.h new file mode 100644 index 0000000..2ee6450 --- /dev/null +++ b/GameObject.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include + +//A basic abstract class that all game objects in the scene are based off +// abstract = We never will make a direct instance of GameObject but will make classes inherit from it +class GameObject +{ +public: + // -- variables -- + float x, y, z; //position + float r, g, b; //colour + + static std::map keys; //save key presses and let game objects access them + static std::map specialKeys; //static = one instance of these variables for the whole class (top of .cpp) + + // -- constructors/destructors -- + GameObject(); //default constructor - aka no values passed in (position at 0,0,0 - colour magenta) + GameObject(float _x, float _y, float _z); //pass in a position (no colour passed in so defaults to white) + GameObject(float _x, float _y, float _z, + float _r, float _g, float _b); //pass in a position, colour + ~GameObject(); //default destructor + + // -- functions -- + //pure virtual so all classes that derive from this one need to include a definion for these + virtual void Draw() = 0; + virtual void Update(float deltaTime) = 0; +}; \ No newline at end of file diff --git a/Helpful Drawing Code.txt b/Helpful Drawing Code.txt new file mode 100644 index 0000000..405e196 --- /dev/null +++ b/Helpful Drawing Code.txt @@ -0,0 +1,64 @@ +This legacy OpenGL code might be useful for drawing/displaying the +physics parts of the assignment. + +Remember, this code will have to go into an object's Draw() function +or +In the drawScene() function (between gluLookAt() and glutSwapBuffers()) in main.cpp to show. + + -- Line Drawing -- + +You can draw a line between two points via the below code. +This could be useful for visually showing forces, acceleration, velocity, boundaries etc. + +The indention isn't needed - it just makes it easier to read. + +This example draws a red line between (0, 0, 0) and (1, 1, 1). + +glPushMatrix(); + glBegin(GL_LINES); //note its GL_LINES and not GL_LINE! + glColor3f(1, 0, 0); //give the line a colour + glVertex3f(0, 0, 0); //line start + glVertex3f(1, 1, 1); //line end + glEnd(); +glPopMatrix(); + +This example uses an object's position to draw the positive axis from its center. +Each 2 points passed in via glVertex3f creates 1 line (so this example has 3 lines in one glBegin()). + +glPushMatrix(); + glBegin(GL_LINES); + + glColor3f(1, 0, 0); + glVertex3f(x, y, z); //uses the game objects position values + glVertex3f(x + 3, y, z); //positive x axis + + glColor3f(0, 1, 0); //note the colour change per line + glVertex3f(x, y, z); + glVertex3f(x, y + 3, z); //positive y axis + + glColor3f(1, 0, 1); + glVertex3f(x, y, z); + glVertex3f(x, y, z + 3); //positive z axis + glEnd(); +glPopMatrix(); + +-- Debug Object Drawing -- + +If you want to place a wireframe object around an object (perhaps to show a collider). +Choose whatever radius/size value you need to make the debug object bigger or smaller. +This would be done seperate to the push and pop you have for the normal objects drawing. + +//normal objects push/pop drawing code here first + +glPushMatrix(); + glTranslatef(x, y, z); //go the the game objects position + glColor3f(1, 0, 1); //make it magneta for easy debug testing + glutWireSphere(radius, 10, 10); //where radius is a float + //or + //glutWireCube(size); //where size is a float +glPopMatrix(); + +-- Colour changes -- + +You may want to change the colour of an object when something happens (like a collision). +This can be done by changing the public colour variables of the object directly. \ No newline at end of file diff --git a/Sphere.cpp b/Sphere.cpp new file mode 100644 index 0000000..5efc614 --- /dev/null +++ b/Sphere.cpp @@ -0,0 +1,55 @@ +#include "Sphere.h" + +//We can either hard code the values in GameObject (like in Sphere()) +//or +//We can use the GameEngine constructors to fill the values ( like in Sphere(x, y, z, radius, speed)) +Sphere::Sphere() +{ + x = 0.0f; + y = 0.0f; + z = 0.0f; + + r = 1.0f; + g = 0.0f; + b = 1.0f; + + radius = 1.0f; + moveSpeed = 5.0f; +} + +Sphere::Sphere(float _x, float _y, float _z, float _radius, float _moveSpeed) + :GameObject(_x, _y, _z) //note the use of GameObject constructor +{ + radius = _radius; + moveSpeed = _moveSpeed; +} + +Sphere::Sphere(float _x, float _y, float _z, + float _r, float _g, float _b, + float _radius, float _moveSpeed): + GameObject(_x, _y, _z, _r, _g, _b) //note the use of GameObject constructor +{ + radius = _radius; + moveSpeed = _moveSpeed; +} + +void Sphere::Draw() +{ + glPushMatrix(); + glTranslatef(x, y, z); + glColor3f(r, g, b); + //glutSolidSphere(radius, 10, 10); //if you'd rather it shows solid + glutWireSphere(radius, 10, 10); + glPopMatrix(); +} + +void Sphere::Update(float deltaTime) +{ + //This uses only special keys at the moment - aka the arrow keys + //You can use normal keys via + //GameObject::keys['a'] for the a key for example + if (GameObject::specialKeys[GLUT_KEY_UP] == true) + y += moveSpeed * deltaTime; + if (GameObject::specialKeys[GLUT_KEY_DOWN] == true) + y -= moveSpeed * deltaTime; +} diff --git a/Sphere.h b/Sphere.h new file mode 100644 index 0000000..dd477cd --- /dev/null +++ b/Sphere.h @@ -0,0 +1,26 @@ +#pragma once + +#include "GameObject.h" + +//A basic sphere class derived from a game object +//It can move (basic position changing only at the moment!) via the arrow keys +class Sphere : public GameObject +{ +public: + // -- variables -- + float radius; + float moveSpeed; + + // -- constructors/destructors -- + Sphere(); //default constructor - aka no values passed in (position at 0,0,0 - colour magenta - radius 1 - move speed - 1) + Sphere(float _x, float _y, float _z, float _radius, float _moveSpeed); //pass in a position, radius and movespeed + Sphere(float _x, float _y, float _z, + float _r, float _g, float _b, + float _radius, float _moveSpeed); //pass in a position, colour, radius and move speed + ~Sphere() {}; //default destructor + + // -- functions -- + //Need to give definions to GameObject's pure virtual functions + virtual void Draw(); + virtual void Update(float deltaTime); +}; \ No newline at end of file diff --git a/freeglut.dll b/freeglut.dll new file mode 100644 index 0000000..2fe3a23 Binary files /dev/null and b/freeglut.dll differ diff --git a/glew32.dll b/glew32.dll new file mode 100644 index 0000000..04f9381 Binary files /dev/null and b/glew32.dll differ diff --git a/main.cpp b/main.cpp index 53fa5c4..a1191cd 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,168 @@ +#include +#include +#pragma comment(lib, "glew32.lib") + #include +#include + +#include "Cube.h" +#include "Sphere.h" using namespace std; -int main() +// -- global variables -- +vector objects; +int oldTimeSinceStart; +int newTimeSinceStart; + +// Initialization +void setup(void) +{ + glClearColor(0.0, 0.0, 0.0, 0.0); + + //Create objects and place them in the objects vector + //If they aren't in the objects vector, they will not be drawn / updated! + + //constructor - position and size only + GameObject* cube1 = new Cube(5, 0, 0, 2); + //default constructor used + GameObject* cube2 = new Cube; + //constructor - position, colour, size + GameObject* cube3 = new Cube(2, 2, -2, 0, 1, 0, 0.5f); + + //constructor - position, colour, radius, moveSpeed + GameObject* sphere1 = new Sphere(-1, 0, -1, 0, 0, 1, 1.5f, 10.0f); + + objects.push_back(cube1); + objects.push_back(cube2); + objects.push_back(cube3); + objects.push_back(sphere1); +} + +//Drawing +void drawScene() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + + // Position the objects for viewing + gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); + + //Draw all our game objects + for (int i = 0; i < objects.size(); ++i) + { + objects[i]->Draw(); + } + + glutSwapBuffers(); +} + +//Called when nothing else is happening (such as rendering) +void idle() +{ + //Work out the delta time - the time between the last frame and this frame + oldTimeSinceStart = newTimeSinceStart; + newTimeSinceStart = glutGet(GLUT_ELAPSED_TIME); + + float deltaTime = (newTimeSinceStart - oldTimeSinceStart) / 1000.0f; + //cout << "Delta Time (seconds): " << deltaTime << endl; - if you want to check the delta time + + //Update all our game objects + for (int i = 0; i < objects.size(); ++i) + { + objects[i]->Update(deltaTime); + } + glutPostRedisplay(); +} + +//Delete any memory gotten from the new keyword +//Is only called when the ESC key is used to leave the game +void CleanUp() { - cin.get(); - return 0; + for (int i = objects.size() - 1; i >= 0; --i) + { + delete objects[i]; + } + objects.clear(); +} + +// Keyboard input processing functions +void keyInputDown(unsigned char key, int x, int y) +{ + GameObject::keys[key] = true; + //If you want to see keys pressed printed to the console + //std::cout << "Key pressed: " << key << std::endl; + + switch (key) + { + case 27: // Esc key + CleanUp(); + exit(0); + break; + default: + break; + } +} + +void keyInputUp(unsigned char key, int x, int y) +{ + GameObject::keys[key] = false; + //If you want to see keys pressed printed to the console + //std::cout << "Key lifted: " << key << std::endl; +} + +void keySpecialDown(int key, int x, int y) +{ + GameObject::specialKeys[key] = true; + //If you want to see keys pressed printed to the console + //std::cout << "Special Key pressed: " << key << std::endl; +} + +void keySpecialUp(int key, int x, int y) +{ + GameObject::specialKeys[key] = false; + //If you want to see keys pressed printed to the console + //std::cout << "Special Key lifted: " << key << std::endl; +} + +//OpenGL window reshape +void resize(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(60.0, (float)w / (float)h, 1.0, 500.0); + glMatrixMode(GL_MODELVIEW); +} + +//Entry point into the program +int main(int argc, char** argv) +{ + //Setup for legacy OpenGL usage + glutInit(&argc, argv); + glutInitContextVersion(2, 0); + glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE); + + //Window settings + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitWindowSize(500, 500); + glutInitWindowPosition(100, 100); + glutCreateWindow("Basic Resit Project"); + + //Callbacks + glutDisplayFunc(drawScene); + glutReshapeFunc(resize); + glutKeyboardFunc(keyInputDown); + glutKeyboardUpFunc(keyInputUp); + glutSpecialFunc(keySpecialDown); + glutSpecialUpFunc(keySpecialUp); + glutIdleFunc(idle); + + glewExperimental = GL_TRUE; + glewInit(); + + setup(); + + glutMainLoop(); } \ No newline at end of file