Dawn/src/dawnglfw/host/DawnGLFWHost.cpp

142 lines
3.2 KiB
C++

/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "DawnGLFWHost.hpp"
#include "game/DawnGame.hpp"
#include "dawnopengl.hpp"
#include "display/BackBufferRenderTarget.hpp"
using namespace Dawn;
// Static declaration of the host, needed due to GLFW events being C-like
DawnHost *DAWN_HOST = nullptr;
// Host
DawnHost::DawnHost() {
this->data = std::make_unique<DawnHostData>();
this->data->window = nullptr;
}
int32_t DawnHost::init(DawnGame &game) {
// Update values
this->game = &game;
DAWN_HOST = this;
// Init GLFW
if(!glfwInit()) return DAWN_GLFW_INIT_RESULT_INIT_FAILED;
glfwSetErrorCallback(&glfwOnError);
// Setup window hints
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
// Create Window
this->data->window = glfwCreateWindow(
DAWN_GLFW_WINDOW_WIDTH_DEFAULT,
DAWN_GLFW_WINDOW_HEIGHT_DEFAULT,
"Dawn", NULL, NULL
);
if(this->data->window == nullptr) {
glfwTerminate();
return DAWN_GLFW_INIT_RESULT_WINDOW_CREATE_FAILED;
}
// Load GLAD
glfwMakeContextCurrent(this->data->window);
glfwSwapInterval(0);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
// Initialize the game
auto result = game.init();
if(result != DAWN_GAME_INIT_RESULT_SUCCESS) return result;
game.renderManager.backBuffer.setSize(
DAWN_GLFW_WINDOW_WIDTH_DEFAULT,
DAWN_GLFW_WINDOW_HEIGHT_DEFAULT
);
// Set up event listeners
glfwSetWindowSizeCallback(this->data->window, &glfwOnResize);
return DAWN_HOST_INIT_RESULT_SUCCESS;
}
int32_t DawnHost::start(DawnGame &game) {
double_t time, newTime;
float_t fDelta;
int32_t updateResult;
// Main Render Loop
time = 0.0f;
while(!glfwWindowShouldClose(this->data->window)) {
// Determine the delta.
newTime = glfwGetTime();
fDelta = (float_t)(newTime - time);
time = newTime;
// Perform update
updateResult = this->update(game, fDelta);
// Did the update complete successfully?
if(updateResult == DAWN_HOST_UPDATE_RESULT_EXIT) {
break;
} else if(updateResult != DAWN_HOST_UPDATE_RESULT_SUCCESS) {
return DAWN_GLFW_START_RESULT_UPDATE_FAILED;
}
// Tick the engine.
glfwSwapBuffers(this->data->window);
// Update events
glfwPollEvents();
}
return DAWN_HOST_START_RESULT_EXIT_SUCCESS;
}
int32_t DawnHost::update(DawnGame &game, float_t delta) {
auto ret = game.update(delta);
switch(ret) {
case DAWN_GAME_UPDATE_RESULT_SUCCESS:
return DAWN_HOST_UPDATE_RESULT_SUCCESS;
case DAWN_GAME_UPDATE_RESULT_EXIT:
return DAWN_HOST_UPDATE_RESULT_EXIT;
default:
return ret;
}
}
void DawnHost::unload(DawnGame &game) {
glfwDestroyWindow(this->data->window);
this->data->window = nullptr;
glfwTerminate();
}
DawnHost::~DawnHost() {
DAWN_HOST = nullptr;
}
// GLFW Callbacks
void glfwOnError(int error, const char* description) {
fputs(description, stderr);
}
void glfwOnResize(
GLFWwindow *window,
int32_t width,
int32_t height
) {
if(DAWN_HOST == nullptr) return;
// TODO: I may throttle this, it calls for every frame the window's resized.
DAWN_HOST->game->renderManager.backBuffer.setSize(
(float_t)width,
(float_t)height
);
}