142 lines
3.2 KiB
C++
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
|
|
);
|
|
} |