From 74480177019ffab71c5a7243631fa94c8788da25 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Tue, 31 Jan 2023 18:41:46 +0100 Subject: [PATCH] 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! --- Editor/src/app.cpp | 12 ++- YoggieEngine/premake5.lua | 4 + YoggieEngine/src/Application.cpp | 15 ++- YoggieEngine/src/Application.h | 2 +- YoggieEngine/src/Input/InputManager.cpp | 12 +-- YoggieEngine/src/Platform/Linux/X11Window.cpp | 26 ++++++ YoggieEngine/src/Platform/Linux/X11Window.h | 32 +++++++ YoggieEngine/src/Platform/Platform.h | 25 +++++ YoggieEngine/src/Platform/Window.cpp | 86 ----------------- YoggieEngine/src/Platform/Window.h | 42 ++++----- .../src/Platform/Windows/win32Window.cpp | 46 +++++++++ .../src/Platform/Windows/win32Window.h | 31 +++++++ YoggieEngine/src/Platform/glfw/glfwWindow.cpp | 93 +++++++++++++++++++ YoggieEngine/src/Platform/glfw/glfwWindow.h | 29 ++++++ YoggieEngine/src/YoggieEngine.h | 3 +- premake5.lua | 1 + 16 files changed, 329 insertions(+), 130 deletions(-) create mode 100644 YoggieEngine/src/Platform/Linux/X11Window.cpp create mode 100644 YoggieEngine/src/Platform/Linux/X11Window.h create mode 100644 YoggieEngine/src/Platform/Platform.h delete mode 100644 YoggieEngine/src/Platform/Window.cpp create mode 100644 YoggieEngine/src/Platform/Windows/win32Window.cpp create mode 100644 YoggieEngine/src/Platform/Windows/win32Window.h create mode 100644 YoggieEngine/src/Platform/glfw/glfwWindow.cpp create mode 100644 YoggieEngine/src/Platform/glfw/glfwWindow.h diff --git a/Editor/src/app.cpp b/Editor/src/app.cpp index 313b9ca..53a2cef 100644 --- a/Editor/src/app.cpp +++ b/Editor/src/app.cpp @@ -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; } diff --git a/YoggieEngine/premake5.lua b/YoggieEngine/premake5.lua index 5f3fc49..6637e64 100644 --- a/YoggieEngine/premake5.lua +++ b/YoggieEngine/premake5.lua @@ -11,6 +11,10 @@ project "YoggieEngine" } + filter "system:Windows" + defines{ + "GLFW" + } includedirs { "./src", diff --git a/YoggieEngine/src/Application.cpp b/YoggieEngine/src/Application.cpp index a21187a..6aa7ebd 100644 --- a/YoggieEngine/src/Application.cpp +++ b/YoggieEngine/src/Application.cpp @@ -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; + } } diff --git a/YoggieEngine/src/Application.h b/YoggieEngine/src/Application.h index e8b4716..f6c5b19 100644 --- a/YoggieEngine/src/Application.h +++ b/YoggieEngine/src/Application.h @@ -20,7 +20,7 @@ namespace YoggieEngine { protected: std::string m_AppName; - NativeWindow appWindow; + NativeWindow* appWindow; friend class ApplicationRuntime; }; diff --git a/YoggieEngine/src/Input/InputManager.cpp b/YoggieEngine/src/Input/InputManager.cpp index 766b776..bdddad9 100644 --- a/YoggieEngine/src/Input/InputManager.cpp +++ b/YoggieEngine/src/Input/InputManager.cpp @@ -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; } diff --git a/YoggieEngine/src/Platform/Linux/X11Window.cpp b/YoggieEngine/src/Platform/Linux/X11Window.cpp new file mode 100644 index 0000000..de84123 --- /dev/null +++ b/YoggieEngine/src/Platform/Linux/X11Window.cpp @@ -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); + + //} + + } + + +} + + diff --git a/YoggieEngine/src/Platform/Linux/X11Window.h b/YoggieEngine/src/Platform/Linux/X11Window.h new file mode 100644 index 0000000..df43393 --- /dev/null +++ b/YoggieEngine/src/Platform/Linux/X11Window.h @@ -0,0 +1,32 @@ +#pragma once +#include "../Window.h" + +//#include +//#include + +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(); + + }; +} \ No newline at end of file diff --git a/YoggieEngine/src/Platform/Platform.h b/YoggieEngine/src/Platform/Platform.h new file mode 100644 index 0000000..6e4e7f1 --- /dev/null +++ b/YoggieEngine/src/Platform/Platform.h @@ -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 + + } + + +} diff --git a/YoggieEngine/src/Platform/Window.cpp b/YoggieEngine/src/Platform/Window.cpp deleted file mode 100644 index 08dbe66..0000000 --- a/YoggieEngine/src/Platform/Window.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#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); - } - } - - - -} diff --git a/YoggieEngine/src/Platform/Window.h b/YoggieEngine/src/Platform/Window.h index 0e7843c..322947e 100644 --- a/YoggieEngine/src/Platform/Window.h +++ b/YoggieEngine/src/Platform/Window.h @@ -1,41 +1,33 @@ #pragma once -#define GLFW_STATIC - -#include -#include - #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; }; - - - } diff --git a/YoggieEngine/src/Platform/Windows/win32Window.cpp b/YoggieEngine/src/Platform/Windows/win32Window.cpp new file mode 100644 index 0000000..979ef4e --- /dev/null +++ b/YoggieEngine/src/Platform/Windows/win32Window.cpp @@ -0,0 +1,46 @@ +#include "YoggieEngine.h" +#include "win32Window.h" +#include + + +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); + + + + } + +} + + diff --git a/YoggieEngine/src/Platform/Windows/win32Window.h b/YoggieEngine/src/Platform/Windows/win32Window.h new file mode 100644 index 0000000..f795b07 --- /dev/null +++ b/YoggieEngine/src/Platform/Windows/win32Window.h @@ -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; + + + }; + +} diff --git a/YoggieEngine/src/Platform/glfw/glfwWindow.cpp b/YoggieEngine/src/Platform/glfw/glfwWindow.cpp new file mode 100644 index 0000000..ef41f23 --- /dev/null +++ b/YoggieEngine/src/Platform/glfw/glfwWindow.cpp @@ -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); + } +} + diff --git a/YoggieEngine/src/Platform/glfw/glfwWindow.h b/YoggieEngine/src/Platform/glfw/glfwWindow.h new file mode 100644 index 0000000..59e2364 --- /dev/null +++ b/YoggieEngine/src/Platform/glfw/glfwWindow.h @@ -0,0 +1,29 @@ +#pragma once +#include +#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; + + + + }; +} \ No newline at end of file diff --git a/YoggieEngine/src/YoggieEngine.h b/YoggieEngine/src/YoggieEngine.h index b2faf11..d18cb2d 100644 --- a/YoggieEngine/src/YoggieEngine.h +++ b/YoggieEngine/src/YoggieEngine.h @@ -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" diff --git a/premake5.lua b/premake5.lua index 4814a9e..e5a7d75 100644 --- a/premake5.lua +++ b/premake5.lua @@ -16,6 +16,7 @@ workspace "Yoggie GameEngine" defines{ " _CRT_SECURE_NO_WARNINGS", + "GLFW_STATIC" } filter "configurations:Debug"