Graphics Refactor Initial
This commit is contained in:
parent
87d8ce84dc
commit
bb5cbfdfe2
14 changed files with 378 additions and 555 deletions
|
|
@ -5,7 +5,7 @@ set(BINDINGS_INCLUDE ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
|
||||||
set(BINDINGS_LIBS glfw Imgui Nanovg ${GLEW_LIB})
|
set(BINDINGS_LIBS glfw Imgui Nanovg ${GLEW_LIB})
|
||||||
|
|
||||||
### ---------------------- Static Library --------------------- ###
|
### ---------------------- Static Library --------------------- ###
|
||||||
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
|
file(GLOB SOURCES "./private/*.cpp")
|
||||||
file(GLOB HEADERS "./public/*.hpp")
|
file(GLOB HEADERS "./public/*.hpp")
|
||||||
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
|
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
|
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
|
||||||
|
|
|
||||||
|
|
@ -12,31 +12,32 @@
|
||||||
#include <nanovg_gl.h>
|
#include <nanovg_gl.h>
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
class Graphics::Canvas::Context {
|
class Canvas::Context {
|
||||||
public:
|
public:
|
||||||
NVGcontext* vg;
|
NVGcontext* vg {};
|
||||||
|
Window* window {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
Graphics::Canvas::Canvas() { mContext = new Context(); }
|
Canvas::Canvas(Window* window) {
|
||||||
|
mContext = new Context();
|
||||||
|
mContext->window = window;
|
||||||
|
|
||||||
Graphics::Canvas::~Canvas() { delete mContext; }
|
|
||||||
|
|
||||||
void Graphics::Canvas::init() {
|
|
||||||
mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
|
mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
|
||||||
|
|
||||||
if (nvgCreateFont(mContext->vg, "default", "Font.ttf") == -1) {
|
if (nvgCreateFont(mContext->vg, "default", "Font.ttf") == -1) {
|
||||||
// TODO
|
ASSERT(!"Cant create NVG font")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::deinit() { nvgDeleteGL3(mContext->vg); }
|
Canvas::~Canvas() {
|
||||||
|
nvgDeleteGL3(mContext->vg);
|
||||||
|
delete mContext;
|
||||||
|
}
|
||||||
|
|
||||||
RectF Graphics::Canvas::getAvaliableArea() { return { (halnf) 0, (halnf) 0, mWidth, mHeight }; }
|
void Canvas::rect(const RectF& rec, const RGBA& col, halnf round) {
|
||||||
|
|
||||||
void Graphics::Canvas::rect(const RectF& rec, const RGBA& col, halnf round) {
|
|
||||||
nvgBeginPath(mContext->vg);
|
nvgBeginPath(mContext->vg);
|
||||||
|
|
||||||
if (round == 0) {
|
if (round == 0) {
|
||||||
|
|
@ -49,7 +50,7 @@ void Graphics::Canvas::rect(const RectF& rec, const RGBA& col, halnf round) {
|
||||||
nvgFill(mContext->vg);
|
nvgFill(mContext->vg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::pushClamp(const RectF& rec) {
|
void Canvas::pushClamp(const RectF& rec) {
|
||||||
RectF intersection = rec;
|
RectF intersection = rec;
|
||||||
if (mScissors.size()) {
|
if (mScissors.size()) {
|
||||||
mScissors.last().calcIntersection(rec, intersection);
|
mScissors.last().calcIntersection(rec, intersection);
|
||||||
|
|
@ -58,7 +59,7 @@ void Graphics::Canvas::pushClamp(const RectF& rec) {
|
||||||
mScissors.append(rec);
|
mScissors.append(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::popClamp() {
|
void Canvas::popClamp() {
|
||||||
DEBUG_ASSERT(mScissors.size());
|
DEBUG_ASSERT(mScissors.size());
|
||||||
mIsClamping = false;
|
mIsClamping = false;
|
||||||
mScissors.pop();
|
mScissors.pop();
|
||||||
|
|
@ -70,7 +71,7 @@ void Graphics::Canvas::popClamp() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::text(
|
void Canvas::text(
|
||||||
const char* string, const RectF& aRec, halnf size, Align align, halnf marging, const RGBA& col
|
const char* string, const RectF& aRec, halnf size, Align align, halnf marging, const RGBA& col
|
||||||
) {
|
) {
|
||||||
RectF rec = { aRec.x + marging, aRec.y + marging, aRec.z - marging * 2, aRec.w - marging * 2 };
|
RectF rec = { aRec.x + marging, aRec.y + marging, aRec.z - marging * 2, aRec.w - marging * 2 };
|
||||||
|
|
@ -112,7 +113,7 @@ void Graphics::Canvas::text(
|
||||||
popClamp();
|
popClamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding) {
|
void Canvas::drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding) {
|
||||||
auto imgPaint = nvgImagePattern(mContext->vg, rec.x, rec.y, rec.z, rec.w, angle, image->id, alpha);
|
auto imgPaint = nvgImagePattern(mContext->vg, rec.x, rec.y, rec.z, rec.w, angle, image->id, alpha);
|
||||||
nvgBeginPath(mContext->vg);
|
nvgBeginPath(mContext->vg);
|
||||||
nvgRoundedRect(mContext->vg, rec.x, rec.y, rec.z, rec.w, rounding);
|
nvgRoundedRect(mContext->vg, rec.x, rec.y, rec.z, rec.w, rounding);
|
||||||
|
|
@ -120,7 +121,7 @@ void Graphics::Canvas::drawImage(const RectF& rec, ImageHandle* image, halnf ang
|
||||||
nvgFill(mContext->vg);
|
nvgFill(mContext->vg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Canvas::ImageHandle Graphics::Canvas::createImageFromTextId(ualni id, Vec2F size) {
|
Canvas::ImageHandle Canvas::createImageFromTextId(ualni id, Vec2F size) {
|
||||||
#ifdef ENV_OS_ANDROID
|
#ifdef ENV_OS_ANDROID
|
||||||
return { (ualni) nvglCreateImageFromHandleGLES3(mContext->vg, id, size.x, size.y, 0) };
|
return { (ualni) nvglCreateImageFromHandleGLES3(mContext->vg, id, size.x, size.y, 0) };
|
||||||
#else
|
#else
|
||||||
|
|
@ -128,12 +129,17 @@ void Graphics::Canvas::drawImage(const RectF& rec, ImageHandle* image, halnf ang
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::deleteImageHandle(ImageHandle image) {
|
void Canvas::deleteImageHandle(ImageHandle image) {
|
||||||
if (image.id) {
|
if (image.id) {
|
||||||
nvgDeleteImage(mContext->vg, image.id);
|
nvgDeleteImage(mContext->vg, image.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::proc() { nvgBeginFrame(mContext->vg, mWidth, mHeight, 1.0); }
|
void Canvas::proc() {
|
||||||
|
const auto size = mContext->window->getSize();
|
||||||
|
nvgBeginFrame(mContext->vg, size.x, size.y, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::Canvas::draw() { nvgEndFrame(mContext->vg); }
|
void Canvas::draw() {
|
||||||
|
nvgEndFrame(mContext->vg);
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
#include "Window.hpp"
|
#include "Window.hpp"
|
||||||
|
|
||||||
#include "WindowContext.hpp"
|
#include "WindowContext.hpp"
|
||||||
|
|
||||||
|
#include "Graphics.hpp"
|
||||||
|
|
||||||
// -------- Debug UI -------- //
|
// -------- Debug UI -------- //
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <imgui_impl_glfw.h>
|
#include <imgui_impl_glfw.h>
|
||||||
|
|
@ -9,7 +10,7 @@
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
class Graphics::GUI::Context {
|
class DebugGUI::Context {
|
||||||
public:
|
public:
|
||||||
ImGuiIO* io{};
|
ImGuiIO* io{};
|
||||||
ImGuiContext* ctx{};
|
ImGuiContext* ctx{};
|
||||||
|
|
@ -18,11 +19,9 @@ namespace tp {
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
Graphics::GUI::GUI() { mContext = new Context(); }
|
DebugGUI::DebugGUI(Window* window) {
|
||||||
|
mContext = new Context();
|
||||||
|
|
||||||
Graphics::GUI::~GUI() { delete mContext; }
|
|
||||||
|
|
||||||
void Graphics::GUI::init(Window* window) {
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
mContext->ctx = ImGui::CreateContext();
|
mContext->ctx = ImGui::CreateContext();
|
||||||
mContext->io = &ImGui::GetIO();
|
mContext->io = &ImGui::GetIO();
|
||||||
|
|
@ -38,13 +37,15 @@ void Graphics::GUI::init(Window* window) {
|
||||||
io.Fonts->AddFontFromFileTTF("Font.ttf", 20.f);
|
io.Fonts->AddFontFromFileTTF("Font.ttf", 20.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::GUI::deinit() {
|
DebugGUI::~DebugGUI() {
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
delete mContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::GUI::proc() {
|
void DebugGUI::proc() {
|
||||||
tp::HeapAllocGlobal::startIgnore();
|
tp::HeapAllocGlobal::startIgnore();
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
|
@ -54,7 +55,7 @@ void Graphics::GUI::proc() {
|
||||||
tp::HeapAllocGlobal::stopIgnore();
|
tp::HeapAllocGlobal::stopIgnore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::GUI::draw() {
|
void DebugGUI::draw() {
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
2
Graphics/private/EventHandler.cpp
Normal file
2
Graphics/private/EventHandler.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
#include "EventHandler.hpp"
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#include "GraphicsCommon.hpp"
|
|
||||||
#include "MathCommon.hpp"
|
|
||||||
|
|
||||||
namespace tp {
|
|
||||||
static ModuleManifest* deps[] = { &gModuleAllocators, nullptr };
|
|
||||||
ModuleManifest gModuleGraphics = ModuleManifest("Graphics", nullptr, nullptr, deps);
|
|
||||||
}
|
|
||||||
151
Graphics/private/Window.cpp
Normal file
151
Graphics/private/Window.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
#include "Window.hpp"
|
||||||
|
#include "WindowContext.hpp"
|
||||||
|
|
||||||
|
// -------- OpenGL -------- //
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
// -------- Window Context -------- //
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#ifdef ENV_OS_WINDOWS
|
||||||
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENV_OS_LINUX
|
||||||
|
#define GLFW_EXPOSE_NATIVE_WAYLAND
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <GLFW/glfw3native.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
static ModuleManifest* deps[] = { &gModuleAllocators, nullptr };
|
||||||
|
ModuleManifest gModuleGraphics = ModuleManifest("Graphics", nullptr, nullptr, deps);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace tp;
|
||||||
|
|
||||||
|
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||||
|
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
|
||||||
|
static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset);
|
||||||
|
|
||||||
|
Window::Window(Vec2F size, const String& title) {
|
||||||
|
mContext = new Context();
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1);
|
||||||
|
|
||||||
|
// Create a window and OpenGL context
|
||||||
|
mContext->window = glfwCreateWindow((int) size.x, (int) size.y, title.read(), nullptr, nullptr);
|
||||||
|
if (!mContext->window) {
|
||||||
|
printf("Failed to create GLFW window\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(mContext->window);
|
||||||
|
|
||||||
|
// Initialize GLEW
|
||||||
|
if (glewInit() != GLEW_OK) {
|
||||||
|
printf("Failed to initialize GLEW\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set event bindings
|
||||||
|
glfwSetWindowUserPointer(mContext->window, this);
|
||||||
|
glfwSetKeyCallback(mContext->window, keyCallback);
|
||||||
|
glfwSetMouseButtonCallback(mContext->window, mouseButtonCallback);
|
||||||
|
glfwSetScrollCallback(mContext->window, scrollCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::~Window() {
|
||||||
|
glfwDestroyWindow(mContext->window);
|
||||||
|
delete mContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window* Window::createWindow(Vec2F size, const String& title) {
|
||||||
|
HeapAllocGlobal::startIgnore();
|
||||||
|
|
||||||
|
static int count = 1;
|
||||||
|
if (!count) {
|
||||||
|
printf("Window class is a singleton\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
count--;
|
||||||
|
|
||||||
|
// Initialize GLFW
|
||||||
|
if (!glfwInit()) {
|
||||||
|
printf("Failed to initialize GLFW\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the GLFW error callback
|
||||||
|
glfwSetErrorCallback([](int error, const char* description) { printf("GLFW Error: %i %s\n", error, description); });
|
||||||
|
|
||||||
|
auto out = new Window(size, title);
|
||||||
|
|
||||||
|
HeapAllocGlobal::stopIgnore();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::destroyWindow(Window* window) {
|
||||||
|
delete window;
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window); }
|
||||||
|
|
||||||
|
void Window::processEvents() {
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
glfwGetWindowSize(mContext->window, &w, &h);
|
||||||
|
mSize = { (halnf) w, (halnf) h };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::draw() {
|
||||||
|
glfwSwapBuffers(mContext->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vec2F& Window::getSize() const { return mSize; }
|
||||||
|
|
||||||
|
Window::Context* Window::getContext() { return mContext; }
|
||||||
|
|
||||||
|
void Window::setEventHandler(EventHandler* eventHandler) { mEventHandler = eventHandler; }
|
||||||
|
EventHandler* Window::getEventHandler() { return mEventHandler; }
|
||||||
|
|
||||||
|
|
||||||
|
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||||
|
|
||||||
|
auto* self = static_cast<Window*>(glfwGetWindowUserPointer(window));
|
||||||
|
if (!self) return;
|
||||||
|
|
||||||
|
EventHandler* eventHandler = self->getEventHandler();
|
||||||
|
if (!eventHandler) return;
|
||||||
|
|
||||||
|
// post key event
|
||||||
|
/*
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
inputManager->keyStates[key] = GLFW_PRESS;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
inputManager->keyStates[key] = GLFW_RELEASE;
|
||||||
|
}
|
||||||
|
inputManager->isEvent = true;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {
|
||||||
|
auto* self = static_cast<Window*>(glfwGetWindowUserPointer(window));
|
||||||
|
if (!self) return;
|
||||||
|
|
||||||
|
EventHandler* eventHandler = self->getEventHandler();
|
||||||
|
if (!eventHandler) return;
|
||||||
|
|
||||||
|
// post mouse button event
|
||||||
|
// inputManager->mouseButtonStates[button] = action;
|
||||||
|
// inputManager->isEvent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {
|
||||||
|
// ignore for now
|
||||||
|
}
|
||||||
14
Graphics/private/WindowContext.hpp
Normal file
14
Graphics/private/WindowContext.hpp
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Window.hpp"
|
||||||
|
|
||||||
|
class GLFWwindow;
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
|
||||||
|
class Window::Context {
|
||||||
|
public:
|
||||||
|
Context() = default;
|
||||||
|
GLFWwindow* window = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,215 +0,0 @@
|
||||||
#include "Window.hpp"
|
|
||||||
|
|
||||||
// -------- OpenGL -------- //
|
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
#include "WindowContext.hpp"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
// #define EASYTAB_IMPLEMENTATION
|
|
||||||
// #include "easytab.h"
|
|
||||||
|
|
||||||
namespace tp {
|
|
||||||
class Graphics::GL::Context {
|
|
||||||
public:
|
|
||||||
// Showoff data
|
|
||||||
GLuint vao{};
|
|
||||||
GLuint vbo{};
|
|
||||||
GLfloat vertices[9] = {
|
|
||||||
-0.0f, -0.0f, 0.0f, // Left vertex
|
|
||||||
1.0f, 0.0f, 0.0f, // Right vertex
|
|
||||||
0.5f, 1.0f, 0.0f // Top vertex
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace tp;
|
|
||||||
|
|
||||||
Graphics::GL::GL() { mContext = new Context(); }
|
|
||||||
|
|
||||||
Graphics::GL::~GL() { delete mContext; }
|
|
||||||
|
|
||||||
void Graphics::GL::init() {
|
|
||||||
// Create a Vertex Array Object (VAO)
|
|
||||||
glGenVertexArrays(1, &mContext->vao);
|
|
||||||
glBindVertexArray(mContext->vao);
|
|
||||||
|
|
||||||
// Create a Vertex Buffer Object (VBO)
|
|
||||||
glGenBuffers(1, &mContext->vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mContext->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(mContext->vertices), mContext->vertices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// Set up vertex attributes
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*) nullptr);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::GL::deinit() {
|
|
||||||
glDeleteBuffers(1, &mContext->vbo);
|
|
||||||
glDeleteVertexArrays(1, &mContext->vao);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::GL::proc() {}
|
|
||||||
|
|
||||||
void Graphics::GL::draw() {
|
|
||||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
|
||||||
glViewport(0, 0, mWidth, mHeight);
|
|
||||||
// glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::init(Window* window) {
|
|
||||||
mGl.init();
|
|
||||||
mGui.init(window);
|
|
||||||
mCanvas.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::deinit() {
|
|
||||||
mCanvas.deinit();
|
|
||||||
mGui.deinit();
|
|
||||||
mGl.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::proc() {
|
|
||||||
mGl.proc();
|
|
||||||
mCanvas.proc();
|
|
||||||
mGui.proc();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::draw() {
|
|
||||||
mGl.draw();
|
|
||||||
mCanvas.draw();
|
|
||||||
mGui.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
tp::Window::Window(int width, int height, const char* title) {
|
|
||||||
mContext = new Context();
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1);
|
|
||||||
|
|
||||||
// Create a window and OpenGL context
|
|
||||||
mContext->window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
|
||||||
if (!mContext->window) {
|
|
||||||
printf("Failed to create GLFW window\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(mContext->window);
|
|
||||||
|
|
||||||
// Initialize GLEW
|
|
||||||
if (glewInit() != GLEW_OK) {
|
|
||||||
printf("Failed to initialize GLEW\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mContext->inputManager.init(mContext->window);
|
|
||||||
|
|
||||||
mGraphics.init(this);
|
|
||||||
|
|
||||||
mEvents.mContext = mContext;
|
|
||||||
|
|
||||||
#ifdef ENV_OS_WINDOWS
|
|
||||||
// EasyTab_Load(glfwGetWin32Window(mContext->window));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
tp::Window::~Window() {
|
|
||||||
#ifdef ENV_OS_WINDOWS
|
|
||||||
// EasyTab_Unload();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mGraphics.deinit();
|
|
||||||
glfwDestroyWindow(mContext->window);
|
|
||||||
delete mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp::Window* tp::Window::createWindow(int width, int height, const char* title) {
|
|
||||||
tp::HeapAllocGlobal::startIgnore();
|
|
||||||
|
|
||||||
static int count = 1;
|
|
||||||
if (!count) {
|
|
||||||
printf("Window class is a singleton\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
|
|
||||||
// Initialize GLFW
|
|
||||||
if (!glfwInit()) {
|
|
||||||
printf("Failed to initialize GLFW\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the GLFW error callback
|
|
||||||
glfwSetErrorCallback([](int error, const char* description) { printf("GLFW Error: %i %s\n", error, description); });
|
|
||||||
|
|
||||||
auto out = new Window(width, height, title);
|
|
||||||
|
|
||||||
tp::HeapAllocGlobal::stopIgnore();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tp::Window::destroyWindow(Window* window) {
|
|
||||||
delete window;
|
|
||||||
glfwTerminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tp::Window::shouldClose() const { return glfwWindowShouldClose(mContext->window); }
|
|
||||||
|
|
||||||
void tp::Window::processEvents() {
|
|
||||||
mContext->inputManager.isEvent = false;
|
|
||||||
|
|
||||||
#ifdef ENV_OS_WINDOWS
|
|
||||||
// HWND w32window = glfwGetWin32Window(mContext->window);
|
|
||||||
// MSG msg;
|
|
||||||
// if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
|
||||||
// if (EasyTab_HandleEvent(msg.hwnd, msg.message, msg.lParam, msg.wParam) == EASYTAB_OK)
|
|
||||||
// mEvents.pressure = EasyTab->Pressure;
|
|
||||||
// }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
int w, h;
|
|
||||||
glfwGetWindowSize(mContext->window, &w, &h);
|
|
||||||
|
|
||||||
mGraphics.mCanvas.mWidth = w;
|
|
||||||
mGraphics.mCanvas.mHeight = h;
|
|
||||||
|
|
||||||
mGraphics.mGl.mWidth = w;
|
|
||||||
mGraphics.mGl.mHeight = h;
|
|
||||||
|
|
||||||
mGraphics.proc();
|
|
||||||
|
|
||||||
mContext->inputManager.update();
|
|
||||||
|
|
||||||
if (mEvents.isPressed()) {
|
|
||||||
mEvents.pressure = 1.f;
|
|
||||||
} else if (mEvents.isReleased()) {
|
|
||||||
mEvents.pressure = 0.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
void tp::Window::draw() {
|
|
||||||
mGraphics.draw();
|
|
||||||
glfwSwapBuffers(mContext->window);
|
|
||||||
mContext->inputManager.resetScroll();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto tp::Window::getContext() -> Context* { return mContext; }
|
|
||||||
Graphics::Canvas& tp::Window::getCanvas() { return mGraphics.mCanvas; }
|
|
||||||
const tp::Window::Events& tp::Window::getEvents() { return mEvents; }
|
|
||||||
|
|
||||||
const Vec2F& tp::Window::Events::getPos() const { return mContext->inputManager.getPos(); }
|
|
||||||
|
|
||||||
bool tp::Window::Events::isPressed() const { return mContext->inputManager.isPressed(); }
|
|
||||||
|
|
||||||
bool tp::Window::Events::isReleased() const { return mContext->inputManager.isReleased(); }
|
|
||||||
|
|
||||||
bool tp::Window::Events::isDown() const { return mContext->inputManager.isDown(); }
|
|
||||||
|
|
||||||
halnf tp::Window::Events::getScrollY() const { return mContext->inputManager.getScrollY(); }
|
|
||||||
|
|
||||||
bool tp::Window::Events::isEvent() const { return mContext->inputManager.isEvents(); }
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Environment.hpp"
|
|
||||||
|
|
||||||
// -------- Window Context -------- //
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#ifdef ENV_OS_WINDOWS
|
|
||||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENV_OS_LINUX
|
|
||||||
#define GLFW_EXPOSE_NATIVE_WAYLAND
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <GLFW/glfw3native.h>
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace tp {
|
|
||||||
|
|
||||||
class Window;
|
|
||||||
|
|
||||||
class InputManager {
|
|
||||||
public:
|
|
||||||
InputManager() = default;
|
|
||||||
|
|
||||||
void init(GLFWwindow* aWindow) {
|
|
||||||
window = aWindow;
|
|
||||||
// Set up key and mouse button callbacks
|
|
||||||
|
|
||||||
glfwSetWindowUserPointer(window, this);
|
|
||||||
glfwSetKeyCallback(window, keyCallback);
|
|
||||||
glfwSetMouseButtonCallback(window, mouseButtonCallback);
|
|
||||||
glfwSetScrollCallback(window, scrollCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2F& getPos() const { return mousePos; }
|
|
||||||
|
|
||||||
bool isKeyPressed(int key) const { return keyStates[key] == GLFW_PRESS; }
|
|
||||||
|
|
||||||
bool isKeyDown(int key) const { return keyStates[key] == GLFW_REPEAT || keyStates[key] == GLFW_PRESS; }
|
|
||||||
|
|
||||||
bool isPressed() const { return mouseButtonStates[GLFW_MOUSE_BUTTON_LEFT] == GLFW_PRESS; }
|
|
||||||
|
|
||||||
bool isReleased() const { return mouseButtonStates[GLFW_MOUSE_BUTTON_LEFT] == GLFW_RELEASE; }
|
|
||||||
|
|
||||||
bool isDown() const { return mouseButtonStates[GLFW_MOUSE_BUTTON_LEFT] == GLFW_REPEAT || mouseButtonStates[GLFW_MOUSE_BUTTON_LEFT] == GLFW_PRESS; }
|
|
||||||
|
|
||||||
bool isEvents() const { return isEvent; }
|
|
||||||
|
|
||||||
double getScrollY() const { return scrollY; }
|
|
||||||
|
|
||||||
// bool isScrollDown() const { return scrollY < 0.0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend Window;
|
|
||||||
|
|
||||||
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
InputManager* inputManager = static_cast<InputManager*>(glfwGetWindowUserPointer(window));
|
|
||||||
|
|
||||||
if (!inputManager) {
|
|
||||||
// Update key state
|
|
||||||
if (action == GLFW_PRESS) {
|
|
||||||
inputManager->keyStates[key] = GLFW_PRESS;
|
|
||||||
} else if (action == GLFW_RELEASE) {
|
|
||||||
inputManager->keyStates[key] = GLFW_RELEASE;
|
|
||||||
}
|
|
||||||
inputManager->isEvent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {
|
|
||||||
InputManager* inputManager = static_cast<InputManager*>(glfwGetWindowUserPointer(window));
|
|
||||||
|
|
||||||
if (inputManager) {
|
|
||||||
// Update mouse button state
|
|
||||||
inputManager->mouseButtonStates[button] = action;
|
|
||||||
inputManager->isEvent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) {
|
|
||||||
InputManager* inputManager = static_cast<InputManager*>(glfwGetWindowUserPointer(window));
|
|
||||||
|
|
||||||
if (inputManager) {
|
|
||||||
// Update scroll state
|
|
||||||
inputManager->scrollX = xoffset;
|
|
||||||
inputManager->scrollY = yoffset;
|
|
||||||
inputManager->isEvent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
|
||||||
double x, y;
|
|
||||||
glfwGetCursorPos(window, &x, &y);
|
|
||||||
mousePosPrev = mousePos;
|
|
||||||
mousePos = { x, y };
|
|
||||||
|
|
||||||
if ((mousePosPrev - mousePos).length2()) {
|
|
||||||
isEvent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetScroll() {
|
|
||||||
scrollX = 0.0;
|
|
||||||
scrollY = 0.0;
|
|
||||||
mouseButtonStates[GLFW_MOUSE_BUTTON_LEFT] = GLFW_REPEAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEvent = false;
|
|
||||||
double scrollX = 0.0;
|
|
||||||
double scrollY = 0.0;
|
|
||||||
GLFWwindow* window;
|
|
||||||
Vec2F mousePos;
|
|
||||||
Vec2F mousePosPrev;
|
|
||||||
std::array<int, GLFW_KEY_LAST + 1> keyStates = { GLFW_RELEASE };
|
|
||||||
std::array<int, GLFW_MOUSE_BUTTON_LAST + 1> mouseButtonStates = { GLFW_RELEASE };
|
|
||||||
};
|
|
||||||
|
|
||||||
class Window::Context {
|
|
||||||
friend Graphics::GL;
|
|
||||||
friend Graphics::GUI;
|
|
||||||
friend Graphics::Canvas;
|
|
||||||
|
|
||||||
public:
|
|
||||||
GLFWwindow* window;
|
|
||||||
InputManager inputManager;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
90
Graphics/public/EventHandler.hpp
Normal file
90
Graphics/public/EventHandler.hpp
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "InputCodes.hpp"
|
||||||
|
#include "Vec.hpp"
|
||||||
|
#include "List.hpp"
|
||||||
|
#include "Map.hpp"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
|
||||||
|
struct InputEvent {
|
||||||
|
enum class Type {
|
||||||
|
NONE,
|
||||||
|
BUTTON_ACTION,
|
||||||
|
MOUSE_DELTA,
|
||||||
|
MOUSE_POS,
|
||||||
|
} type = Type::NONE;
|
||||||
|
|
||||||
|
enum class ButtonAction {
|
||||||
|
NONE,
|
||||||
|
PRESS,
|
||||||
|
RELEASE,
|
||||||
|
REPEAT,
|
||||||
|
} buttonAction = ButtonAction::NONE;
|
||||||
|
|
||||||
|
Vec2F mouseEvent = { 0, 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputState {
|
||||||
|
// Transitions from state to state is strict and defined by state order in the enum
|
||||||
|
// If posted event conflicts with that automata, we need to emulate intermediate states
|
||||||
|
enum State {
|
||||||
|
NONE, // Button is inactive
|
||||||
|
PRESSED, // Button is pressed
|
||||||
|
HOLD, // Button is still pressed
|
||||||
|
RELEASED, // Button is released
|
||||||
|
};
|
||||||
|
|
||||||
|
State mCurrentState;
|
||||||
|
State mPreviousState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InputState() = default;
|
||||||
|
|
||||||
|
void handleEvent(const InputEvent& event);
|
||||||
|
|
||||||
|
bool isStateChanged();
|
||||||
|
|
||||||
|
// true if event is no longer needed and false if we need to emulate some transitions further
|
||||||
|
bool isHandled();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assumes that user and event poster use different threads
|
||||||
|
// User can add own states for each input and decide how this state changes on specific events
|
||||||
|
// Event posters has no access to any custom state and only report any changes in any way
|
||||||
|
class EventHandler {
|
||||||
|
public:
|
||||||
|
EventHandler() = default;
|
||||||
|
~EventHandler();
|
||||||
|
|
||||||
|
public: // Event Poster Interface
|
||||||
|
void postEvent(InputID inputID, InputEvent inputEvent); // Record event
|
||||||
|
|
||||||
|
public: // User interface
|
||||||
|
bool isEvents();
|
||||||
|
void processEvent();
|
||||||
|
|
||||||
|
const Vec2F& getPointer() const;
|
||||||
|
|
||||||
|
bool isPressed(InputID id) const;
|
||||||
|
bool isReleased(InputID id) const;
|
||||||
|
bool isDown(InputID id) const;
|
||||||
|
|
||||||
|
halnf getScrollY() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mMutex = {};
|
||||||
|
|
||||||
|
// Store thread protected queue of posted events
|
||||||
|
List<InputEvent> mEventQueue;
|
||||||
|
|
||||||
|
// input states
|
||||||
|
Vec2F mPointer;
|
||||||
|
halnf pressure = 0;
|
||||||
|
|
||||||
|
InputState mInputStates[(int) InputID::LAST_KEY_CODE];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,70 +1,33 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GraphicsCommon.hpp"
|
#include "Color.hpp"
|
||||||
|
#include "Rect.hpp"
|
||||||
|
|
||||||
// TODO : ugly
|
#include "Buffer.hpp"
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
class Window;
|
class Window;
|
||||||
|
|
||||||
class Graphics {
|
class DebugGUI {
|
||||||
public:
|
|
||||||
class GL {
|
|
||||||
class Context;
|
class Context;
|
||||||
Context* mContext;
|
Context* mContext;
|
||||||
|
|
||||||
private:
|
public:
|
||||||
friend Graphics;
|
explicit DebugGUI(Window* window);
|
||||||
friend Window;
|
~DebugGUI();
|
||||||
|
|
||||||
GL();
|
|
||||||
~GL();
|
|
||||||
|
|
||||||
void init();
|
|
||||||
void deinit();
|
|
||||||
void proc();
|
void proc();
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
public:
|
|
||||||
// TODO : API
|
|
||||||
|
|
||||||
private:
|
|
||||||
halnf mWidth = 100;
|
|
||||||
halnf mHeight = 100;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GUI {
|
|
||||||
class Context;
|
|
||||||
Context* mContext;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend Graphics;
|
|
||||||
|
|
||||||
GUI();
|
|
||||||
~GUI();
|
|
||||||
|
|
||||||
void init(Window* window);
|
|
||||||
void deinit();
|
|
||||||
void proc();
|
|
||||||
void draw();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// TODO : API
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Canvas {
|
class Canvas {
|
||||||
class Context;
|
class Context;
|
||||||
Context* mContext;
|
Context* mContext;
|
||||||
|
|
||||||
private:
|
public:
|
||||||
friend Graphics;
|
explicit Canvas(Window* window);
|
||||||
friend Window;
|
|
||||||
|
|
||||||
Canvas();
|
|
||||||
~Canvas();
|
~Canvas();
|
||||||
|
|
||||||
void init();
|
|
||||||
void deinit();
|
|
||||||
void proc();
|
void proc();
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
|
|
@ -85,35 +48,36 @@ namespace tp {
|
||||||
ualni id = 0;
|
ualni id = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
RectF getAvaliableArea();
|
|
||||||
void pushClamp(const RectF& rec);
|
void pushClamp(const RectF& rec);
|
||||||
void popClamp();
|
void popClamp();
|
||||||
void rect(const RectF& rec, const RGBA& col, halnf round = 0);
|
void rect(const RectF& rec, const RGBA& col, halnf round = 0);
|
||||||
void text(const char*, const RectF&, halnf size, Align, halnf marging, const RGBA&);
|
void text(const char*, const RectF&, halnf size, Align, halnf padding, const RGBA&);
|
||||||
|
|
||||||
ImageHandle createImageFromTextId(ualni id, Vec2F size);
|
ImageHandle createImageFromTextId(ualni id, Vec2F size);
|
||||||
void deleteImageHandle(ImageHandle image);
|
void deleteImageHandle(ImageHandle image);
|
||||||
void drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding);
|
void drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
halnf mWidth = 600;
|
|
||||||
halnf mHeight = 600;
|
|
||||||
Buffer<RectF> mScissors;
|
Buffer<RectF> mScissors;
|
||||||
bool mIsClamping = false;
|
bool mIsClamping = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Graphics {
|
||||||
private:
|
private:
|
||||||
friend Window;
|
explicit Graphics(Window* window) : mGui(window), mCanvas(window) {}
|
||||||
|
|
||||||
Graphics() = default;
|
void proc() {
|
||||||
void init(Window* window);
|
mCanvas.proc();
|
||||||
void deinit();
|
mGui.proc();
|
||||||
void draw();
|
}
|
||||||
void proc();
|
|
||||||
|
void draw() {
|
||||||
|
mCanvas.draw();
|
||||||
|
mGui.draw();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GUI mGui;
|
|
||||||
GL mGl;
|
|
||||||
Canvas mCanvas;
|
Canvas mCanvas;
|
||||||
|
DebugGUI mGui;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Color.hpp"
|
|
||||||
#include "Rect.hpp"
|
|
||||||
#include "Timing.hpp"
|
|
||||||
|
|
||||||
#include "Allocators.hpp"
|
|
||||||
|
|
||||||
namespace tp {
|
|
||||||
extern ModuleManifest gModuleGraphics;
|
|
||||||
}
|
|
||||||
|
|
@ -2,10 +2,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
|
enum class InputID : ualni {
|
||||||
// basically copy of glfw keys
|
|
||||||
enum class Keycode {
|
|
||||||
|
|
||||||
/* Printable keys */
|
/* Printable keys */
|
||||||
SPACE = 32,
|
SPACE = 32,
|
||||||
APOSTROPHE = 39, /* ' */
|
APOSTROPHE = 39, /* ' */
|
||||||
|
|
@ -145,22 +142,7 @@ namespace tp {
|
||||||
MOUSE5 = 505,
|
MOUSE5 = 505,
|
||||||
MOUSE_UP = 506,
|
MOUSE_UP = 506,
|
||||||
MOUSE_DOWN = 507,
|
MOUSE_DOWN = 507,
|
||||||
};
|
|
||||||
|
|
||||||
enum class KeyState {
|
LAST_KEY_CODE = 508,
|
||||||
PRESSED,
|
|
||||||
RELEASED,
|
|
||||||
HOLD,
|
|
||||||
REPEAT,
|
|
||||||
NONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct KeyEvent {
|
|
||||||
Keycode code;
|
|
||||||
enum class EventState {
|
|
||||||
RELEASED = 0,
|
|
||||||
PRESSED = 1,
|
|
||||||
REPEAT = 2,
|
|
||||||
} event_state;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,62 +1,38 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// TODO : fix this ugly shit
|
|
||||||
|
|
||||||
#include "Buffer.hpp"
|
#include "Buffer.hpp"
|
||||||
#include "Graphics.hpp"
|
#include "EventHandler.hpp"
|
||||||
#include "Keycodes.hpp"
|
#include "Strings.hpp"
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
|
|
||||||
|
extern ModuleManifest gModuleGraphics;
|
||||||
|
|
||||||
class Window {
|
class Window {
|
||||||
class Context;
|
class Context;
|
||||||
|
|
||||||
public:
|
|
||||||
struct Event {
|
|
||||||
enum Type {
|
|
||||||
KEY,
|
|
||||||
MOUSE,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Events {
|
|
||||||
Vec2F mPointer;
|
|
||||||
halnf pressure = 0;
|
|
||||||
|
|
||||||
const Vec2F& getPos() const;
|
|
||||||
bool isPressed() const;
|
|
||||||
bool isReleased() const;
|
|
||||||
bool isDown() const;
|
|
||||||
halnf getScrollY() const;
|
|
||||||
bool isEvent() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend Window;
|
Window(Vec2F size, const String& title);
|
||||||
Buffer<Event> mQueu;
|
|
||||||
Context* mContext;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
Window(int width, int height, const char* title);
|
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Window* createWindow(int width, int height, const char* title);
|
static Window* createWindow(Vec2F size = { 1000.f, 900.f }, const String& title = "Window");
|
||||||
static void destroyWindow(Window* window);
|
static void destroyWindow(Window* window);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void draw();
|
void draw();
|
||||||
void processEvents();
|
void processEvents();
|
||||||
|
|
||||||
|
void setEventHandler(EventHandler* eventHandler);
|
||||||
|
[[nodiscard]] EventHandler* getEventHandler();
|
||||||
|
|
||||||
|
Context* getContext();
|
||||||
[[nodiscard]] bool shouldClose() const;
|
[[nodiscard]] bool shouldClose() const;
|
||||||
|
[[nodiscard]] const Vec2F& getSize() const;
|
||||||
auto getContext() -> Context*;
|
|
||||||
|
|
||||||
Graphics::Canvas& getCanvas();
|
|
||||||
const Events& getEvents();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Vec2F mSize;
|
||||||
Context* mContext;
|
Context* mContext;
|
||||||
Graphics mGraphics;
|
EventHandler* mEventHandler = nullptr;
|
||||||
Events mEvents;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue