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

View File

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

View File

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

View File

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

View File

@ -17,10 +17,10 @@ namespace YoggieEngine {
void init_inputSystem(NativeWindow* window) { void init_inputSystem(NativeWindow* window) {
cursor_pos_x = 0; cursor_pos_x = 0;
cursor_pos_y = 0; cursor_pos_y = 0;
glfwSetKeyCallback(window->GetGLFWHandle(), key_callback); glfwSetKeyCallback((GLFWwindow*) window->GetHandle(), key_callback);
glfwSetMouseButtonCallback(window->GetGLFWHandle(), mouseButton_callback); glfwSetMouseButtonCallback((GLFWwindow*)window->GetHandle(), mouseButton_callback);
glfwSetCursorPosCallback(window->GetGLFWHandle(), cursorPos_callback); glfwSetCursorPosCallback((GLFWwindow*)window->GetHandle(), cursorPos_callback);
glfwSetCursorEnterCallback(window->GetGLFWHandle(), cursorEnter_callback); glfwSetCursorEnterCallback((GLFWwindow*)window->GetHandle(), cursorEnter_callback);
} }
void ReceiveInput() { void ReceiveInput() {
@ -43,13 +43,13 @@ namespace YoggieEngine {
double getCursorPosX(NativeWindow* window) double getCursorPosX(NativeWindow* window)
{ {
glfwGetCursorPos(window->GetGLFWHandle(), &cursor_pos_x, nullptr); glfwGetCursorPos((GLFWwindow*)window->GetHandle(), &cursor_pos_x, nullptr);
return cursor_pos_x; return cursor_pos_x;
} }
double getCursorPosY(NativeWindow* window) double getCursorPosY(NativeWindow* window)
{ {
glfwGetCursorPos(window->GetGLFWHandle(), nullptr, &cursor_pos_y); glfwGetCursorPos((GLFWwindow*)window->GetHandle(), nullptr, &cursor_pos_y);
return 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 #pragma once
#define GLFW_STATIC
#include <iostream>
#include <GLFW/glfw3.h>
#include "../EventSystem/Event.h" #include "../EventSystem/Event.h"
#include "../EventSystem/EventListener.h" #include "../EventSystem/EventListener.h"
namespace YoggieEngine { namespace YoggieEngine {
class NativeWindow { class NativeWindow {
public: public:
NativeWindow(const int width, const int height); NativeWindow() { spdlog::debug("NativeWindow Constructor called!"); }
~NativeWindow(); 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); const int getWidth()const { return m_width; }
void Poll(); const int getHeight()const { return m_height; }
void SwapBuffers();
GLFWwindow* GetGLFWHandle() { return window; } virtual void* GetHandle() { return m_handle; }
const int getWidth()const { return Width; }
const int getHeight()const { return Height; }
private: protected:
GLFWwindow* window; virtual void SetContext() {}
bool FullScreen = false;
bool Resizable = true;
bool VSync = false;
int Width, Height;
void SetContext(); bool m_fullscreen = false;
static bool InitGLFW(); 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 // Main library stuff
#include "Platform/Platform.h"
#include "Platform/Window.h"
#include "Graphics/Primitives/Mesh.h" #include "Graphics/Primitives/Mesh.h"
#include "Graphics/Primitives/Shader.h" #include "Graphics/Primitives/Shader.h"

View File

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