SparrowEngine/src/engine.cpp
2017-04-08 12:14:15 +02:00

267 lines
7.1 KiB
C++

#include "engine.h"
#include <SFML/System/Clock.hpp>
#include <SFML/Window.hpp>
#include <SparrowInput/input.h>
#include <SparrowRenderer/sparrowrenderer.h>
#include <btBulletCollisionCommon.h>
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include "resourcemanager.h"
#include "scene/scenetree.h"
#include "sparrowshell/sparrowshell.h"
#include "scene/physicsdebugnode.h"
#include "imgui/imgui.h"
Engine::Engine() :
m_window(nullptr),
m_input(nullptr),
m_world(nullptr),
m_physicsDebugNode(nullptr),
m_togglePhysicsDebugAction(NO_ACTION),
m_toggleShellAction(NO_ACTION),
m_exitGameAction(NO_ACTION),
m_showMouseAction(NO_ACTION),
m_mouseVisible(true)
{
m_clock = new sf::Clock();
m_clock->restart();
m_renderer = new SparrowRenderer();
}
Engine::~Engine()
{
delete m_clock;
delete m_renderer;
if(m_window != NULL)
{
m_window->close();
delete m_window;
delete m_input;
}
if(m_world != NULL)
delete m_world;
}
void Engine::createWindow(std::string title,
unsigned int w,
unsigned int h,
const std::string &mode)
{
sf::Uint32 style = sf::Style::Close;
if(mode == "fullscreen")
style = sf::Style::Fullscreen;
else if(mode == "borderless")
style = sf::Style::None;
m_window = new sf::Window(sf::VideoMode(w, h),
title,
style,
sf::ContextSettings(24, 8, 0, 3, 3, sf::ContextSettings::Attribute::Core));
m_window->setFramerateLimit(60);
m_input = new Input(m_window);
m_renderer->initGL(w, h);
m_sparrowshell = new SparrowShell(m_window);
}
void Engine::initPhysics()
{
btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration();
btBroadphaseInterface *broadPhase = new btAxisSweep3(btVector3(-1000, -1000, -1000), btVector3(1000, 1000, 1000));
btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver *solver = new btSequentialImpulseConstraintSolver();
m_world = new btDiscreteDynamicsWorld(dispatcher, broadPhase, solver, collisionConfiguration);
m_world->setGravity(btVector3(0, -9.81f, 0));
}
void Engine::update()
{
// update delta time
m_lastTimeStamp = m_timeStamp;
m_timeStamp = (unsigned int) m_clock->getElapsedTime().asMilliseconds();
// update Events
m_input->updateEvents();
checkSpecialInputs();
// initialize imgui frame
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = float(getDeltaTime()) / 1000.;
ImGui::NewFrame();
// test gui
{
static bool testGuiOpen = true;
if(testGuiOpen)
{
ImGui::Begin("Test imgui Window", &testGuiOpen);
ImGui::Text("Hello, world!");
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
bool physicsDebugEnabled = (m_physicsDebugNode != nullptr);
if(ImGui::Checkbox("Toggle physics debug", &physicsDebugEnabled))
{
if(physicsDebugEnabled)
enablePhysicsDebug();
else
disablePhysicsDebug();
}
if(ImGui::Button("EXIT GAME"))
stop();
ImGui::End();
}
}
// update Physics
if(m_world != nullptr)
{
m_world->stepSimulation(1000.f*(float)getDeltaTime());
if(m_physicsDebugNode != nullptr)
{
m_physicsDebugNode->clearBuffers();
m_world->debugDrawWorld();
}
}
// update Scene
getScene()->update();
// update Display
if(m_input->isResized())
m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y);
m_renderer->renderGL();
m_window->display();
}
void Engine::start()
{
m_running = true;
while(!m_input->isCloseRequested() && m_running)
update();
}
void Engine::stop()
{
m_running = false;
}
unsigned int Engine::getTime() const
{
return m_timeStamp;
}
unsigned int Engine::getDeltaTime() const
{
return m_timeStamp - m_lastTimeStamp;
}
//void Engine::setScene(SceneTree *scene)
void Engine::setScene(std::string scene)
{
if(m_current_scene.empty()){
m_current_scene = scene;
}
SceneTree* previous_scene = RESOURCE_GET(SceneTree,m_current_scene);
SceneTree* new_scene = RESOURCE_GET(SceneTree,scene);
m_current_scene = scene;
if(m_physicsDebugNode != nullptr)
{
previous_scene->removeFromIndex(m_physicsDebugNode);
new_scene->addToIndex(m_physicsDebugNode);
}
previous_scene->getRootObject()->removeChild(m_sparrowshell);
m_renderer->setScene(new_scene);
m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y);
new_scene->getRootObject()->addChild(m_sparrowshell);
new_scene->updateShaders();
}
void Engine::enablePhysicsDebug()
{
if(m_world != nullptr && m_physicsDebugNode == nullptr)
{
m_physicsDebugNode = new PhysicsDebugNode();
getScene()->addToIndex(m_physicsDebugNode);
m_world->setDebugDrawer(m_physicsDebugNode);
m_world->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
getScene()->updateShaders();
}
}
void Engine::disablePhysicsDebug()
{
if(m_world != nullptr && m_physicsDebugNode != nullptr)
{
m_world->setDebugDrawer(nullptr);
getScene()->removeFromIndex(m_physicsDebugNode);
delete m_physicsDebugNode;
m_physicsDebugNode = nullptr;
}
}
void Engine::toggleMouseVisibility()
{
m_mouseVisible = !m_mouseVisible;
m_window->setMouseCursorVisible(m_mouseVisible);
m_input->setMouseGrabbed(!m_mouseVisible);
}
void Engine::setTogglePhysicsDebugAction(int action)
{
m_togglePhysicsDebugAction = action;
}
void Engine::setToggleShellAction(int action)
{
m_toggleShellAction = action;
}
void Engine::setExitGameAction(int action)
{
m_exitGameAction = action;
}
void Engine::setShowMouseAction(int action)
{
m_showMouseAction = action;
}
void Engine::checkSpecialInputs()
{
for(Action action : m_input->getActions())
{
if(action.action == NO_ACTION)
continue;
if(action.action == m_togglePhysicsDebugAction)
{
if(m_physicsDebugNode == nullptr)
enablePhysicsDebug();
else
disablePhysicsDebug();
}
else if(action.action == m_toggleShellAction)
m_sparrowshell->toggleShell();
else if(action.action == m_exitGameAction)
{
if(m_sparrowshell->isVisible())
m_sparrowshell->toggleShell();
else
m_running = false;
}
else if(action.action == m_showMouseAction)
toggleMouseVisibility();
}
}
void Engine::createScene(std::string scene_name)
{
RESOURCE_ADD(new SceneTree(*this),SceneTree,scene_name);
//return new SceneTree(*this);
}
SceneTree* Engine::getScene() const
{
return RESOURCE_GET(SceneTree,m_current_scene);
}