Program Listing for File GLFWWindow.cpp¶
↰ Return to documentation for file (Source\Azura\RenderSystem\Src\Generic\GLFWWindow.cpp
)
// Don't include GLFW's non-sense. We include what we need.
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include "Generic/GLFWWindow.h"
namespace Azura {
namespace {
float GetUpdateRateDelta(UpdateRate rate) {
switch (rate) {
case UpdateRate::RateUnlocked:
return 0.0f;
case UpdateRate::Rate240:
return 1.0f / 240.0f;
case UpdateRate::Rate120:
return 1.0f / 120.0f;
case UpdateRate::Rate60:
return 1.0f / 60.0f;
case UpdateRate::Rate30:
return 1.0f / 30.0f;
default:
return 0.0f;
}
}
KeyboardKey GetKey(int key) {
switch (key) {
case GLFW_KEY_W:
return KeyboardKey::W;
case GLFW_KEY_A:
return KeyboardKey::A;
case GLFW_KEY_S:
return KeyboardKey::S;
case GLFW_KEY_D:
return KeyboardKey::D;
case GLFW_KEY_R:
return KeyboardKey::R;
case GLFW_KEY_T:
return KeyboardKey::T;
case GLFW_KEY_Q:
return KeyboardKey::Q;
case GLFW_KEY_E:
return KeyboardKey::E;
case GLFW_KEY_Y:
return KeyboardKey::Y;
case GLFW_KEY_U:
return KeyboardKey::U;
case GLFW_KEY_I:
return KeyboardKey::I;
case GLFW_KEY_ESCAPE:
return KeyboardKey::Esc;
case GLFW_KEY_UP:
return KeyboardKey::Up;
case GLFW_KEY_DOWN:
return KeyboardKey::Down;
case GLFW_KEY_RIGHT:
return KeyboardKey::Right;
case GLFW_KEY_LEFT:
return KeyboardKey::Left;
default:
return KeyboardKey::Unmapped;
}
}
} // namespace
GLFWWindow::GLFWWindow(String title, U32 width, U32 height)
: Window(title, width, height),
p_window(nullptr) {
}
bool GLFWWindow::Initialize() {
if (glfwInit() == GLFW_FALSE) {
return false;
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
p_window = glfwCreateWindow(GetWidth(), GetHeight(), GetTitle(), nullptr, nullptr);
glfwSetMouseButtonCallback(p_window, MouseEventCallback);
glfwSetKeyCallback(p_window, KeyPressCallback);
glfwSetWindowUserPointer(p_window, this);
return true;
}
void GLFWWindow::Destroy() {
glfwDestroyWindow(p_window);
glfwTerminate();
}
void GLFWWindow::StartListening() {
int frameCount{0};
double previousStatsTime = glfwGetTime();
double previousFrameTime = glfwGetTime();
const float rateDelta = GetUpdateRateDelta(m_rate);
// TODO(vasumahesh1):[GAME]: Need a Performance Timer here
while (glfwWindowShouldClose(p_window) == GLFW_FALSE) {
const double currentTime = glfwGetTime();
double currCursorX;
double currCursorY;
glfwGetCursorPos(p_window, &currCursorX, &currCursorY);
MouseEvent mouseEvent = {};
mouseEvent.m_internalType = MouseEventType::MouseUpdate;
mouseEvent.m_eventX = float(currCursorX);
mouseEvent.m_eventY = float(currCursorY);
CallMouseEventFunction(mouseEvent);
if (m_mouseLeftDown) {
const double diffX = currCursorX - m_prevCursorX;
const double diffY = currCursorY - m_prevCursorY;
if (diffX > 0.001 || diffY > 0.001) {
MouseEvent evt = {};
evt.m_internalType = MouseEventType::Drag;
evt.m_eventX = float(diffX);
evt.m_eventY = float(diffY);
CallMouseEventFunction(evt);
}
m_prevCursorX = currCursorX;
m_prevCursorY = currCursorY;
}
const auto timeDelta = float(currentTime - previousFrameTime);
const bool shouldTick = m_rate == UpdateRate::RateUnlocked || (timeDelta > rateDelta);
if (shouldTick) {
CallUpdateFunction(timeDelta);
frameCount++;
previousFrameTime = currentTime;
}
const double statsTimeDelta = currentTime - previousStatsTime;
if (statsTimeDelta >= 1.0) {
String windowTitle = String(GetTitle()) + " - FPS: " + std::to_string(frameCount) + " - Frame Time: " + std::
to_string(1000.0 / frameCount) + "ms";
glfwSetWindowTitle(p_window, windowTitle.c_str());
frameCount = 0;
previousStatsTime = currentTime;
}
glfwPollEvents();
}
}
void GLFWWindow::ResetCursor() {
glfwSetCursorPos(p_window, m_midWidth, m_midHeight);
}
GLFWwindow* GLFWWindow::GetGLFWHandle() const {
return p_window;
}
void GLFWWindow::KeyPressCallback(GLFWwindow* window, int key, int scanCode, int action, int mods) {
UNUSED(mods);
UNUSED(scanCode);
GLFWWindow* wrapper = reinterpret_cast<GLFWWindow*>(glfwGetWindowUserPointer(window)); // NOLINT
if (action == GLFW_PRESS) {
wrapper->CallKeyEventFunction(KeyEvent(key, GetKey(key), KeyEventType::KeyPress));
} else if (action == GLFW_RELEASE) {
wrapper->CallKeyEventFunction(KeyEvent(key, GetKey(key), KeyEventType::KeyRelease));
}
}
void GLFWWindow::SetCursorState(CursorState state) {
switch (state) {
case CursorState::Visible:
glfwSetInputMode(p_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
break;
case CursorState::Hidden:
glfwSetInputMode(p_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
break;
case CursorState::Disabled:
glfwSetInputMode(p_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
break;
default:
break;
}
}
void GLFWWindow::MouseEventCallback(GLFWwindow* window, int button, int action, int mods) {
UNUSED(mods);
GLFWWindow* wrapper = reinterpret_cast<GLFWWindow*>(glfwGetWindowUserPointer(window)); // NOLINT
if (button == GLFW_MOUSE_BUTTON_LEFT) {
if (GLFW_PRESS == action) {
wrapper->m_mouseLeftDown = true;
glfwGetCursorPos(window, &(wrapper->m_prevCursorX), &(wrapper->m_prevCursorY));
} else if (GLFW_RELEASE == action) {
wrapper->m_mouseLeftDown = false;
}
}
}
} // namespace Azura