Graphics Refactor Initial

This commit is contained in:
IlyaShurupov 2024-03-19 11:21:58 +03:00
parent 87d8ce84dc
commit bb5cbfdfe2
14 changed files with 378 additions and 555 deletions

View 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];
};
}

View file

@ -1,119 +1,83 @@
#pragma once
#include "GraphicsCommon.hpp"
#include "Color.hpp"
#include "Rect.hpp"
// TODO : ugly
#include "Buffer.hpp"
namespace tp {
class Window;
class Graphics {
class DebugGUI {
class Context;
Context* mContext;
public:
class GL {
class Context;
Context* mContext;
explicit DebugGUI(Window* window);
~DebugGUI();
private:
friend Graphics;
friend Window;
GL();
~GL();
void init();
void deinit();
void proc();
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 Context;
Context* mContext;
private:
friend Graphics;
friend Window;
Canvas();
~Canvas();
void init();
void deinit();
void proc();
void draw();
public:
enum Align : int2 {
CC = 0x0000,
CT = 0x0001,
CB = 0x0002,
LC = 0x0100,
LT = 0x0101,
LB = 0x0102,
RC = 0x0200,
RT = 0x0201,
RB = 0x0202,
};
struct ImageHandle {
ualni id = 0;
};
RectF getAvaliableArea();
void pushClamp(const RectF& rec);
void popClamp();
void rect(const RectF& rec, const RGBA& col, halnf round = 0);
void text(const char*, const RectF&, halnf size, Align, halnf marging, const RGBA&);
ImageHandle createImageFromTextId(ualni id, Vec2F size);
void deleteImageHandle(ImageHandle image);
void drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding);
private:
halnf mWidth = 600;
halnf mHeight = 600;
Buffer<RectF> mScissors;
bool mIsClamping = false;
};
private:
friend Window;
Graphics() = default;
void init(Window* window);
void deinit();
void draw();
void proc();
void draw();
};
class Canvas {
class Context;
Context* mContext;
public:
explicit Canvas(Window* window);
~Canvas();
void proc();
void draw();
public:
enum Align : int2 {
CC = 0x0000,
CT = 0x0001,
CB = 0x0002,
LC = 0x0100,
LT = 0x0101,
LB = 0x0102,
RC = 0x0200,
RT = 0x0201,
RB = 0x0202,
};
struct ImageHandle {
ualni id = 0;
};
void pushClamp(const RectF& rec);
void popClamp();
void rect(const RectF& rec, const RGBA& col, halnf round = 0);
void text(const char*, const RectF&, halnf size, Align, halnf padding, const RGBA&);
ImageHandle createImageFromTextId(ualni id, Vec2F size);
void deleteImageHandle(ImageHandle image);
void drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding);
private:
Buffer<RectF> mScissors;
bool mIsClamping = false;
};
class Graphics {
private:
explicit Graphics(Window* window) : mGui(window), mCanvas(window) {}
void proc() {
mCanvas.proc();
mGui.proc();
}
void draw() {
mCanvas.draw();
mGui.draw();
}
private:
GUI mGui;
GL mGl;
Canvas mCanvas;
DebugGUI mGui;
};
}

View file

@ -1,11 +0,0 @@
#pragma once
#include "Color.hpp"
#include "Rect.hpp"
#include "Timing.hpp"
#include "Allocators.hpp"
namespace tp {
extern ModuleManifest gModuleGraphics;
}

View file

@ -2,10 +2,7 @@
#pragma once
namespace tp {
// basically copy of glfw keys
enum class Keycode {
enum class InputID : ualni {
/* Printable keys */
SPACE = 32,
APOSTROPHE = 39, /* ' */
@ -145,22 +142,7 @@ namespace tp {
MOUSE5 = 505,
MOUSE_UP = 506,
MOUSE_DOWN = 507,
};
enum class KeyState {
PRESSED,
RELEASED,
HOLD,
REPEAT,
NONE,
LAST_KEY_CODE = 508,
};
struct KeyEvent {
Keycode code;
enum class EventState {
RELEASED = 0,
PRESSED = 1,
REPEAT = 2,
} event_state;
};
};
}

View file

@ -1,62 +1,38 @@
#pragma once
// TODO : fix this ugly shit
#include "Buffer.hpp"
#include "Graphics.hpp"
#include "Keycodes.hpp"
#include "EventHandler.hpp"
#include "Strings.hpp"
namespace tp {
extern ModuleManifest gModuleGraphics;
class Window {
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:
friend Window;
Buffer<Event> mQueu;
Context* mContext;
};
private:
Window(int width, int height, const char* title);
Window(Vec2F size, const String& title);
~Window();
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);
public:
void draw();
void processEvents();
void setEventHandler(EventHandler* eventHandler);
[[nodiscard]] EventHandler* getEventHandler();
Context* getContext();
[[nodiscard]] bool shouldClose() const;
auto getContext() -> Context*;
Graphics::Canvas& getCanvas();
const Events& getEvents();
[[nodiscard]] const Vec2F& getSize() const;
private:
Vec2F mSize;
Context* mContext;
Graphics mGraphics;
Events mEvents;
EventHandler* mEventHandler = nullptr;
};
}