commit
834d3758d6
@ -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)
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extern/bullet/src)
|
||||||
SET(HEADER_FILES ${HEADER_FILES} ${HEADER_FILES_BULLET})
|
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/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/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})
|
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES} ${SHADER_FILES} ${README_FILES})
|
||||||
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${LIBRARIES})
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${LIBRARIES})
|
||||||
|
167
graphics.cc
167
graphics.cc
@ -1,100 +1,151 @@
|
|||||||
#include "graphics.hh"
|
#include "graphics.hh"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <ACGL/OpenGL/glloaders/extensions.hh>
|
||||||
|
#include <ACGL/Utils/FileHelpers.hh>
|
||||||
|
#include <ACGL/Utils/StringHelpers.hh>
|
||||||
|
|
||||||
#include "model.hh"
|
#include "model.hh"
|
||||||
#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ACGL::OpenGL::SharedShaderProgram shader;
|
Graphics::Graphics() {
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteCustomResources()
|
GLFWwindow* Graphics::getWindow() {
|
||||||
{
|
return window;
|
||||||
// we have memory management via reference counting, so nothing to do here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#ifdef __APPLE__
|
||||||
level.update(runTime);
|
#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:
|
// clear the framebuffer:
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
//set view and projection matrix
|
//set view and projection matrix
|
||||||
shader->setUniform("projectionMatrix", buildFrustum(75.0, 0.1, 100.0, (float)g_windowSize.x/(float)g_windowSize.y) );
|
shader->setUniform("projectionMatrix", buildFrustum(75.0f, 0.1f, 100.0f, (float)windowSize.x/(float)windowSize.y) );
|
||||||
// the + (0,1,0) compensates bunny doesn't have its center at it's center
|
shader->setUniform("viewMatrix", buildViewMatrix(level));
|
||||||
shader->setUniform("viewMatrix", buildViewMatrix());
|
|
||||||
|
|
||||||
//set lighting parameters
|
//set lighting parameters
|
||||||
if (level.getLights().size() > 0) {
|
if (level->getLights().size() > 0) {
|
||||||
shader->setUniform("lightCount", (int) level.getLights().size());
|
shader->setUniform("lightCount", (int) level->getLights().size());
|
||||||
|
|
||||||
// TODO look into doing this less often
|
// TODO look into doing this less often
|
||||||
// Build light position array
|
// Build light position array
|
||||||
glm::vec3 lightSources[level.getLights().size()];
|
glm::vec3 lightSources[level->getLights().size()];
|
||||||
for(unsigned int i = 0; i<level.getLights().size(); i++) {
|
for(unsigned int i = 0; i<level->getLights().size(); i++) {
|
||||||
lightSources[i] = level.getLights()[i].getPosition();
|
lightSources[i] = level->getLights()[i].getPosition();
|
||||||
}
|
}
|
||||||
glUniform3fv(shader->getUniformLocation("lightSources"),
|
glUniform3fv(shader->getUniformLocation("lightSources"),
|
||||||
sizeof(lightSources), (GLfloat*) lightSources);
|
sizeof(lightSources), (GLfloat*) lightSources);
|
||||||
// Build light colour array
|
// Build light colour array
|
||||||
glm::vec3 lightColours[level.getLights().size()];
|
glm::vec3 lightColours[level->getLights().size()];
|
||||||
for(unsigned int i = 0; i<level.getLights().size(); i++) {
|
for(unsigned int i = 0; i<level->getLights().size(); i++) {
|
||||||
lightColours[i] = level.getLights()[i].getColour();
|
lightColours[i] = level->getLights()[i].getColour();
|
||||||
}
|
}
|
||||||
glUniform3fv(shader->getUniformLocation("lightColors"),
|
glUniform3fv(shader->getUniformLocation("lightColors"),
|
||||||
sizeof(lightColours), (GLfloat*) lightColours);
|
sizeof(lightColours), (GLfloat*) lightColours);
|
||||||
// Build light attenuation array
|
// Build light attenuation array
|
||||||
float lightIntensities[level.getLights().size()];
|
float lightIntensities[level->getLights().size()];
|
||||||
for(unsigned int i = 0; i<level.getLights().size(); i++) {
|
for(unsigned int i = 0; i<level->getLights().size(); i++) {
|
||||||
lightIntensities[i] = level.getLights()[i].getIntensity();
|
lightIntensities[i] = level->getLights()[i].getIntensity();
|
||||||
}
|
}
|
||||||
glUniform1fv(shader->getUniformLocation("lightIntensities"),
|
glUniform1fv(shader->getUniformLocation("lightIntensities"),
|
||||||
sizeof(lightIntensities), (GLfloat*) lightIntensities);
|
sizeof(lightIntensities), (GLfloat*) lightIntensities);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set Material Parameters
|
// set Material Parameters
|
||||||
shader->setUniform("ambientColor", level.getAmbientLight());
|
shader->setUniform("ambientColor", level->getAmbientLight());
|
||||||
shader->setUniform("camera", glm::vec3(0.0f, 0.0f, 0.0f));
|
shader->setUniform("camera", glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
// render the level(currently only a bunny):
|
// 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:
|
// store the new window size and adjust the viewport:
|
||||||
g_windowSize = glm::uvec2( newWidth, newHeight);
|
graphics->setWindowSize(glm::uvec2( newWidth, newHeight));
|
||||||
glViewport( 0, 0, g_windowSize.x, g_windowSize.y );
|
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 phiHalfInRadians = 0.5*phiInDegree * (M_PI/180.0);
|
||||||
float top = _near * tan( phiHalfInRadians );
|
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);
|
return glm::frustum(left, right, bottom, top, _near, _far);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 buildViewMatrix() {
|
glm::mat4 Graphics::buildViewMatrix(Level* level) {
|
||||||
glm::vec4 cameraVector = glm::vec4(0.0f, 0.0f, level.getCamera().getDistance(), 0.0f);
|
glm::vec4 cameraVector = glm::vec4(0.0f, 0.0f, level->getCamera().getDistance(), 0.0f);
|
||||||
// rotate vector
|
// rotate vector
|
||||||
glm::mat4 rotationMatrix = glm::rotate<float>(level.getCamera().getRotation()[0], glm::vec3(1.0f, 0.0f, 0.0f)) *
|
glm::mat4 rotationMatrix = glm::rotate<float>(level->getCamera().getRotation()[0], glm::vec3(1.0f, 0.0f, 0.0f)) *
|
||||||
glm::rotate<float>(level.getCamera().getRotation()[1], glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate<float>(level.getCamera().getRotation()[2], glm::vec3(0.0f, 0.0f, 1.0f));
|
glm::rotate<float>(level->getCamera().getRotation()[1], glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate<float>(level->getCamera().getRotation()[2], glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
cameraVector = rotationMatrix * cameraVector;
|
cameraVector = rotationMatrix * cameraVector;
|
||||||
//construct lookAt (cameraPosition = cameraCenter + 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));
|
||||||
}
|
}
|
||||||
|
35
graphics.hh
35
graphics.hh
@ -1,26 +1,33 @@
|
|||||||
#ifndef GRAPHICS_HH_INCLUDED
|
#ifndef GRAPHICS_HH_INCLUDED
|
||||||
#define GRAPHICS_HH_INCLUDED
|
#define GRAPHICS_HH_INCLUDED
|
||||||
|
#include <ACGL/OpenGL/GL.hh>
|
||||||
|
|
||||||
#include "main.hh"
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <ACGL/Base/Settings.hh>
|
|
||||||
#include <ACGL/Math/Math.hh>
|
#include <ACGL/Math/Math.hh>
|
||||||
|
#include "level.hh"
|
||||||
|
|
||||||
// gets called after the OpenGL window is prepared, init of example specific stuff:
|
class Graphics {
|
||||||
void initCustomResources();
|
public:
|
||||||
|
Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane);
|
||||||
// gets called at application shutdown:
|
Graphics();
|
||||||
void deleteCustomResources();
|
void render(Level* level, ACGL::OpenGL::SharedShaderProgram shader);
|
||||||
|
|
||||||
// gets called ech frame, runTime is in seconds:
|
|
||||||
void draw(float runTime);
|
|
||||||
|
|
||||||
// gets called at window resize:
|
// gets called at window resize:
|
||||||
void resizeCallback( GLFWwindow *, int newWidth, int newHeight );
|
void resizeCallback( GLFWwindow *, int newWidth, int newHeight );
|
||||||
|
|
||||||
// to build the projection matrix:
|
// to build the projection matrix:
|
||||||
glm::mat4 buildFrustum( float phiInDegree, float near, float far, float aspectRatio);
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
glm::mat4 buildViewMatrix();
|
void resizeCallback(Graphics* graphics, int newWidth, int newHeight);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
154
main.cc
154
main.cc
@ -10,108 +10,63 @@
|
|||||||
#include <ACGL/Math/Math.hh>
|
#include <ACGL/Math/Math.hh>
|
||||||
#include <ACGL/Utils/FileHelpers.hh>
|
#include <ACGL/Utils/FileHelpers.hh>
|
||||||
#include <ACGL/Utils/StringHelpers.hh>
|
#include <ACGL/Utils/StringHelpers.hh>
|
||||||
|
#include <ACGL/OpenGL/Objects/VertexArrayObject.hh>
|
||||||
|
#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>
|
||||||
|
|
||||||
#include <ACGL/OpenGL/glloaders/extensions.hh>
|
#include <ACGL/OpenGL/glloaders/extensions.hh>
|
||||||
|
#include <ACGL/Base/Settings.hh>
|
||||||
|
|
||||||
|
#include "model.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ACGL::OpenGL;
|
using namespace ACGL::OpenGL;
|
||||||
using namespace ACGL::Base;
|
using namespace ACGL::Base;
|
||||||
using namespace ACGL::Utils;
|
using namespace ACGL::Utils;
|
||||||
|
|
||||||
glm::uvec2 g_windowSize( 1024, 786 );
|
Application::Application() {
|
||||||
float g_nearPlane = 0.1f;
|
graphics = Graphics(glm::uvec2(1024, 786), 0.1f, 100.0f);
|
||||||
float g_farPlane = 100.0f;
|
}
|
||||||
bool glfwWindowClosed = false;
|
|
||||||
|
|
||||||
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__
|
// define where shaders and textures can be found:
|
||||||
#if (ACGL_OPENGL_VERSION >= 30)
|
ACGL::Base::Settings::the()->setResourcePath("../");
|
||||||
// request OpenGL 3.2, will return a 4.1 context on Mavericks
|
ACGL::Base::Settings::the()->setShaderPath("Shader/");
|
||||||
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
|
ACGL::Base::Settings::the()->setTexturePath("Geometry/");
|
||||||
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 );
|
ACGL::Base::Settings::the()->setGeometryPath("Geometry/");
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
// load Model to give shader correct Attribute locations
|
||||||
#endif
|
// TODO look up if this is really necessary, since this looks really stupid.
|
||||||
#else
|
Model model = Model("Bunny.obj");
|
||||||
// non-apple
|
|
||||||
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, _version / 10 );
|
// look up all shader files starting with 'phong' and build a ShaderProgram from it:
|
||||||
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, _version % 10 );
|
shader = ACGL::OpenGL::ShaderProgramCreator("phong").attributeLocations(
|
||||||
#ifdef ACGL_OPENGL_PROFILE_CORE
|
model.getReference()->getAttributeLocations()).create();
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
shader->use();
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
#endif
|
// load Level
|
||||||
#endif
|
level.load(shader);
|
||||||
|
|
||||||
|
// just in case: check for errors
|
||||||
|
openGLCriticalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************
|
/**********************************************************************************************************************
|
||||||
* Returns true if a window with the desired context could get created.
|
* Returns true if a window with the desired context could get created.
|
||||||
* Requested OpenGL version gets set by ACGL defines.
|
* 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)
|
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[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
|
Application app = Application();
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Create OpenGL capable window:
|
// Create OpenGL capable window:
|
||||||
//
|
//
|
||||||
if ( !createWindow() ) {
|
if ( !app.getGraphics()->createWindow() ) {
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit( -1 );
|
exit( -1 );
|
||||||
}
|
}
|
||||||
@ -138,11 +92,11 @@ int main( int argc, char *argv[] )
|
|||||||
// Set window title to binary name (without the path):
|
// Set window title to binary name (without the path):
|
||||||
//
|
//
|
||||||
std::vector<std::string> tmp = StringHelpers::split( std::string( argv[0] ), '/' );
|
std::vector<std::string> 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
|
// Ensure we can capture the escape key being pressed below
|
||||||
glfwSetInputMode( g_window, GLFW_STICKY_KEYS, 1 );
|
glfwSetInputMode(app.getGraphics()->getWindow(), GLFW_STICKY_KEYS, 1 );
|
||||||
glfwSetWindowSizeCallback( g_window, resizeCallback );
|
//glfwSetWindowSizeCallback(app.getGraphics(), resizeCallback);
|
||||||
glfwSetKeyCallback( g_window, keyCallback );
|
glfwSetKeyCallback(app.getGraphics()->getWindow(), keyCallback );
|
||||||
|
|
||||||
// Enable vertical sync (on cards that support it) with parameter 1 - 0 means off
|
// Enable vertical sync (on cards that support it) with parameter 1 - 0 means off
|
||||||
glfwSwapInterval( 0 );
|
glfwSwapInterval( 0 );
|
||||||
@ -152,7 +106,7 @@ int main( int argc, char *argv[] )
|
|||||||
//
|
//
|
||||||
glClearColor( 0.0, 0.0, 0.0, 1.0 );
|
glClearColor( 0.0, 0.0, 0.0, 1.0 );
|
||||||
glEnable( GL_DEPTH_TEST );
|
glEnable( GL_DEPTH_TEST );
|
||||||
initCustomResources();
|
app.init();
|
||||||
|
|
||||||
int frameCount = 0;
|
int frameCount = 0;
|
||||||
|
|
||||||
@ -167,23 +121,23 @@ int main( int argc, char *argv[] )
|
|||||||
stringstream sstream (stringstream::in | stringstream::out);
|
stringstream sstream (stringstream::in | stringstream::out);
|
||||||
sstream << setprecision(1) << std::fixed
|
sstream << setprecision(1) << std::fixed
|
||||||
<< tmp[tmp.size()-1] << " - FPS: " << frameCount / (now-showNextFPS + FPSdelay) << " " << 1000 * (now-showNextFPS + FPSdelay)/frameCount << " msec";
|
<< 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;
|
showNextFPS = now + FPSdelay;
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw( now - startTimeInSeconds );
|
app.getLevel()->update(now - startTimeInSeconds);
|
||||||
|
app.getGraphics()->render(app.getLevel(), app.getShader());
|
||||||
|
|
||||||
openGLCriticalError();
|
openGLCriticalError();
|
||||||
|
|
||||||
// MacOS X will not swap correctly is another FBO is bound:
|
// MacOS X will not swap correctly is another FBO is bound:
|
||||||
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
|
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
|
||||||
glfwSwapBuffers( g_window );
|
glfwSwapBuffers(app.getGraphics()->getWindow());
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
frameCount++;
|
frameCount++;
|
||||||
} // Check if the window was closed
|
} // Check if the window was closed
|
||||||
while( !glfwWindowShouldClose( g_window ) );
|
while( !glfwWindowShouldClose(app.getGraphics()->getWindow()) );
|
||||||
|
|
||||||
deleteCustomResources();
|
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
35
main.hh
35
main.hh
@ -1,27 +1,28 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
#ifndef MAIN_HH_INCLUDED
|
||||||
//
|
#define MAIN_HH_INCLUDED
|
||||||
// headers needed:
|
|
||||||
//
|
|
||||||
#include <ACGL/Math/Math.hh>
|
|
||||||
#include <ACGL/OpenGL/GL.hh>
|
#include <ACGL/OpenGL/GL.hh>
|
||||||
|
#include <ACGL/Math/Math.hh>
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <ACGL/OpenGL/Objects/ArrayBuffer.hh>
|
#include <ACGL/OpenGL/Objects/ArrayBuffer.hh>
|
||||||
//
|
////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "physics.hh"
|
#include "physics.hh"
|
||||||
#include "graphics.hh"
|
#include "graphics.hh"
|
||||||
#include "level.hh"
|
#include "level.hh"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
//
|
class Application {
|
||||||
// implement the following functions:
|
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:
|
#endif
|
||||||
extern glm::uvec2 g_windowSize;
|
|
||||||
extern float g_nearPlane;
|
|
||||||
extern float g_farPlane;
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
177
physics.cc
Normal file
177
physics.cc
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#include "physics.hh"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
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<btRigidBody*> bodies; //list of all bodies. bodies are also in world, but save again to ease cleaning up process.
|
||||||
|
btRigidBody* playerBall;
|
||||||
|
btRigidBody* terrainBody;
|
||||||
|
|
||||||
|
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 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 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
if(bodies.size() == indice)
|
||||||
|
throw std::invalid_argument( "Bodies out of Sync" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getPos(int i)
|
||||||
|
{
|
||||||
|
btVector3 origin = bodies[i]->getCenterOfMassPosition();
|
||||||
|
glm::vec3 save(origin.getX(),origin.getY(),origin.getZ());
|
||||||
|
return save;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 getRotation(int i)
|
||||||
|
{
|
||||||
|
btQuaternion quat = bodies[i]->getOrientation();
|
||||||
|
|
||||||
|
glm::mat4 matrix = glm::rotate(
|
||||||
|
matrix,
|
||||||
|
quat.getAngle(),
|
||||||
|
glm::vec3(quat.getAxis().getX(), quat.getAxis().getY(), quat.getAxis().getZ())
|
||||||
|
);
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rollForward(glm::mat3 rotCamera)
|
||||||
|
{
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
50
physics.hh
50
physics.hh
@ -1,8 +1,58 @@
|
|||||||
#ifndef PHYSICS_HH_INCLUDED
|
#ifndef PHYSICS_HH_INCLUDED
|
||||||
#define PHYSICS_HH_INCLUDED
|
#define PHYSICS_HH_INCLUDED
|
||||||
|
|
||||||
|
#include <ACGL/Base/Settings.hh>
|
||||||
|
#include <ACGL/Math/Math.hh>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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!
|
||||||
|
|
||||||
|
#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"
|
||||||
|
#include "extern/bullet/src/LinearMath/btVector3.h"
|
||||||
|
#include "extern/bullet/src/LinearMath/btMatrix3x3.h"
|
||||||
|
|
||||||
class Physics {
|
class Physics {
|
||||||
public:
|
public:
|
||||||
Physics();
|
Physics();
|
||||||
|
~Physics();
|
||||||
|
void init();
|
||||||
|
void takeUpdateStep(float timeDiff);
|
||||||
|
void rollForward(glm::vec3 camPos, float strength);
|
||||||
|
glm::vec3 getPos(int i);
|
||||||
|
glm::mat4 getRotation(int i);
|
||||||
|
void rollForward(glm::mat3 rotCamera);
|
||||||
|
void addTerrain(int width, int length, float** heightData);
|
||||||
|
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;
|
||||||
|
btRigidBody* terrainBody;
|
||||||
|
std::vector<btRigidBody*> 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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user