Skip to content

Instantly share code, notes, and snippets.

@Pikachuxxxx
Created August 22, 2021 13:07
Show Gist options
  • Save Pikachuxxxx/5b54c2c0558526e5ec672fb2f3d876d8 to your computer and use it in GitHub Desktop.
Save Pikachuxxxx/5b54c2c0558526e5ec672fb2f3d876d8 to your computer and use it in GitHub Desktop.
A ready to use GLFW Window with input management and other utilities
#include "Window.h"
Window::Window(const char *title, int width, int height) : backgroundColor(glm::vec4(0, 0, 0, 1))
{
m_Title = title;
m_Width = width;
m_Height = height;
if(!init())
glfwTerminate();
for(int i = 0; i < MAX_KEYS ; i++)
{
m_HeldKeys[i] = false;
m_PressedKeys[i] = false;
m_ReleasedKeys[i] = false;
}
for(int i = 0; i < MAX_BUTTONS ; i++)
{
m_HeldMouseButtons[i] = false;
}
firstMouse = true;
lastMouseX = width / 2;
lastMouseY = height / 2;
}
Window::~Window()
{
glfwTerminate();
}
bool Window::init()
{
glfwSetErrorCallback(glfw_initialisation_error);
if(!glfwInit())
return false;
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
// Create the window
m_Window = glfwCreateWindow(m_Width, m_Height, m_Title, NULL, NULL);
if(!m_Window)
{
glfwTerminate();
std::cerr << "ERROR::GLFW::Could not initialise GLFW Window" << '\n';
return false;
}
glfwSetWindowUserPointer(m_Window, this);
// Window Callback Functions
glfwSetFramebufferSizeCallback(m_Window, window_resize_callback);
glfwSetKeyCallback(m_Window, key_callback);
glfwSetMouseButtonCallback(m_Window, mouse_button_callback);
glfwSetCursorPosCallback(m_Window, mouse_position_callback);
return true;
}
bool Window::isKeyPressed(unsigned int keycode)
{
if (keycode >= MAX_KEYS)
return false;
bool result = m_PressedKeys[keycode];
m_PressedKeys[keycode] = false;
return result;
}
bool Window::isKeyReleased(unsigned int keycode)
{
if (keycode >= MAX_KEYS)
return false;
bool result = m_ReleasedKeys[keycode];
m_ReleasedKeys[keycode] = false;
return result;
}
bool Window::isKeyHeld(unsigned int keycode) const
{
// TODO: Log this
if (keycode >= MAX_KEYS)
return false;
return m_HeldKeys[keycode];
}
bool Window::isMouseButtonPressed(unsigned int button)
{
if (button >= MAX_BUTTONS)
return false;
bool result = m_PressedMouseButtons[button];
m_PressedMouseButtons[button] = false;
return result;
}
bool Window::isMouseButtonReleased(unsigned int button)
{
if (button >= MAX_BUTTONS)
return false;
bool result = m_ReleasedMouseButtons[button];
m_ReleasedMouseButtons[button] = false;
return result;
}
bool Window::isMouseButtonHeld(unsigned int button) const
{
// TODO: Log this
if (button >= MAX_BUTTONS)
return false;
return m_HeldMouseButtons[button];
}
void Window::getMousePosition(double& x, double& y) const
{
x = m_MouseX;
y = m_MouseY;
}
bool Window::closed() const
{
return glfwWindowShouldClose(m_Window) == 1;
}
void Window::Update() const
{
glfwPollEvents();
}
void glfw_initialisation_error(int error, const char* description)
{
std::cerr << "ERROR::GLFW::" << error << "::DESCRIPTION::" << description << std::endl;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
Window* wind = (Window *) glfwGetWindowUserPointer(window);
wind->m_ReleasedKeys[key] = ((action == GLFW_RELEASE) && wind->m_HeldKeys[key]);
wind->m_HeldKeys[key] = action != GLFW_RELEASE;
if(!wind->m_PressedKeys[key])
wind->m_PressedKeys[key] = (action == GLFW_PRESS);
// Window closing
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
std::cout << "Escape Key Pressed..." << "Quiting..." <<'\n';
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
void window_resize_callback(GLFWwindow* window, int width, int height)
{
Window* wind = (Window *) glfwGetWindowUserPointer(window);
wind->m_Width = width;
wind->m_Height = height;
wind->m_IsResized = true;
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
Window* wind = (Window *) glfwGetWindowUserPointer(window);
wind->m_ReleasedMouseButtons[button] = ((action == GLFW_RELEASE) && wind->m_ReleasedMouseButtons[button]);
wind->m_HeldMouseButtons[button] = action != GLFW_RELEASE;
if (!wind->m_PressedMouseButtons[button])
wind->m_PressedMouseButtons[button] = action == GLFW_PRESS;
}
void mouse_position_callback(GLFWwindow* window, double xpos, double ypos)
{
Window* wind = (Window *) glfwGetWindowUserPointer(window);
wind->m_MouseX = xpos;
wind->m_MouseY = ypos;
if (wind->firstMouse)
{
wind->lastMouseX = xpos;
wind->lastMouseY = ypos;
wind->firstMouse = false;
}
wind->deltaMouseX = xpos - wind->lastMouseX;
wind->deltaMouseY = wind->lastMouseY - ypos;
wind->lastMouseX = xpos;
wind->lastMouseY = ypos;
}
#pragma once
// STD. includes
#include <iostream>
// GLFW
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
// GLM
#include <glm/glm.hpp>
#define MAX_KEYS 1024
#define MAX_BUTTONS 32
static void glfw_initialisation_error(int error, const char* description);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void window_resize_callback(GLFWwindow* window, int width, int height);
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
static void mouse_position_callback(GLFWwindow* window, double xpos, double ypos);
/// The class responsible for Window Creation.
class Window
{
public:
/// The background color of the Window.
glm::vec4 backgroundColor;
float deltaMouseX, deltaMouseY;
mutable float deltaTime;
public:
Window(const char *title, int width, int height);
~Window();
/// Indicates the current state of the Window.
bool closed() const;
void Update() const;
/// Gets the current width of the window.
inline int getWidth() const { return m_Width; }
/// Gets the current height of the window.
inline int getHeight() const { return m_Height; }
/// Gets the current window's pointer to it's native object.
inline GLFWwindow* getGLFWwindow() const { return m_Window; }
bool IsResized() {return m_IsResized; }
void SetResizedFalse() { m_IsResized = false; }
/// Tells if a particular key on the keyboard was pressed or not.
bool isKeyPressed(unsigned int keycode);
/// Tells if a particular key on the keyboard was released or not.
bool isKeyReleased(unsigned int keycode);
/// Tells if a particular key on the keyboard is being held or not.
bool isKeyHeld(unsigned int keycode) const;
/// Tells if a particular key on the Mouse button was pressed or not.
bool isMouseButtonPressed(unsigned int button);
// TODO: To be implemented
bool isMouseButtonReleased(unsigned int button);
/// Tells if a particular key on the Mouse button is being held or not.
bool isMouseButtonHeld(unsigned int button) const;
/// Gets the current position of the mouse in Screen Space Coordinates.
void getMousePosition(double& x, double& y) const;
private:
const char* m_Title;
int m_Width, m_Height;
GLFWwindow* m_Window;
bool m_Closed;
bool m_IsResized;
bool m_HeldKeys[MAX_KEYS];
bool m_PressedKeys[MAX_KEYS];
bool m_ReleasedKeys[MAX_KEYS];
bool m_HeldMouseButtons[MAX_BUTTONS];
bool m_PressedMouseButtons[MAX_BUTTONS];
bool m_ReleasedMouseButtons[MAX_BUTTONS];
double m_MouseX;
double m_MouseY;
bool firstMouse;
float lastMouseX, lastMouseY;
mutable float m_LastTime;
private :
bool init();
friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
friend void window_resize_callback(GLFWwindow* window, int width, int height);
friend void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
friend void mouse_position_callback(GLFWwindow* window, double xpos, double ypos);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment