mirror of
https://github.com/gwm17/Specter.git
synced 2025-04-18 05:48:52 -04:00
180 lines
4.7 KiB
C++
180 lines
4.7 KiB
C++
/*
|
|
OpenGLWindow.h
|
|
Implementation of a window with OpenGL context. Not really OpenGL specific, other than in creation of GraphicsContext.
|
|
Bulk of creation can be used in any api/context (glfw compatible with Cocoa, X11, or Windows). Based entirely upon the
|
|
work of @TheCherno in his game engine series.
|
|
|
|
GWM -- Feb 2022
|
|
*/
|
|
#include "OpenGLWindow.h"
|
|
#include "OpenGLContext.h"
|
|
#include "Navigator/Core/NavCore.h"
|
|
#include "Navigator/Events/AppEvent.h"
|
|
#include "Navigator/Events/KeyEvent.h"
|
|
#include "Navigator/Events/MouseEvent.h"
|
|
|
|
namespace Navigator {
|
|
|
|
static bool s_glfwInitialized = false;
|
|
static void GLFWErrorCallback(int error, const char* description)
|
|
{
|
|
NAV_ERROR("GLFW Error Code {0}: {1}", error, description);
|
|
}
|
|
|
|
Window* Window::Create(const WindowProperties& props) { return new OpenGLWindow(props); }
|
|
|
|
OpenGLWindow::OpenGLWindow(const WindowProperties& props)
|
|
{
|
|
Init(props);
|
|
}
|
|
|
|
OpenGLWindow::~OpenGLWindow()
|
|
{
|
|
Shutdown();
|
|
}
|
|
|
|
void OpenGLWindow::Init(const WindowProperties& props)
|
|
{
|
|
m_data.width = props.width;
|
|
m_data.height = props.height;
|
|
m_data.name = props.name;
|
|
|
|
NAV_INFO("Creating OpenGLWindow with height {0} width {1} and name {2}", m_data.height, m_data.width, m_data.name);
|
|
|
|
if(!s_glfwInitialized)
|
|
{
|
|
int passed = glfwInit();
|
|
NAV_INFO("Initializing GLFW ... Returned value {0}", passed);
|
|
glfwSetErrorCallback(GLFWErrorCallback);
|
|
}
|
|
|
|
//Apple specific. OpenGL is technically deprecated, so a little extra work to force the correct version
|
|
#ifdef __APPLE__
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,true);
|
|
#endif
|
|
|
|
m_window = glfwCreateWindow((int)m_data.width, (int)m_data.height, m_data.name.c_str(), nullptr, nullptr);
|
|
|
|
m_context = new OpenGLContext(m_window); //This is the only seriously OpenGL specific code
|
|
m_context->Init();
|
|
|
|
glfwSetWindowUserPointer(m_window, &m_data);
|
|
SetVSync(true);
|
|
|
|
//Set all of the callback functions for the window.
|
|
glfwSetWindowSizeCallback(m_window, [](GLFWwindow* window, int width, int height)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
data.width = width;
|
|
data.height = height;
|
|
WindowResizeEvent event(width, height);
|
|
data.event_callback_func(event);
|
|
});
|
|
|
|
glfwSetWindowCloseCallback(m_window, [](GLFWwindow* window)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
WindowCloseEvent event;
|
|
data.event_callback_func(event);
|
|
});
|
|
|
|
glfwSetKeyCallback(m_window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
switch(action)
|
|
{
|
|
case GLFW_PRESS:
|
|
{
|
|
KeyPressedEvent event(key, 0);
|
|
data.event_callback_func(event);
|
|
break;
|
|
}
|
|
case GLFW_RELEASE:
|
|
{
|
|
KeyReleasedEvent event(key);
|
|
data.event_callback_func(event);
|
|
break;
|
|
}
|
|
case GLFW_REPEAT:
|
|
{
|
|
//GLFW doesnt have a hold count, so here we just pass 1 to indicate a hold is happening.
|
|
KeyPressedEvent event(key, 1);
|
|
data.event_callback_func(event);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
glfwSetCharCallback(m_window, [](GLFWwindow* window, unsigned int character)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
KeyTypedEvent event(character);
|
|
data.event_callback_func(event);
|
|
});
|
|
|
|
glfwSetMouseButtonCallback(m_window, [](GLFWwindow* window, int button, int action, int mods)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
switch(action)
|
|
{
|
|
case GLFW_PRESS:
|
|
{
|
|
MouseButtonPressedEvent event(button);
|
|
data.event_callback_func(event);
|
|
}
|
|
case GLFW_RELEASE:
|
|
{
|
|
MouseButtonReleasedEvent event(button);
|
|
data.event_callback_func(event);
|
|
}
|
|
}
|
|
});
|
|
|
|
glfwSetScrollCallback(m_window, [](GLFWwindow* window, double xoffset, double yoffset)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
MouseScrolledEvent event((float)xoffset, (float)yoffset);
|
|
data.event_callback_func(event);
|
|
});
|
|
|
|
glfwSetCursorPosCallback(m_window, [](GLFWwindow* window, double xpos, double ypos)
|
|
{
|
|
Data& data = *(Data*) glfwGetWindowUserPointer(window);
|
|
MouseMovedEvent event((float)xpos, (float)ypos);
|
|
data.event_callback_func(event);
|
|
});
|
|
}
|
|
|
|
void OpenGLWindow::Shutdown()
|
|
{
|
|
glfwDestroyWindow(m_window);
|
|
}
|
|
|
|
void OpenGLWindow::OnUpdate()
|
|
{
|
|
glfwPollEvents();
|
|
m_context->SwapBuffers();
|
|
}
|
|
|
|
void OpenGLWindow::SetVSync(bool enabled)
|
|
{
|
|
if(enabled)
|
|
{
|
|
glfwSwapInterval(1);
|
|
}
|
|
else
|
|
{
|
|
glfwSwapInterval(0);
|
|
}
|
|
m_data.vsyncFlag = enabled;
|
|
}
|
|
|
|
bool OpenGLWindow::IsVSync() const
|
|
{
|
|
return m_data.vsyncFlag;
|
|
}
|
|
}
|