From 5424e469ca9989765e0069e05139bc883db2e34a Mon Sep 17 00:00:00 2001 From: Jasper Date: Mon, 10 Nov 2014 17:35:51 +0100 Subject: [PATCH 1/7] Changing linking order of Bullet libs. --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0913e5e..2b34054 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,9 +118,12 @@ FILE(GLOB_RECURSE HEADER_FILES_BULLET ${CMAKE_SOURCE_DIR}/extern/bullet/src/*.h) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extern/bullet/src) SET(HEADER_FILES ${HEADER_FILES} ${HEADER_FILES_BULLET}) -SET (LIBRARIES ${LIBRARIES} ${CMAKE_SOURCE_DIR}/extern/bullet/build/src/BulletCollision/libBulletCollision.a) + SET (LIBRARIES ${LIBRARIES} ${CMAKE_SOURCE_DIR}/extern/bullet/build/src/BulletDynamics/libBulletDynamics.a) +SET (LIBRARIES ${LIBRARIES} ${CMAKE_SOURCE_DIR}/extern/bullet/build/src/BulletCollision/libBulletCollision.a) SET (LIBRARIES ${LIBRARIES} ${CMAKE_SOURCE_DIR}/extern/bullet/build/src/LinearMath/libLinearMath.a) +SET (LIBRARIES ${LIBRARIES} ${CMAKE_SOURCE_DIR}/extern/bullet/build/src/BulletSoftBody/libBulletSoftBody.a) + ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES} ${SHADER_FILES} ${README_FILES}) TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${LIBRARIES}) From 58cc753aec941ae206474e415779fa28c96fc6b3 Mon Sep 17 00:00:00 2001 From: Jasper Date: Fri, 14 Nov 2014 14:17:04 +0100 Subject: [PATCH 2/7] terrain added --- physics.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ physics.hh | 37 ++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 physics.cc diff --git a/physics.cc b/physics.cc new file mode 100644 index 0000000..7b22507 --- /dev/null +++ b/physics.cc @@ -0,0 +1,92 @@ +#include "physics.hh" + +#include + + +btDynamicsWorld* world; //contains physical attributes of the world. +btDispatcher* dispatcher; // +btCollisionConfiguration* colConfig; //defines the type of collision detection. +btBroadphaseInterface* broadphase; //defines how objects are culled from collision detection. +btConstraintSolver* solver; //solver for forces and impulses. + +std::vector bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process. + +void init() +{ + colConfig = new btDefaultCollisionConfiguration(); + dispatcher = new btCollisionDispatcher(colConfig); + broadphase = new btDbvtBroadphase(); + solver = new btSequentialImpulseConstraintSolver(); + world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,colConfig); + + world->setGravity(btVector3(0,-10,-0)); + + +} + +void takeUpdateStep(float timeDiff) +{ + world->stepSimulation(timeDiff); +} + +void addSphere(float rad, float x, float y, float z, float mass) +{ + btSphereShape* sphere = new btSphereShape(rad); + btVector3 inertia(0,0,0); + if(mass == 0.0) + { + } + else + { + sphere->calculateLocalInertia((btScalar)mass,inertia); + } + + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(x,y,z))); + + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia); + + btRigidBody* body = new btRigidBody(info); + + world->addRigidBody(body); + + bodies.push_back(body); +} + +void getPos(int i) +{ + btVector3 origin = bodies[i]->getCenterOfMassPosition(); +} + +void getRotation(int i) +{ + btQuaternion rotQuantrino = bodies[i]->getOrientation(); //TODO return orientation in gl format +} + +void rollForward() +{ + //bodies[k].applyTorque(btVector3); +} + +/* +void kill() +{ + //btDynamimcWorld* + for(int i = 0; i < bodies.size();i++) + { + world->removeCollisionObject(bodies[i]); //clarification: go through the list of bodies in wordl for each body b, then remove exactly this body b from world + btMotionState* motionState = bodies[i]->getMotionState(); + btCollisionShape* shape = bodies[i]->getCollisionShape(); + delete shape; + delete motionState; + delete bodies[i]; + } + + delete dispatcher; + delete colConfig; + delete solver; +} + delete broadphase; + delete world; +} +*/ + diff --git a/physics.hh b/physics.hh index 5df0e83..5c25912 100644 --- a/physics.hh +++ b/physics.hh @@ -1,8 +1,45 @@ #ifndef PHYSICS_HH_INCLUDED #define PHYSICS_HH_INCLUDED +#include +#include +#include + +#include "extern/bullet/src/BulletDynamics/Dynamics/btRigidBody.h" +#include "extern/bullet/src/BulletDynamics/Dynamics/btDynamicsWorld.h" +#include "extern/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "extern/bullet/src/BulletCollision/CollisionShapes/btSphereShape.h" + +#include "extern/bullet/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h" +#include "extern/bullet/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"//YAY! + +#include "extern/bullet/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h" +#include "extern/bullet/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" + +#include "extern/bullet/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "extern/bullet/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h" +#include "extern/bullet/src/BulletCollision/BroadphaseCollision/btDispatcher.h" + +#include "extern/bullet/src/LinearMath/btScalar.h" +#include "extern/bullet/src/LinearMath/btMotionState.h" +#include "extern/bullet/src/LinearMath/btDefaultMotionState.h" +#include "extern/bullet/src/LinearMath/btQuaternion.h" + class Physics { public: Physics(); + ~Physics(); + void rollForward(glm::vec3 camPos, float strength); + private: + btRigidBody* playerBody; + btRigidBody* terrainBody; + std::vector bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process. + + + btDynamicsWorld* world; //contains physical attributes of the world. + btDispatcher* dispatcher; // + btCollisionConfiguration* colConfig; //defines the type of collision detection. + btBroadphaseInterface* broadphase; //defines how objects are culled from collision detection. + btConstraintSolver* solver; //solver for forces and impulses. }; #endif From ba8be9e10db6c7911027838dd92ce9c8df1223a5 Mon Sep 17 00:00:00 2001 From: Jasper Date: Fri, 14 Nov 2014 14:23:10 +0100 Subject: [PATCH 3/7] aaah --- physics.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++-- physics.hh | 10 ++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/physics.cc b/physics.cc index 7b22507..cf030ff 100644 --- a/physics.cc +++ b/physics.cc @@ -10,6 +10,8 @@ btBroadphaseInterface* broadphase; //defines how objects are culled from collisi btConstraintSolver* solver; //solver for forces and impulses. std::vector bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process. +btRigidBody* playerBall; +btRigidBody* terrainBody; void init() { @@ -29,7 +31,46 @@ void takeUpdateStep(float timeDiff) world->stepSimulation(timeDiff); } -void addSphere(float rad, float x, float y, float z, float mass) +void addTerrain(int width, int length, float** heightData) +{ + float* heightfield = new float[width * length]; + int highest = -999999, j = 0, i = 0; + for (i = 0; i < width; i++) + for (j = 0; j < length; j++) { + heightfield[j*length+i] = heightData[i][j]; + if (heightData[i][j] > highest) + highest = heightData[i][j]; + } + + btHeightfieldTerrainShape* terrianShape = new btHeightfieldTerrainShape(width,length,heightData,highest,1,true,false); + + btRigidBody* tBody = new btRigidBody(0,new btDefaultMotionState(),terrianShape); + + tBody->getWorldTransform().setOrigin(btVector3(0,highest/2,0)); + + //tBody->getWoorldTransform().setRotation(btQuaternion(0,0,0,1)); + + terrainBody = tBody; + + world->addRigidBody(terrainBody); + +/* + terrianShape->setLocalScaling(btVector3(1,1,1)); + btCollisionShape* trimeshShape = terrianShape; + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,highest/2,0));//not 100% sure maybe (0,0,0) or (0,-highest/2,0) + + btRigidBody* groundBody = localCreateRigidBody(mass, startTransform,trimeshShape); + + world->addRigidBody(terrainBody); + */ + +} + +void addSphere(float rad, float x, float y, float z, float mass, int indice) //TODO add indice check { btSphereShape* sphere = new btSphereShape(rad); btVector3 inertia(0,0,0); @@ -52,9 +93,11 @@ void addSphere(float rad, float x, float y, float z, float mass) bodies.push_back(body); } -void getPos(int i) +glm::vec3 getPos(int i) { btVector3 origin = bodies[i]->getCenterOfMassPosition(); + glm::vec3 save(origin.getX(),origin.getY(),origin.getZ()); + return save; } void getRotation(int i) diff --git a/physics.hh b/physics.hh index 5c25912..a52e646 100644 --- a/physics.hh +++ b/physics.hh @@ -8,7 +8,9 @@ #include "extern/bullet/src/BulletDynamics/Dynamics/btRigidBody.h" #include "extern/bullet/src/BulletDynamics/Dynamics/btDynamicsWorld.h" #include "extern/bullet/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" + #include "extern/bullet/src/BulletCollision/CollisionShapes/btSphereShape.h" +#include "extern/bullet/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" #include "extern/bullet/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h" #include "extern/bullet/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"//YAY! @@ -29,7 +31,15 @@ class Physics { public: Physics(); ~Physics(); + void init(); + void takeUpdateStep(float timeDiff); void rollForward(glm::vec3 camPos, float strength); + glm::vec3 getPos(int i); + void getRotation(int i); + void rollForward(); + void addTerrain(int width, int length, float** heightData); + void addSphere(float rad, float x, float y, float z, float mass, int indice); + private: btRigidBody* playerBody; btRigidBody* terrainBody; From d5198ff4f5334791d3cfac0e313d289f5aa3b0d1 Mon Sep 17 00:00:00 2001 From: Jasper Date: Fri, 14 Nov 2014 15:15:29 +0100 Subject: [PATCH 4/7] Added getRotation in physics to give rotation of object back as 4x4Matrix --- physics.cc | 10 ++++++++-- physics.hh | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/physics.cc b/physics.cc index cf030ff..f092a1d 100644 --- a/physics.cc +++ b/physics.cc @@ -100,9 +100,15 @@ glm::vec3 getPos(int i) return save; } -void getRotation(int i) +glm::mat4 getRotation(int i) { - btQuaternion rotQuantrino = bodies[i]->getOrientation(); //TODO return orientation in gl format + btQuaternion quat = bodies[i]->getOrientation(); + + glm::mat4 matrix = glm::rotate( + matrix, + quat.getAngle(), + glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ()) + ); } void rollForward() diff --git a/physics.hh b/physics.hh index a52e646..97a56ca 100644 --- a/physics.hh +++ b/physics.hh @@ -26,6 +26,8 @@ #include "extern/bullet/src/LinearMath/btMotionState.h" #include "extern/bullet/src/LinearMath/btDefaultMotionState.h" #include "extern/bullet/src/LinearMath/btQuaternion.h" +#include "extern/bullet/src/LinearMath/btVector3.h" +#include "extern/bullet/src/LinearMath/btMatrix3x3.h" class Physics { public: @@ -35,7 +37,7 @@ class Physics { void takeUpdateStep(float timeDiff); void rollForward(glm::vec3 camPos, float strength); glm::vec3 getPos(int i); - void getRotation(int i); + glm::mat4 getRotation(int i); void rollForward(); void addTerrain(int width, int length, float** heightData); void addSphere(float rad, float x, float y, float z, float mass, int indice); From 6c0c9733055b1818f8eeec891fdd60008897118f Mon Sep 17 00:00:00 2001 From: Jasper Date: Fri, 14 Nov 2014 15:48:50 +0100 Subject: [PATCH 5/7] added Roll forward methode, needs testing to be sure. --- physics.cc | 7 +++++-- physics.hh | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/physics.cc b/physics.cc index f092a1d..774d9a9 100644 --- a/physics.cc +++ b/physics.cc @@ -109,11 +109,14 @@ glm::mat4 getRotation(int i) quat.getAngle(), glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ()) ); + return matrix; } -void rollForward() +void rollForward(glm::mat3 rotCamera) { - //bodies[k].applyTorque(btVector3); + glm::vec3 saveVector= glm::vec3(1,0,0) * rotCamera; + saveVector = glm::cross(glm::vec3(0,1,0),saveVector); + playerBall->applyTorque(btVector3(saveVector[0],saveVector[1],saveVector[2])); } /* diff --git a/physics.hh b/physics.hh index 97a56ca..90136ad 100644 --- a/physics.hh +++ b/physics.hh @@ -38,7 +38,7 @@ class Physics { void rollForward(glm::vec3 camPos, float strength); glm::vec3 getPos(int i); glm::mat4 getRotation(int i); - void rollForward(); + void rollForward(glm::mat3 rotCamera); void addTerrain(int width, int length, float** heightData); void addSphere(float rad, float x, float y, float z, float mass, int indice); From 3eb406efd11f65284b8dd0ec6a86bf5a510820f2 Mon Sep 17 00:00:00 2001 From: Jasper Date: Fri, 14 Nov 2014 16:23:14 +0100 Subject: [PATCH 6/7] Added addPlayer analog to addSphere and added a check to make sure incice stay synchronized (possibly dangerous but needs to be tested) --- physics.cc | 39 ++++++++++++++++++++++++++++++++++++--- physics.hh | 3 ++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/physics.cc b/physics.cc index 774d9a9..58d7d0f 100644 --- a/physics.cc +++ b/physics.cc @@ -70,14 +70,42 @@ void addTerrain(int width, int length, float** heightData) } -void addSphere(float rad, float x, float y, float z, float mass, int indice) //TODO add indice check +void addPlayer(float rad, float x, float y, float z, float mass, unsigned indice) { + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); + btSphereShape* sphere = new btSphereShape(rad); btVector3 inertia(0,0,0); - if(mass == 0.0) + if(mass != 0.0) { + sphere->calculateLocalInertia((btScalar)mass,inertia); } - else + + btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(x,y,z))); + + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,sphere,inertia); + + playerBall = new btRigidBody(info); + + world->addRigidBody(playerBall); + + bodies.push_back(playerBall); + + if(bodies.size() == indice) + throw std::invalid_argument( "Bodies out of Sync" ); + +} + + +void addSphere(float rad, float x, float y, float z, float mass, unsigned indice) +{ + if(bodies.size() != indice) + throw std::invalid_argument( "Bodies out of Sync" ); + + btSphereShape* sphere = new btSphereShape(rad); + btVector3 inertia(0,0,0); + if(mass != 0.0) { sphere->calculateLocalInertia((btScalar)mass,inertia); } @@ -91,6 +119,11 @@ void addSphere(float rad, float x, float y, float z, float mass, int indice) //T world->addRigidBody(body); bodies.push_back(body); + + + if(bodies.size() == indice) + throw std::invalid_argument( "Bodies out of Sync" ); + } glm::vec3 getPos(int i) diff --git a/physics.hh b/physics.hh index 90136ad..afb3b5c 100644 --- a/physics.hh +++ b/physics.hh @@ -40,7 +40,8 @@ class Physics { glm::mat4 getRotation(int i); void rollForward(glm::mat3 rotCamera); void addTerrain(int width, int length, float** heightData); - void addSphere(float rad, float x, float y, float z, float mass, int indice); + void addPlayer(float rad, float x, float y, float z, float mass, unsigned indice); + void addSphere(float rad, float x, float y, float z, float mass, unsigned indice); private: btRigidBody* playerBody; From 7b331edff99d19596c9a87eff5a1fb3463c6f553 Mon Sep 17 00:00:00 2001 From: Fabian Klemp Date: Fri, 14 Nov 2014 16:47:47 +0100 Subject: [PATCH 7/7] Reorganized code quite a bit. Resizing is deactivated currently. --- graphics.cc | 167 ++++++++++++++++++++++++++++++++++------------------ graphics.hh | 43 ++++++++------ main.cc | 154 +++++++++++++++++------------------------------- main.hh | 35 +++++------ 4 files changed, 206 insertions(+), 193 deletions(-) diff --git a/graphics.cc b/graphics.cc index 4832d62..35513f5 100644 --- a/graphics.cc +++ b/graphics.cc @@ -1,100 +1,151 @@ #include "graphics.hh" +#include +#include +#include +#include + +#include +#include +#include + #include "model.hh" -#include using namespace std; -ACGL::OpenGL::SharedShaderProgram shader; -Level level; - -// gets called after the OpenGL window is prepared: -void initCustomResources() -{ - // define where shaders and textures can be found: - ACGL::Base::Settings::the()->setResourcePath("../"); - ACGL::Base::Settings::the()->setShaderPath("Shader/"); - ACGL::Base::Settings::the()->setTexturePath("Geometry/"); - ACGL::Base::Settings::the()->setGeometryPath("Geometry/"); - - // load Model to give shader correct Attribute locations - // TODO look up if this is really necessary, since this looks really stupid. - Model model = Model("Bunny.obj"); - - // look up all shader files starting with 'phong' and build a ShaderProgram from it: - shader = ACGL::OpenGL::ShaderProgramCreator("phong").attributeLocations( - model.getReference()->getAttributeLocations()).create(); - shader->use(); - - // load Level - level.load(shader); - - // just in case: check for errors - openGLCriticalError(); +Graphics::Graphics() { } -void deleteCustomResources() -{ - // we have memory management via reference counting, so nothing to do here +GLFWwindow* Graphics::getWindow() { + return window; } -void draw(float runTime) +void Graphics::setGLFWHintsForOpenGLVersion( unsigned int _version ) { - // update Level first TODO: move this with the rest of the stuff that doesn't belong here to main - level.update(runTime); +#ifdef __APPLE__ +#if (ACGL_OPENGL_VERSION >= 30) + // request OpenGL 3.2, will return a 4.1 context on Mavericks + glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); + glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 ); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); +#endif +#else +// non-apple + glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, _version / 10 ); + glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, _version % 10 ); + #ifdef ACGL_OPENGL_PROFILE_CORE + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + #endif +#endif +} +bool Graphics::createWindow() +{ + ///////////////////////////////////////////////////////////////////////////////////// + // Initialise GLFW + // + if ( !glfwInit() ) + { + ACGL::Utils::error() << "Failed to initialize GLFW" << endl; + exit( -1 ); + } + + ///////////////////////////////////////////////////////////////////////////////////// + // Configure OpenGL context + // + setGLFWHintsForOpenGLVersion( ACGL_OPENGL_VERSION ); + + // activate multisampling (second parameter is the number of samples): + //glfwWindowHint( GLFW_SAMPLES, 8 ); + + // request an OpenGL debug context: + glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, true ); + + // define whether the window can get resized: + glfwWindowHint(GLFW_RESIZABLE, false); + + // non-decorated windows can be used as splash screens: + //glfwWindowHint( GLFW_DECORATED, false ); + + ///////////////////////////////////////////////////////////////////////////////////// + // try to create an OpenGL context in a window and check the supported OpenGL version: + // R,G,B,A, Depth,Stencil + window = glfwCreateWindow(windowSize.x, windowSize.y, "SWP MarbleGame Group C", NULL, NULL); + if (!getWindow()) { + ACGL::Utils::error() << "Failed to open a GLFW window - requested OpenGL: " << ACGL_OPENGL_VERSION << endl; + return false; + } + glfwMakeContextCurrent(window); + ACGL::init(); + return true; +} + +Graphics::Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane) { + this->windowSize = windowSize; + this->nearPlane = nearPlane; + this->farPlane = farPlane; +} + + +void Graphics::render(Level* level, ACGL::OpenGL::SharedShaderProgram shader) +{ // clear the framebuffer: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //set view and projection matrix - shader->setUniform("projectionMatrix", buildFrustum(75.0, 0.1, 100.0, (float)g_windowSize.x/(float)g_windowSize.y) ); - // the + (0,1,0) compensates bunny doesn't have its center at it's center - shader->setUniform("viewMatrix", buildViewMatrix()); + shader->setUniform("projectionMatrix", buildFrustum(75.0f, 0.1f, 100.0f, (float)windowSize.x/(float)windowSize.y) ); + shader->setUniform("viewMatrix", buildViewMatrix(level)); //set lighting parameters - if (level.getLights().size() > 0) { - shader->setUniform("lightCount", (int) level.getLights().size()); + if (level->getLights().size() > 0) { + shader->setUniform("lightCount", (int) level->getLights().size()); // TODO look into doing this less often // Build light position array - glm::vec3 lightSources[level.getLights().size()]; - for(unsigned int i = 0; igetLights().size()]; + for(unsigned int i = 0; igetLights().size(); i++) { + lightSources[i] = level->getLights()[i].getPosition(); } glUniform3fv(shader->getUniformLocation("lightSources"), sizeof(lightSources), (GLfloat*) lightSources); // Build light colour array - glm::vec3 lightColours[level.getLights().size()]; - for(unsigned int i = 0; igetLights().size()]; + for(unsigned int i = 0; igetLights().size(); i++) { + lightColours[i] = level->getLights()[i].getColour(); } glUniform3fv(shader->getUniformLocation("lightColors"), sizeof(lightColours), (GLfloat*) lightColours); // Build light attenuation array - float lightIntensities[level.getLights().size()]; - for(unsigned int i = 0; igetLights().size()]; + for(unsigned int i = 0; igetLights().size(); i++) { + lightIntensities[i] = level->getLights()[i].getIntensity(); } glUniform1fv(shader->getUniformLocation("lightIntensities"), sizeof(lightIntensities), (GLfloat*) lightIntensities); } // set Material Parameters - shader->setUniform("ambientColor", level.getAmbientLight()); + shader->setUniform("ambientColor", level->getAmbientLight()); shader->setUniform("camera", glm::vec3(0.0f, 0.0f, 0.0f)); // render the level(currently only a bunny): - level.render(); + level->render(); } -void resizeCallback( GLFWwindow *, int newWidth, int newHeight ) +void Graphics::setWindowSize(glm::uvec2 windowSize) { + this->windowSize = windowSize; +} + +void resizeCallback(Graphics* graphics, int newWidth, int newHeight) { // store the new window size and adjust the viewport: - g_windowSize = glm::uvec2( newWidth, newHeight); - glViewport( 0, 0, g_windowSize.x, g_windowSize.y ); + graphics->setWindowSize(glm::uvec2( newWidth, newHeight)); + glViewport( 0, 0, newWidth, newHeight); } -glm::mat4 buildFrustum( float phiInDegree, float _near, float _far, float aspectRatio) { +glm::mat4 Graphics::buildFrustum( float phiInDegree, float _near, float _far, float aspectRatio) { float phiHalfInRadians = 0.5*phiInDegree * (M_PI/180.0); float top = _near * tan( phiHalfInRadians ); @@ -105,12 +156,12 @@ glm::mat4 buildFrustum( float phiInDegree, float _near, float _far, float aspect return glm::frustum(left, right, bottom, top, _near, _far); } -glm::mat4 buildViewMatrix() { - glm::vec4 cameraVector = glm::vec4(0.0f, 0.0f, level.getCamera().getDistance(), 0.0f); +glm::mat4 Graphics::buildViewMatrix(Level* level) { + glm::vec4 cameraVector = glm::vec4(0.0f, 0.0f, level->getCamera().getDistance(), 0.0f); // rotate vector - glm::mat4 rotationMatrix = glm::rotate(level.getCamera().getRotation()[0], glm::vec3(1.0f, 0.0f, 0.0f)) * - glm::rotate(level.getCamera().getRotation()[1], glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate(level.getCamera().getRotation()[2], glm::vec3(0.0f, 0.0f, 1.0f)); + glm::mat4 rotationMatrix = glm::rotate(level->getCamera().getRotation()[0], glm::vec3(1.0f, 0.0f, 0.0f)) * + glm::rotate(level->getCamera().getRotation()[1], glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate(level->getCamera().getRotation()[2], glm::vec3(0.0f, 0.0f, 1.0f)); cameraVector = rotationMatrix * cameraVector; //construct lookAt (cameraPosition = cameraCenter + cameraVector - return glm::lookAt(level.getCameraCenter()->getPosition() + glm::vec3(cameraVector), level.getCameraCenter()->getPosition(), glm::vec3(0.0f, 1.0f, 0.0f)); + return glm::lookAt(level->getCameraCenter()->getPosition() + glm::vec3(cameraVector), level->getCameraCenter()->getPosition(), glm::vec3(0.0f, 1.0f, 0.0f)); } diff --git a/graphics.hh b/graphics.hh index 09a3a8b..c161227 100644 --- a/graphics.hh +++ b/graphics.hh @@ -1,26 +1,33 @@ #ifndef GRAPHICS_HH_INCLUDED #define GRAPHICS_HH_INCLUDED +#include -#include "main.hh" - -#include +#include #include +#include "level.hh" -// gets called after the OpenGL window is prepared, init of example specific stuff: -void initCustomResources(); +class Graphics { + public: + Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane); + Graphics(); + void render(Level* level, ACGL::OpenGL::SharedShaderProgram shader); + // gets called at window resize: + void resizeCallback( GLFWwindow *, int newWidth, int newHeight ); + // to build the projection matrix: + glm::mat4 buildFrustum( float phiInDegree, float near, float far, float aspectRatio); + glm::mat4 buildViewMatrix(Level* level); + glm::uvec2 getWindowSize(); + bool createWindow(); + GLFWwindow* getWindow(); + void setWindowSize(glm::uvec2 windowSize); + private: + void setGLFWHintsForOpenGLVersion( unsigned int _version ); + glm::uvec2 windowSize; + float nearPlane; + float farPlane; + GLFWwindow* window; +}; -// gets called at application shutdown: -void deleteCustomResources(); - -// gets called ech frame, runTime is in seconds: -void draw(float runTime); - -// gets called at window resize: -void resizeCallback( GLFWwindow *, int newWidth, int newHeight ); - -// to build the projection matrix: -glm::mat4 buildFrustum( float phiInDegree, float near, float far, float aspectRatio); - -glm::mat4 buildViewMatrix(); +void resizeCallback(Graphics* graphics, int newWidth, int newHeight); #endif diff --git a/main.cc b/main.cc index 535705f..6efddf7 100644 --- a/main.cc +++ b/main.cc @@ -10,108 +10,63 @@ #include #include #include +#include +#include #include +#include + +#include "model.hh" using namespace std; using namespace ACGL::OpenGL; using namespace ACGL::Base; using namespace ACGL::Utils; -glm::uvec2 g_windowSize( 1024, 786 ); -float g_nearPlane = 0.1f; -float g_farPlane = 100.0f; -bool glfwWindowClosed = false; +Application::Application() { + graphics = Graphics(glm::uvec2(1024, 786), 0.1f, 100.0f); +} -GLFWwindow* g_window; +Graphics* Application::getGraphics() { + return &graphics; +} -void setGLFWHintsForOpenGLVersion( unsigned int _version ) +Level* Application::getLevel() { + return &level; +} + +ACGL::OpenGL::SharedShaderProgram Application::getShader() { + return shader; +} + +void Application::init() { -#ifdef __APPLE__ -#if (ACGL_OPENGL_VERSION >= 30) - // request OpenGL 3.2, will return a 4.1 context on Mavericks - glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); - glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 ); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif -#else -// non-apple - glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, _version / 10 ); - glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, _version % 10 ); - #ifdef ACGL_OPENGL_PROFILE_CORE - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - #endif -#endif + // define where shaders and textures can be found: + ACGL::Base::Settings::the()->setResourcePath("../"); + ACGL::Base::Settings::the()->setShaderPath("Shader/"); + ACGL::Base::Settings::the()->setTexturePath("Geometry/"); + ACGL::Base::Settings::the()->setGeometryPath("Geometry/"); + + // load Model to give shader correct Attribute locations + // TODO look up if this is really necessary, since this looks really stupid. + Model model = Model("Bunny.obj"); + + // look up all shader files starting with 'phong' and build a ShaderProgram from it: + shader = ACGL::OpenGL::ShaderProgramCreator("phong").attributeLocations( + model.getReference()->getAttributeLocations()).create(); + shader->use(); + + // load Level + level.load(shader); + + // just in case: check for errors + openGLCriticalError(); } /********************************************************************************************************************** * Returns true if a window with the desired context could get created. * Requested OpenGL version gets set by ACGL defines. */ -bool createWindow() -{ - ///////////////////////////////////////////////////////////////////////////////////// - // Initialise GLFW - // - if ( !glfwInit() ) - { - error() << "Failed to initialize GLFW" << endl; - exit( -1 ); - } - - ///////////////////////////////////////////////////////////////////////////////////// - // Configure OpenGL context - // - setGLFWHintsForOpenGLVersion( ACGL_OPENGL_VERSION ); - - // activate multisampling (second parameter is the number of samples): - //glfwWindowHint( GLFW_SAMPLES, 8 ); - - // request an OpenGL debug context: - glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, true ); - - // define whether the window can get resized: - //glfwWindowHint( GLFW_RESIZABLE, true ); - - // non-decorated windows can be used as splash screens: - //glfwWindowHint( GLFW_DECORATED, false ); - - // request an sRGB framebuffer: - //glfwWindowHint( GLFW_SRGB_CAPABLE, true ); - - //glfwWindowHint( , true ); - //glfwWindowHint( , true ); - //glfwWindowHint( , true ); - //glfwWindowHint( , true ); - - - ///////////////////////////////////////////////////////////////////////////////////// - // try to create an OpenGL context in a window and check the supported OpenGL version: - // R,G,B,A, Depth,Stencil - g_window = glfwCreateWindow( g_windowSize.x, g_windowSize.y, "ACGL GLFWExamples", NULL, NULL); - if (!g_window) { - error() << "Failed to open a GLFW window - requested OpenGL: " << ACGL_OPENGL_VERSION << endl; - return false; - } - glfwMakeContextCurrent(g_window); - ACGL::init(); - - ///////////////////////////////////////////////////////////////////////////////////// - // Init debug-extension - // - if (ACGL_ARB_debug_output()) { - //debug() << "GL_ARB_DEBUG_OUTPUT is supported, register callback" << endl; - //glDebugMessageCallbackARB( debugCallback, NULL); - - // filter out the strange performance warnings about shader recompiles: - //glDebugMessageControlARB( GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DEBUG_SEVERITY_MEDIUM_ARB, 0, NULL, GL_FALSE ); - } else { - //debug() << "GL_ARB_DEBUG_OUTPUT is missing!" << endl; - } - return true; -} static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int) { @@ -121,15 +76,14 @@ static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int) } -/********************************************************************************************************************** - * Generic main for different example apps - */ int main( int argc, char *argv[] ) { + Application app = Application(); + ///////////////////////////////////////////////////////////////////////////////////// // Create OpenGL capable window: // - if ( !createWindow() ) { + if ( !app.getGraphics()->createWindow() ) { glfwTerminate(); exit( -1 ); } @@ -138,11 +92,11 @@ int main( int argc, char *argv[] ) // Set window title to binary name (without the path): // std::vector tmp = StringHelpers::split( std::string( argv[0] ), '/' ); - glfwSetWindowTitle( g_window, tmp[tmp.size()-1].c_str() ); + glfwSetWindowTitle(app.getGraphics()->getWindow(), tmp[tmp.size()-1].c_str() ); // Ensure we can capture the escape key being pressed below - glfwSetInputMode( g_window, GLFW_STICKY_KEYS, 1 ); - glfwSetWindowSizeCallback( g_window, resizeCallback ); - glfwSetKeyCallback( g_window, keyCallback ); + glfwSetInputMode(app.getGraphics()->getWindow(), GLFW_STICKY_KEYS, 1 ); + //glfwSetWindowSizeCallback(app.getGraphics(), resizeCallback); + glfwSetKeyCallback(app.getGraphics()->getWindow(), keyCallback ); // Enable vertical sync (on cards that support it) with parameter 1 - 0 means off glfwSwapInterval( 0 ); @@ -152,7 +106,7 @@ int main( int argc, char *argv[] ) // glClearColor( 0.0, 0.0, 0.0, 1.0 ); glEnable( GL_DEPTH_TEST ); - initCustomResources(); + app.init(); int frameCount = 0; @@ -167,23 +121,23 @@ int main( int argc, char *argv[] ) stringstream sstream (stringstream::in | stringstream::out); sstream << setprecision(1) << std::fixed << tmp[tmp.size()-1] << " - FPS: " << frameCount / (now-showNextFPS + FPSdelay) << " " << 1000 * (now-showNextFPS + FPSdelay)/frameCount << " msec"; - glfwSetWindowTitle( g_window, sstream.str().c_str() ); + glfwSetWindowTitle(app.getGraphics()->getWindow(), sstream.str().c_str() ); showNextFPS = now + FPSdelay; frameCount = 0; } - draw( now - startTimeInSeconds ); + app.getLevel()->update(now - startTimeInSeconds); + app.getGraphics()->render(app.getLevel(), app.getShader()); + openGLCriticalError(); // MacOS X will not swap correctly is another FBO is bound: glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - glfwSwapBuffers( g_window ); + glfwSwapBuffers(app.getGraphics()->getWindow()); glfwPollEvents(); frameCount++; } // Check if the window was closed - while( !glfwWindowShouldClose( g_window ) ); - - deleteCustomResources(); + while( !glfwWindowShouldClose(app.getGraphics()->getWindow()) ); glfwTerminate(); exit(0); diff --git a/main.hh b/main.hh index dfc33d3..17e8fad 100644 --- a/main.hh +++ b/main.hh @@ -1,27 +1,28 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// headers needed: -// -#include +#ifndef MAIN_HH_INCLUDED +#define MAIN_HH_INCLUDED #include +#include #include #include -// -/////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// #include "physics.hh" #include "graphics.hh" #include "level.hh" -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// implement the following functions: -// +///////////////////////////////////////////////////////////////// +class Application { + public: + Application(); + Graphics* getGraphics(); + Level* getLevel(); + ACGL::OpenGL::SharedShaderProgram getShader(); + void init(); + private: + Graphics graphics; + Level level; + ACGL::OpenGL::SharedShaderProgram shader; +}; -// global variables exported by the generic main: -extern glm::uvec2 g_windowSize; -extern float g_nearPlane; -extern float g_farPlane; -// -/////////////////////////////////////////////////////////////////////////////////////////////////// +#endif