Further abstraction of platform window handling

We could now build our own native window class and stop relying on GLFW. However this won't be important for now!
This commit is contained in:
Nigel Barink 2023-01-31 18:41:46 +01:00
parent ba69726e33
commit 7448017701
16 changed files with 329 additions and 130 deletions

View File

@ -45,13 +45,15 @@ public:
double previous = glfwGetTime();
double lag = 0.0;
while (!appWindow.WindowShouldClose())
while (!appWindow->WindowShouldClose())
{
PollEvents();
double now = glfwGetTime();
double elapsed = now - previous ;
previous = now;
lag += elapsed;
scene.Update();
if (sceneview.isFocused)
{
@ -62,9 +64,9 @@ public:
if (MouseButtonPressed(YOGGIE_MOUSE_BUTTON_RIGHT)) {
glfwSetInputMode(appWindow.GetGLFWHandle(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
auto newX = getCursorPosX(&appWindow);
auto newY = getCursorPosY(&appWindow);
glfwSetInputMode((GLFWwindow*)appWindow->GetHandle(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
auto newX = getCursorPosX(appWindow);
auto newY = getCursorPosY(appWindow);
if (firstMouse)
{
@ -94,7 +96,7 @@ public:
}
else if (firstMouse == false)
{
glfwSetInputMode(appWindow.GetGLFWHandle(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetInputMode((GLFWwindow*)appWindow->GetHandle(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
firstMouse = true;
}

View File

@ -11,6 +11,10 @@ project "YoggieEngine"
}
filter "system:Windows"
defines{
"GLFW"
}
includedirs {
"./src",

View File

@ -9,8 +9,10 @@
namespace YoggieEngine {
Application::Application(const std::string& name)
: m_AppName(name), appWindow(1200, 700)
: m_AppName(name)
{
appWindow = CreateNativeWindow(1200, 700, m_AppName.c_str());
// Initialize engine should possibly happen here
EngineInstrumentation::PerfomanceSamplerInit();
@ -24,14 +26,14 @@ namespace YoggieEngine {
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(appWindow.GetGLFWHandle(), true);
ImGui_ImplGlfw_InitForOpenGL((GLFWwindow*)appWindow->GetHandle(), true);
ImGui_ImplOpenGL3_Init("#version 450");
ImGuizmo::SetImGuiContext(ImGui::GetCurrentContext());
ImGuizmo::SetOrthographic(true);
init_inputSystem(&appWindow);
init_inputSystem(appWindow);
}
@ -41,12 +43,12 @@ namespace YoggieEngine {
void Application::PollEvents() {
appWindow.Poll();
appWindow->Poll();
}
void Application::SwapBuffers()
{
appWindow.SwapBuffers();
appWindow->SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
@ -81,5 +83,8 @@ namespace YoggieEngine {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
delete appWindow;
}
}

View File

@ -20,7 +20,7 @@ namespace YoggieEngine {
protected:
std::string m_AppName;
NativeWindow appWindow;
NativeWindow* appWindow;
friend class ApplicationRuntime;
};

View File

@ -17,10 +17,10 @@ namespace YoggieEngine {
void init_inputSystem(NativeWindow* window) {
cursor_pos_x = 0;
cursor_pos_y = 0;
glfwSetKeyCallback(window->GetGLFWHandle(), key_callback);
glfwSetMouseButtonCallback(window->GetGLFWHandle(), mouseButton_callback);
glfwSetCursorPosCallback(window->GetGLFWHandle(), cursorPos_callback);
glfwSetCursorEnterCallback(window->GetGLFWHandle(), cursorEnter_callback);
glfwSetKeyCallback((GLFWwindow*) window->GetHandle(), key_callback);
glfwSetMouseButtonCallback((GLFWwindow*)window->GetHandle(), mouseButton_callback);
glfwSetCursorPosCallback((GLFWwindow*)window->GetHandle(), cursorPos_callback);
glfwSetCursorEnterCallback((GLFWwindow*)window->GetHandle(), cursorEnter_callback);
}
void ReceiveInput() {
@ -43,13 +43,13 @@ namespace YoggieEngine {
double getCursorPosX(NativeWindow* window)
{
glfwGetCursorPos(window->GetGLFWHandle(), &cursor_pos_x, nullptr);
glfwGetCursorPos((GLFWwindow*)window->GetHandle(), &cursor_pos_x, nullptr);
return cursor_pos_x;
}
double getCursorPosY(NativeWindow* window)
{
glfwGetCursorPos(window->GetGLFWHandle(), nullptr, &cursor_pos_y);
glfwGetCursorPos((GLFWwindow*)window->GetHandle(), nullptr, &cursor_pos_y);
return cursor_pos_y;
}

View File

@ -0,0 +1,26 @@
#include "YoggieEngine.h"
#include "X11Window.h"
namespace YoggieEngine {
X11Window::X11Window(const int width, const int height, const char* title) : NativeWindow()
{
// Open a display
//Display* d = XOpenDisplay(0);
//if (d) {
// // create the window
// Window w = XCreateWindow(d, DefaultRootWindow(d), 0, 0, 200, 100, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, 0);
// // show the window
// XMapWindow(d, w);
// XFlush(d);
//}
}
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "../Window.h"
//#include <X11/Xlib.h>
//#include <unistd.h>
namespace YoggieEngine {
class X11Window : public NativeWindow {
public:
X11Window(const int width, const int height, const char* title);
~X11Window();
bool WindowShouldClose();
void SetViewPort(int width, int height);
void Poll();
void SwappBuffers();
void* GetHandle();
private:
void* m_handle;
bool m_fullscreen;
bool m_resizable;
bool m_vsync;
int m_widht;
int m_height;
void SetContext();
};
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "Window.h"
#include "glfw/glfwWindow.h"
#include "Windows/win32Window.h"
namespace YoggieEngine {
inline NativeWindow* CreateNativeWindow(int width, int height, const char* title) {
spdlog::debug("CreateNativeWindow is called!");
#ifdef PLATFORM_WINDOWS
spdlog::debug("PLATFROM_WINDOWS");
return win32Window(width, height, title);
#elseif PLATFORM_LINUX
spdlog::debug("PLATFORM_LINUX");
return X11Window(width, height, title);
#else
spdlog::debug("PLATFORM_GLFW");
return new glfwWindow(width, height, title);
#endif
}
}

View File

@ -1,86 +0,0 @@
#include <YoggieEngine.h>
#include "Window.h"
namespace YoggieEngine {
void LoadGLExtensions();
NativeWindow::NativeWindow(const int width, const int height) :
Width(width), Height(height), FullScreen(false)
{
if (InitGLFW() == false) {
exit(-1);
}
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
if( FullScreen )
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
if( !Resizable)
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
if (!VSync)
glfwSwapInterval(0);
window = glfwCreateWindow(Width, Height, "BarinkEngine", NULL, NULL);
if (!window)
{
spdlog::error("GLFW failed to create window!");
glfwTerminate();
return;
}
SetContext();
glfwGetFramebufferSize(window, &Width, &Height);
LoadGLExtensions();
}
void NativeWindow::SetViewPort(int width, int height) {
glViewport(0, 0, width, height);
}
NativeWindow::~NativeWindow() {
glfwTerminate();
}
bool NativeWindow::WindowShouldClose() {
return glfwWindowShouldClose(window);
}
void NativeWindow::SetContext()
{
glfwMakeContextCurrent(window);
}
void NativeWindow::Poll()
{
glfwPollEvents();
}
void NativeWindow::SwapBuffers()
{
glfwSwapBuffers(window);
}
bool NativeWindow::InitGLFW()
{
if (!glfwInit())
{
spdlog::error("Failed to initialise GLFW!");
return false;
}
return true;
}
void LoadGLExtensions()
{
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
spdlog::error("Failed to initialize GLAD!\n");
exit(-1);
}
}
}

View File

@ -1,41 +1,33 @@
#pragma once
#define GLFW_STATIC
#include <iostream>
#include <GLFW/glfw3.h>
#include "../EventSystem/Event.h"
#include "../EventSystem/EventListener.h"
namespace YoggieEngine {
class NativeWindow {
public:
NativeWindow(const int width, const int height);
~NativeWindow();
NativeWindow() { spdlog::debug("NativeWindow Constructor called!"); }
virtual bool WindowShouldClose() { return true; }
bool WindowShouldClose();
virtual void SetViewPort(int width , int height) {}
virtual void Poll() {}
virtual void SwapBuffers() {}
void SetViewPort(int width , int height);
void Poll();
void SwapBuffers();
const int getWidth()const { return m_width; }
const int getHeight()const { return m_height; }
GLFWwindow* GetGLFWHandle() { return window; }
const int getWidth()const { return Width; }
const int getHeight()const { return Height; }
virtual void* GetHandle() { return m_handle; }
private:
GLFWwindow* window;
bool FullScreen = false;
bool Resizable = true;
bool VSync = false;
int Width, Height;
protected:
virtual void SetContext() {}
void SetContext();
static bool InitGLFW();
bool m_fullscreen = false;
bool m_resizable = true;
bool m_vsync = false;
int m_width;
int m_height;
void* m_handle;
};
}

View File

@ -0,0 +1,46 @@
#include "YoggieEngine.h"
#include "win32Window.h"
#include <Windows.h>
namespace YoggieEngine {
Win32Window::Win32Window(const int width, const int height, const char* title)
{
//WNDCLASS wc = {};
//wc.lpfnWndProc = WindowProc;
//wc.hInstance = GetModuleHandle(NULL);
//wc.lpszClassName = (const wchar_t*) title;
//RegisterClass(&wc);
//HWND hwnd = CreateWindowEx(
// 0, // Optional window style
// (const wchar_t*)title, // Window Class
// (const wchar_t*)title, // Window Text
// WS_OVERLAPPEDWINDOW, // Window Style
// // Size and Position
// CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
// NULL, // Parent window
// NULL, // Menu
// wc.hInstance, // Instance handle
// NULL // Additional appplication data
//);
//if (hwnd == NULL) {
// spdlog::error("This is bad!! Window creation failed!");
// return;
//}
//ShowWindow(hwnd, SW_NORMAL);
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../Window.h"
namespace YoggieEngine {
class Win32Window : public NativeWindow {
public:
Win32Window(const int width, const int height, const char* title);
~Win32Window();
bool WindowShouldClose();
void setViewPort(int width, int height);
void Poll();
void SwapBuffers();
void* GetHandle();
private:
void SetContext();
bool m_vsync;
bool m_resizable;
bool m_fullscreen;
int m_width;
int m_height;
};
}

View File

@ -0,0 +1,93 @@
#include "YoggieEngine.h"
#include "glfwWindow.h"
namespace YoggieEngine {
void LoadGLExtensions() {
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
spdlog::error("Failed to initialize GLAD!\n");
exit(-1);
}
}
glfwWindow::glfwWindow(const int width, const int height, const char* title)
: NativeWindow()
{
spdlog::debug("Creating window");
m_width = width;
m_height = height;
m_fullscreen = false;
if (!glfwInit()) {
spdlog::error("Failed to initialise GLFW!");
exit(-1);
}
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
if (m_fullscreen) {
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
}
if (!m_resizable) {
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
}
if (!m_vsync) {
glfwSwapInterval(0);
}
window = glfwCreateWindow(m_width, m_height, title, NULL, NULL);
if (!window) {
spdlog::error("GLFW failed to create a window!");
glfwTerminate();
exit(-1);
}
SetContext();
glfwGetFramebufferSize(window, &m_width, &m_height);
LoadGLExtensions();
}
glfwWindow::~glfwWindow()
{
glfwTerminate();
}
bool glfwWindow::WindowShouldClose()
{
return glfwWindowShouldClose(window);
}
void glfwWindow::Poll()
{
glfwPollEvents();
}
void glfwWindow::SwapBuffers()
{
glfwSwapBuffers(window);
}
void* glfwWindow::GetHandle()
{
return window;
}
void glfwWindow::SetViewPort(int width, int height)
{
glViewport(0, 0, width, height);
}
void glfwWindow::SetContext()
{
glfwMakeContextCurrent(window);
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <GLFW/glfw3.h>
#include "../Window.h"
namespace YoggieEngine {
class glfwWindow : public NativeWindow {
public:
glfwWindow(const int width, const int height, const char* title);
~glfwWindow();
bool WindowShouldClose() override;
void Poll() override;
void SwapBuffers() override;
void* GetHandle() override;
void SetViewPort(int width, int height) override;
private:
void SetContext() override;
private:
// GLFW specific
GLFWwindow* window;
};
}

View File

@ -31,8 +31,7 @@ extern "C"
// Main library stuff
#include "Platform/Window.h"
#include "Platform/Platform.h"
#include "Graphics/Primitives/Mesh.h"
#include "Graphics/Primitives/Shader.h"

View File

@ -16,6 +16,7 @@ workspace "Yoggie GameEngine"
defines{
" _CRT_SECURE_NO_WARNINGS",
"GLFW_STATIC"
}
filter "configurations:Debug"