Program Listing for File Window.cpp
↰ Return to documentation for file (Src/GraphicsEngineVulkan/window/Window.cpp
)
#include "window/Window.hpp"
#include "spdlog/spdlog.h"
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_vulkan.h>
#include <stdexcept>
using namespace Kataglyphis::Frontend;
// GLFW Callback functions
static void onErrorCallback(int error, const char *description)
{
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
}
Window::Window()
:
window_width(800.f), window_height(600.f), x_change(0.0f), y_change(0.0f), framebuffer_resized(false)
{
// all keys non-pressed in the beginning
for (size_t i = 0; i < 1024; i++) { keys[i] = 0; }
initialize();
}
// please use this constructor; never the standard
Window::Window(uint32_t window_width, uint32_t window_height)
:
window_width(window_width), window_height(window_height), x_change(0.0f), y_change(0.0f), framebuffer_resized(false)
{
// all keys non-pressed in the beginning
for (size_t i = 0; i < 1024; i++) { keys[i] = 0; }
initialize();
}
int Window::initialize()
{
glfwSetErrorCallback(onErrorCallback);
if (!glfwInit()) {
printf("GLFW Init failed!");
glfwTerminate();
return 1;
}
if (!glfwVulkanSupported()) { spdlog::error("No Vulkan Supported!"); }
// allow it to resize
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
// retrieve new window
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
main_window = glfwCreateWindow(window_width, window_height, "\\__/ Epic graphics from hell \\__/ ", NULL, NULL);
if (!main_window) {
printf("GLFW Window creation failed!");
glfwTerminate();
return 1;
}
// get buffer size information
glfwGetFramebufferSize(main_window, &window_buffer_width, &window_buffer_height);
init_callbacks();
return 0;
}
void Window::cleanUp()
{
glfwDestroyWindow(main_window);
glfwTerminate();
}
void Window::update_viewport() { glfwGetFramebufferSize(main_window, &window_buffer_width, &window_buffer_height); }
void Window::set_buffer_size(float window_buffer_width, float window_buffer_height)
{
this->window_buffer_width = window_buffer_width;
this->window_buffer_height = window_buffer_height;
}
float Window::get_x_change()
{
float the_change = x_change;
x_change = 0.0f;
return the_change;
}
float Window::get_y_change()
{
float the_change = y_change;
y_change = 0.0f;
return the_change;
}
float Window::get_height() { return float(window_height); }
float Window::get_width() { return float(window_width); }
bool Window::framebuffer_size_has_changed() { return framebuffer_resized; }
void Window::init_callbacks()
{
// TODO: remember this section for our later game logic
// for the space ship to fly around
glfwSetWindowUserPointer(main_window, this);
glfwSetKeyCallback(main_window, &key_callback);
glfwSetMouseButtonCallback(main_window, &mouse_button_callback);
glfwSetFramebufferSizeCallback(main_window, &framebuffer_size_callback);
}
void Window::framebuffer_size_callback(GLFWwindow *window, int width, int height)
{
auto app = reinterpret_cast<Window *>(glfwGetWindowUserPointer(window));
app->framebuffer_resized = true;
app->window_width = width;
app->window_height = height;
}
void Window::reset_framebuffer_has_changed() { this->framebuffer_resized = false; }
void Window::key_callback(GLFWwindow *window, int key, int code, int action, int mode)
{
Window *the_window = static_cast<Window *>(glfwGetWindowUserPointer(window));
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { glfwSetWindowShouldClose(window, VK_TRUE); }
if (key >= 0 && key < 1024) {
if (action == GLFW_PRESS) {
the_window->keys[key] = true;
} else if (action == GLFW_RELEASE) {
the_window->keys[key] = false;
}
}
}
void Window::mouse_callback(GLFWwindow *window, double x_pos, double y_pos)
{
Window *the_window = static_cast<Window *>(glfwGetWindowUserPointer(window));
// need to handle first occurance of a mouse moving event
if (the_window->mouse_first_moved) {
the_window->last_x = static_cast<float>(x_pos);
the_window->last_y = static_cast<float>(y_pos);
the_window->mouse_first_moved = false;
}
the_window->x_change = static_cast<float>((x_pos - the_window->last_x));
// take care of correct substraction :)
the_window->y_change = static_cast<float>((the_window->last_y - y_pos));
// update params
the_window->last_x = static_cast<float>(x_pos);
the_window->last_y = static_cast<float>(y_pos);
}
void Window::mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
{
if (ImGui::GetCurrentContext() != nullptr && ImGui::GetIO().WantCaptureMouse) {
ImGuiIO &io = ImGui::GetIO();
io.AddMouseButtonEvent(button, action);
return;
}
Window *the_window = static_cast<Window *>(glfwGetWindowUserPointer(window));
if ((action == GLFW_PRESS) && (button == GLFW_MOUSE_BUTTON_RIGHT)) {
glfwSetCursorPosCallback(window, mouse_callback);
} else {
the_window->mouse_first_moved = true;
glfwSetCursorPosCallback(window, NULL);
}
}
Window::~Window() {}