From fec99fc737e36727747df0ce368831d534656cfd Mon Sep 17 00:00:00 2001 From: Nathan Date: Wed, 18 Feb 2026 23:07:53 -0600 Subject: [PATCH] render obj file --- src/ArchimedesCore/Archimedes.cpp | 11 + src/ArchimedesCore/pch.cpp | 1 + src/ArchimedesCore/utils/App/App.cpp | 285 ++++++++++++++++++ src/ArchimedesCore/utils/Audio/Audio.cpp | 51 ++++ .../Audio/AudioImpl/AudioSDL3/AudioSDL3.cpp | 0 .../utils/Events/BasicEvents.cpp | 88 ++++++ src/ArchimedesCore/utils/Events/Event.cpp | 25 ++ .../utils/Events/NetworkEvents.cpp | 59 ++++ src/ArchimedesCore/utils/Module/Module.cpp | 48 +++ src/ArchimedesCore/utils/Objects/Body.cpp | 32 ++ src/ArchimedesCore/utils/Objects/Camera.cpp | 25 ++ src/ArchimedesCore/utils/Objects/Object.cpp | 75 +++++ .../utils/Renderer/RenderTarget.cpp | 194 ++++++++++++ .../utils/Renderer/Renderer.cpp | 67 ++++ .../RendererOpenGL/RendererOpenGL.cpp | 268 ++++++++++++++++ .../RendererSDL3/RendererSDL3.cpp | 43 +++ src/ArchimedesCore/utils/Window/Window.cpp | 66 ++++ .../utils/Window/WindowEvents.cpp | 220 ++++++++++++++ .../WindowImpl/WindowGLFW/WindowGLFW.cpp | 146 +++++++++ .../WindowImpl/WindowSDL3/WindowSDL3.cpp | 161 ++++++++++ src/include/utils/Objects/Body.h | 8 +- src/include/utils/Objects/Camera.h | 2 +- src/include/utils/Objects/Object.h | 52 +++- src/include/utils/Renderer/RenderTarget.h | 25 +- src/include/utils/Renderer/Renderer.h | 9 +- .../RendererOpenGL/RendererOpenGL.h | 19 +- src/include/utils/Renderer/concepts.h | 21 -- src/include/utils/Window/concepts.h | 25 -- .../Archimedes-Modules/Sandbox/JObject.h | 121 +++++++- .../Archimedes-Modules/Sandbox/Sandbox.cpp | 140 ++++----- .../Archimedes-Modules/Sandbox/Sandbox.h | 21 +- 31 files changed, 2138 insertions(+), 170 deletions(-) create mode 100644 src/ArchimedesCore/Archimedes.cpp create mode 100644 src/ArchimedesCore/pch.cpp create mode 100644 src/ArchimedesCore/utils/App/App.cpp create mode 100644 src/ArchimedesCore/utils/Audio/Audio.cpp create mode 100644 src/ArchimedesCore/utils/Audio/AudioImpl/AudioSDL3/AudioSDL3.cpp create mode 100644 src/ArchimedesCore/utils/Events/BasicEvents.cpp create mode 100644 src/ArchimedesCore/utils/Events/Event.cpp create mode 100644 src/ArchimedesCore/utils/Events/NetworkEvents.cpp create mode 100644 src/ArchimedesCore/utils/Module/Module.cpp create mode 100644 src/ArchimedesCore/utils/Objects/Body.cpp create mode 100644 src/ArchimedesCore/utils/Objects/Camera.cpp create mode 100644 src/ArchimedesCore/utils/Objects/Object.cpp create mode 100644 src/ArchimedesCore/utils/Renderer/RenderTarget.cpp create mode 100644 src/ArchimedesCore/utils/Renderer/Renderer.cpp create mode 100644 src/ArchimedesCore/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.cpp create mode 100644 src/ArchimedesCore/utils/Renderer/RendererImpl/RendererSDL3/RendererSDL3.cpp create mode 100644 src/ArchimedesCore/utils/Window/Window.cpp create mode 100644 src/ArchimedesCore/utils/Window/WindowEvents.cpp create mode 100644 src/ArchimedesCore/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.cpp create mode 100644 src/ArchimedesCore/utils/Window/WindowImpl/WindowSDL3/WindowSDL3.cpp delete mode 100644 src/include/utils/Renderer/concepts.h delete mode 100644 src/include/utils/Window/concepts.h diff --git a/src/ArchimedesCore/Archimedes.cpp b/src/ArchimedesCore/Archimedes.cpp new file mode 100644 index 0000000..55f7e7b --- /dev/null +++ b/src/ArchimedesCore/Archimedes.cpp @@ -0,0 +1,11 @@ +#ifndef ARCHIMEDES_H +#define ARCHIMEDES_H + +#include "utils/Module/Module.h" +#include "utils/App/App.h" + +#include "utils/Events/Event.h" + +#include "entryPoint.h" + +#endif diff --git a/src/ArchimedesCore/pch.cpp b/src/ArchimedesCore/pch.cpp new file mode 100644 index 0000000..3854579 --- /dev/null +++ b/src/ArchimedesCore/pch.cpp @@ -0,0 +1 @@ +#include "pch.hpp" diff --git a/src/ArchimedesCore/utils/App/App.cpp b/src/ArchimedesCore/utils/App/App.cpp new file mode 100644 index 0000000..79eb210 --- /dev/null +++ b/src/ArchimedesCore/utils/App/App.cpp @@ -0,0 +1,285 @@ +#ifndef APP_H +#define APP_H + +#include "pch.hpp" +#include "utils/Module/Module.h" +#include "utils/Events/Event.h" + +namespace Archimedes { + + class App { + + public: + App() { + if(instance != nullptr) { + std::cout << "App already exists\nThere can only be one!\n"; + std::abort(); + } + instance = this; + roInsert = runOrder.begin(); + + registerEvent(AnonymousEvent()); + + registerEvent(DoLoadModuleEvent()); + registerEvent(DoUnloadModuleEvent()); + + registerEvent(LoadModuleEvent()); + registerEvent(UnloadModuleEvent()); + } + + virtual ~App() { + + unregisterEvent(AnonymousEvent()); + + unregisterEvent(DoLoadModuleEvent()); + unregisterEvent(DoUnloadModuleEvent()); + + unregisterEvent(LoadModuleEvent()); + unregisterEvent(UnloadModuleEvent()); + + for(std::string s : runOrder) { + void* handle = modules[s]->getHandle(); + delete modules[s]; + if(handle) + dlclose(handle); + modules[s] = nullptr; + } + runOrder.clear(); + } + + + static App* Get() { return instance; } + + std::list getModuleNames() const { return runOrder; } + + virtual void handleArgs(const int&, char*[]) = 0; + + virtual void run() = 0; + + + void end() { done = true; } + + bool isDone() const { return done; } + + void emitEvent(Event* e) { events.push_back(e); } + + unsigned int getEventType(std::string event) { return eventTypes[event]; } + + void registerEvent(std::string type) { + //only add each type once + if(eventTypes.find(type) == eventTypes.end()) + eventTypes[type] = nextEventType++; + } + + void unregisterEvent(std::string type) { + //only erase registered types + auto it = eventTypes.find(type); + if(it != eventTypes.end()) + eventTypes.erase(it); + } + + private: + + std::list::iterator roInsert; + + inline static App* instance = nullptr; + + unsigned int nextEventType = 0; + protected: + + bool done = false; + + std::unordered_map modules; + std::unordered_map eventTypes; + + std::list events; + + std::list runOrder; + + std::list toClose; + std::list> toOpen; + + virtual void stopModule(std::string lib) { + //unload modules that depend on the one we are unloading + for(std::string s : runOrder) { + if(modules[s]->deps.find(lib) != modules[s]->deps.end()) { + stopModule(s); + } + } + toClose.push_back(lib); + } + + virtual void startModule(std::variant m) { toOpen.push_back(m); } + + virtual bool onEvent(const Event& event) = 0; + + void handleEvents() { + static bool handled; + + while(!events.empty()) { + + handled = false; + + for(auto it = runOrder.rbegin(); it != runOrder.rend(); it++) { + + handled = modules[*it]->onEvent(*events.front()); + + if(handled) { + Event* e = events.front(); + events.pop_front(); + delete e; + break; + } + } + + if(!handled) { + if(this->onEvent(*events.front())) { + Event* e = events.front(); + events.pop_front(); + delete e; + } else { + std::cout << "Error: Unhandled Event: " << (std::string) *events.front() << std::endl; + } + } + } + } + + virtual Module* dynamicLoad(std::string lib) { + + void* h = dlopen(lib.c_str(), RTLD_NOW); + + if(!h) { + std::cout << "could not open lib at: \"" << lib.c_str() << "\"\nError: " << dlerror() << std::endl; + return nullptr; + } + + Module::create_t* create = (Module::create_t*) dlsym(h, "create"); + char* err = dlerror(); + if(err) { + std::cout << "error finding create function in file: " << lib << std::endl; + std::cout << "dlerror(): " << err << std::endl; + return nullptr; + } + + return create(Get(), h); + } + + virtual Module* reload(std::string lib) { + + for(std::string s : runOrder) { + if(s == lib) { + return modules[lib]; + } + } + + return modules.find(lib) != modules.end() ? load(modules[lib]) : nullptr; + } + + virtual Module* load(std::string moduleNameOrPath) { + Module* m = dynamicLoad(moduleNameOrPath); + //return m != nullptr ? load(m) : reload(moduleNameOrPath); + return load(m); + } + + virtual Module* load(Module* m) { + + if(!m) { + return nullptr; + } + + void* h = m->getHandle(); + for(auto it = runOrder.begin(); it != runOrder.end(); it++) { + if(*it == static_cast(*m)) { + std::cout << "Module \"" << *it << "\" is already loaded!\n"; + delete m; + if(h) { + dlclose(h); + } + return modules[*it]; + } + } + + if(modules.find(*m) == modules.end()) + modules[*m] = m; + + for(auto it = runOrder.begin(); it != runOrder.end(); it++) { + + if(m->deps.find(*it) != m->deps.end()) { + m->moduleInstances[*it] = modules[*it]; + //modules should be located after their dependencies + if(std::distance(roInsert, it) <= 0) { + roInsert = ++it--; + } + } + } + + //insert temporarily to avoid circular dependencies + runOrder.insert(roInsert, *m); + + bool skip = false; + for(auto it : m->deps) { + for(auto s : runOrder) { + if(s == it.first) { + skip = true; + m->moduleInstances[s] = modules[s]; + } + } + + if(skip) + continue; + + if(std::holds_alternative(it.second)) + m->moduleInstances[it.first] = load(std::get(it.second)); + else + m->moduleInstances[it.first] = load(std::get(it.second)); + } + + //reinsert once final order has been reached + runOrder.remove(*m); + + runOrder.insert(roInsert, *m); + + emitEvent(new LoadModuleEvent(*m)); + + return m; + } + + virtual void unload(std::string name) { + + if(modules.find(name) == modules.end()) + return; + + Module* m = modules[name]; + void* h = m->getHandle(); + + modules[name] = nullptr; + modules.erase(name); + + runOrder.remove(name); + + if(h) { + //don't dlclose if other modules are still in runOrder! + bool closable = true; + for(auto s = runOrder.begin(); s != runOrder.end(); s++) { + if(modules[*s]->getHandle() == h) { + closable = false; + } + } + + delete m; + + if(closable) { + dlclose(h); + } + } + + emitEvent(new UnloadModuleEvent(name)); + } + + virtual void printHelp() = 0; + + }; + +} + +#endif diff --git a/src/ArchimedesCore/utils/Audio/Audio.cpp b/src/ArchimedesCore/utils/Audio/Audio.cpp new file mode 100644 index 0000000..983befb --- /dev/null +++ b/src/ArchimedesCore/utils/Audio/Audio.cpp @@ -0,0 +1,51 @@ +#ifndef AUDIO_H +#define AUDIO_H + +#include "pch.hpp" + +#include +#include + +namespace Archimedes { + + class Audio { + + public: + + Audio() { + if(!SDL_Init(SDL_INIT_AUDIO)) { + + std::abort(); + } + + pDevices = SDL_GetAudioPlaybackDevices(&pDeviceCount); + rDevices = SDL_GetAudioPlaybackDevices(&rDeviceCount); + } + + ~Audio() { + + for(SDL_AudioStream* s : streams) { + DestroyAudioStream(s); + } + + SDL_QuitSubsystem(SDL_INIT_AUDIO); + } + + + private: + + SDL_AudioDeviceID* pDevices; + + int pDeviceCount = 0; + + SDL_AudioDeviceID* rDevices; + + int rDeviceCount = 0; + + std::vector streams; + std::vector specs; + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Audio/AudioImpl/AudioSDL3/AudioSDL3.cpp b/src/ArchimedesCore/utils/Audio/AudioImpl/AudioSDL3/AudioSDL3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/ArchimedesCore/utils/Events/BasicEvents.cpp b/src/ArchimedesCore/utils/Events/BasicEvents.cpp new file mode 100644 index 0000000..516313a --- /dev/null +++ b/src/ArchimedesCore/utils/Events/BasicEvents.cpp @@ -0,0 +1,88 @@ +#ifndef BASICEVENTS_H +#define BASICEVENTS_H + +#include "Event.h" + +namespace Archimedes { + + class Module; + + class AnonymousEvent : public Event { + + public: + + AnonymousEvent() {} + + AnonymousEvent(std::any data) : Event(data) {} + + ~AnonymousEvent() {} + + operator std::string() const override { return "AnonymousEvent"; } + + }; + + class LoadModuleEvent : public Event { + + public: + + LoadModuleEvent() {} + + LoadModuleEvent(std::string n) : module(n) {} + + ~LoadModuleEvent() {} + + operator std::string() const override { return "LoadModuleEvent"; } + + std::string module; + + }; + + class DoLoadModuleEvent : public Event { + + public: + + DoLoadModuleEvent() {} + + DoLoadModuleEvent(std::variant n) : module(n) {} + + ~DoLoadModuleEvent() {} + + operator std::string() const override { return "DoLoadModuleEvent"; } + + std::variant module; + + }; + + class UnloadModuleEvent : public Event { + + public: + + UnloadModuleEvent() {} + + UnloadModuleEvent(std::string n) : module(n) {} + + ~UnloadModuleEvent() {} + + operator std::string() const override { return "UnloadModuleEvent"; } + + std::string module; + }; + + class DoUnloadModuleEvent : public Event { + + public: + + DoUnloadModuleEvent() {} + + DoUnloadModuleEvent(std::string n) : module(n) {} + + ~DoUnloadModuleEvent() {} + + operator std::string() const override { return "DoUnloadModuleEvent"; } + + std::string module; + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Events/Event.cpp b/src/ArchimedesCore/utils/Events/Event.cpp new file mode 100644 index 0000000..28d4747 --- /dev/null +++ b/src/ArchimedesCore/utils/Events/Event.cpp @@ -0,0 +1,25 @@ +#ifndef EVENT_H +#define EVENT_H + +#include "pch.hpp" + +namespace Archimedes { + + class Event { + + public: + + Event() {} + Event(std::any data) : userData(data) {} + + virtual ~Event() {} + + virtual operator std::string() const = 0; + + std::any userData; + }; +} + +#include "BasicEvents.h" + +#endif diff --git a/src/ArchimedesCore/utils/Events/NetworkEvents.cpp b/src/ArchimedesCore/utils/Events/NetworkEvents.cpp new file mode 100644 index 0000000..1438c7e --- /dev/null +++ b/src/ArchimedesCore/utils/Events/NetworkEvents.cpp @@ -0,0 +1,59 @@ +#ifndef NETWORKEVENTS_H +#define NETWORKEVENTS_H + +#include "Event.h" + +#include +#include + +namespace Archimedes { + + class DataRecievedEvent : public Event { + + public: + + DataRecievedEvent() : Event(nullptr), msg(nullptr) {} + + DataRecievedEvent(ISteamNetworkingMessage* m) : Event(nullptr), msg(m) {} + + ~DataRecievedEvent() { + if(msg) + msg->Release(); + } + + operator std::string() const override { return "DataRecievedEvent"; } + + ISteamNetworkingMessage* msg; + + }; + + class DataSentEvent : public Event { + + public: + + DataSentEvent() : Event(nullptr), msg(nullptr) {} + + DataSentEvent(const void* m, uint32 l) : Event(nullptr), msg(m), length(l) {} + + operator std::string() const override { return "DataSentEvent"; } + + const void* msg; + uint32 length; + }; + + class ConnectionStatusChangedEvent : public Event { + + public: + + ConnectionStatusChangedEvent() : Event(nullptr), info(nullptr) {} + + ConnectionStatusChangedEvent(SteamNetConnectionStatusChangedCallback_t* i) : Event(nullptr), info(i) {} + + operator std::string() const override { return "ConnectionStatusChangedEvent"; } + + SteamNetConnectionStatusChangedCallback_t* info; + }; + +} + +#endif diff --git a/src/ArchimedesCore/utils/Module/Module.cpp b/src/ArchimedesCore/utils/Module/Module.cpp new file mode 100644 index 0000000..cce4ad7 --- /dev/null +++ b/src/ArchimedesCore/utils/Module/Module.cpp @@ -0,0 +1,48 @@ +#ifndef MODULE_H +#define MODULE_H + +#include "pch.hpp" + +namespace Archimedes { + + class App; + + class Event; + + class Module { + + friend class App; + + public: + + typedef Module* create_t(App*, void*); + + Module(App* a, void* h) : app(a), handle(h) {} + + Module() : app(nullptr), handle(nullptr) {} + + virtual ~Module() {} + + virtual void run() {} + virtual bool onEvent(const Event& e) { return false; } + + virtual void onLoad() {} + virtual void onUnload() {} + + operator std::string() const { return name; } + void* getHandle() { return handle; } + + protected: + std::string name; + + App* app; + void* handle; + + std::unordered_map> deps; + std::unordered_map> exts; + std::unordered_map moduleInstances; + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Objects/Body.cpp b/src/ArchimedesCore/utils/Objects/Body.cpp new file mode 100644 index 0000000..1e843b1 --- /dev/null +++ b/src/ArchimedesCore/utils/Objects/Body.cpp @@ -0,0 +1,32 @@ +#ifndef BODY_H +#define BODY_H + +#include "pch.hpp" + +#include "extratools.h" + +#include "Object.h" + +namespace Archimedes { + + class Body : public Object { + + public: + Body(RenderTarget rt, glm::mat4 t = glm::mat4(1.0f)) : mesh(rt), Object(t) {}; + + Body(VertexBuffer vb, IndexArray ia, VertexLayout vl, Shader s, glm::mat4 t = glm::mat4(1.0f)) + : mesh(vb, ia, vl, s), Object(t) {} + + Body() : Object(glm::mat4(1.0f)) {} + + ~Body() {}; + + RenderTarget& getMesh() { return mesh; } + + private: + + RenderTarget mesh; + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Objects/Camera.cpp b/src/ArchimedesCore/utils/Objects/Camera.cpp new file mode 100644 index 0000000..ea21dd0 --- /dev/null +++ b/src/ArchimedesCore/utils/Objects/Camera.cpp @@ -0,0 +1,25 @@ +#ifndef CAMERA_H +#define CAMERA_H + +#include "pch.hpp" + +#include "extratools.h" + +#include "Object.h" + +namespace Archimedes { + + class Camera : public Object { + + public: + Camera() : Object(glm::mat4(1.0f)) {} + + Camera(glm::mat4 t) + : Object(t) {} + + ~Camera() {}; + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Objects/Object.cpp b/src/ArchimedesCore/utils/Objects/Object.cpp new file mode 100644 index 0000000..cfe3dd4 --- /dev/null +++ b/src/ArchimedesCore/utils/Objects/Object.cpp @@ -0,0 +1,75 @@ +#ifndef OBJECT_H +#define OBJECT_H + +#include "pch.hpp" + +#include "extratools.h" + +#include "utils/Renderer/RenderTarget.h" + +namespace Archimedes { + + class Object { + + public: + + Object(glm::mat4 t) + : worldTransform(t) {} + + ~Object() {}; + + ///scales an object absolutely + ///scale factors less than zero do nothing + void scaleTo(float s) { + if(s > 0) { + worldTransform = glm::scale(worldTransform, glm::vec3(s / scale)); + scale = s; + } + } + + void scaleRel(float s) { + scaleTo(scale * s); + } + + void scaleAdd(float s) { + scaleTo(scale + s); + } + + void moveTo(glm::vec3 pos) { + worldTransform = glm::translate(worldTransform, pos - position); + position = pos; + } + + void moveRel(glm::vec3 pos) { + moveTo(pos + position); + } + + void rotateTo(glm::vec3 angles) { + worldTransform = glm::rotate(worldTransform, angles.x - rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)); + worldTransform = glm::rotate(worldTransform, angles.y - rotation.y, glm::vec3(0.0f, 1.0f, 0.0f)); + worldTransform = glm::rotate(worldTransform, angles.z - rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)); + rotation = angles; + } + + void rotateRel(glm::vec3 angles) { + rotateTo(angles + rotation); + } + + glm::vec3& getPosition() { return position; } + glm::vec3& getRotation() { return rotation; } + float& getScale() { return scale; } + + const glm::mat4& getTransform() { return worldTransform; } + + private: + + glm::vec3 position = glm::vec3(0); + glm::vec3 rotation = glm::vec3(0); + float scale = 1.0f; + + glm::mat4 worldTransform = glm::mat4(1.0f); + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Renderer/RenderTarget.cpp b/src/ArchimedesCore/utils/Renderer/RenderTarget.cpp new file mode 100644 index 0000000..b434c47 --- /dev/null +++ b/src/ArchimedesCore/utils/Renderer/RenderTarget.cpp @@ -0,0 +1,194 @@ +#ifndef RENDERTARGET_H +#define RENDERTARGET_H + +#include "pch.hpp" + +#include "extratools.h" + +namespace Archimedes { + + class LayoutElement { + + public: + LayoutElement(unsigned int type, size_t count) : type(type), count(count) {} + + ~LayoutElement() {} + + unsigned int getType() const { return type; } + + size_t getSize() const { return size; } + + size_t getCount() const { return count; } + private: + + unsigned int type; + size_t size; + size_t count; + }; + + class VertexLayout { + + public: + VertexLayout() {} + ~VertexLayout() {} + + const std::vector& getElements() const { return elements; } + + private: + std::vector elements; + }; + + class VertexBuffer { + + public: + VertexBuffer(const void* data, size_t size) : data(data), size(size) { + } + + VertexBuffer() {} + + ~VertexBuffer() {} + + const void* getData() const { return data; } + size_t getSize() const { return size; } + + unsigned int id; + private: + const void* data; + size_t size; + }; + + class VertexArray { + + public: + VertexArray() { + } + + ~VertexArray() {} + + + unsigned int id; + private: + }; + + class IndexArray { + + public: + IndexArray(const unsigned int* indices, size_t count) : indices(indices), count(count) { + } + + IndexArray() {} + + ~IndexArray() {} + + const void* getIndicies() const { return indices; } + size_t getCount() const { return count; } + + unsigned int id; + private: + const unsigned int* indices; + size_t count; + }; + + class Shader { + + public: + enum class LoadType { + FromSource, + FromBin, + FromFileSource, + FromFileBin + }; + + Shader() {} + + Shader(const std::string& vs, const std::string& fs, LoadType loadType) { + init(vs, fs, loadType); + } + + ~Shader() {} + + void init(const std::string& vs, const std::string& fs, LoadType loadType) { + switch(loadType) { + case LoadType::FromSource: + this->vs = vs; + this->fs = fs; + break; + case LoadType::FromBin: + break; + case LoadType::FromFileSource: + this->vs = readSourceFile(vs); + this->fs = readSourceFile(fs); + break; + case LoadType::FromFileBin: + break; + default: + break; + } + } + + std::string getVSource() const { return vs; } + std::string getFSource() const { return fs; } + + unsigned int id; + private: + std::string vs; + std::string fs; + + std::string readSourceFile(const std::string& path) { + + std::ifstream file(path); + + if(!file.is_open()) { + return ""; + } + + std::string s; + + while(!file.eof()) { + file >> s; + } + + return s; + + } + }; + + class RenderTarget { + + public: + RenderTarget(const void* data, size_t size, unsigned int* indices, size_t count, VertexLayout layout, const std::string& vs, const std::string& fs) + : vertexBuffer(data, size), + indexArray(indices, count), + layout(layout), + shader(vs, fs, Shader::LoadType::FromFileSource) { + + } + + RenderTarget(VertexBuffer vb, IndexArray ia, VertexLayout vl, Shader s) + : vertexBuffer(vb), + indexArray(ia), + layout(vl), + shader(s) { + + } + + RenderTarget() {} + + ~RenderTarget() {} + + //private: + + VertexBuffer vertexBuffer; + + VertexArray vertexArray; + + IndexArray indexArray; + + VertexLayout layout; + + Shader shader; + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Renderer/Renderer.cpp b/src/ArchimedesCore/utils/Renderer/Renderer.cpp new file mode 100644 index 0000000..e867e69 --- /dev/null +++ b/src/ArchimedesCore/utils/Renderer/Renderer.cpp @@ -0,0 +1,67 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#include "pch.hpp" + +#include "extratools.h" + +#include "RenderTarget.h" + +namespace Archimedes { + + class Renderer { + + public: + + enum class RenderMode { + Triangles, + Lines, + ConnectedLines, + ConnectedLinesLooped, + Points + }; + + int w, h; + + glm::vec4 clearColor = { 0.0f, 0.0f, 0.0f, 1.0f }; + + Renderer() : w(0), h(0) {} + + virtual ~Renderer() {} + + virtual bool init() = 0; + + virtual void render() = 0; + + virtual Shader createShader(const std::string& vs, const std::string& fs, const Shader::LoadType& lt) = 0; + + virtual void useShader(Shader& shader) = 0; + + virtual RenderTarget createRenderTarget( + VertexBuffer vb, + IndexArray ia, + VertexLayout layout, + Shader& s + ) = 0; + + virtual void setupRenderTarget(RenderTarget& rt) = 0; + + virtual void updateRenderTarget(RenderTarget& rt) = 0; + + virtual void freeRenderTarget(RenderTarget& rt) = 0; + + virtual void draw( + const RenderTarget& rt, + const glm::mat4 world = glm::mat4(1.0f), + const glm::mat4 view = glm::mat4(1.0f), + const glm::mat4 proj = glm::mat4(1.0f), + glm::vec4 color = { 1.0f, 0.0f, 1.0f, 1.0f }, + RenderMode mode = RenderMode::Triangles + ) = 0; + + virtual Renderer* getRendererImpl() = 0; + + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.cpp b/src/ArchimedesCore/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.cpp new file mode 100644 index 0000000..875f23e --- /dev/null +++ b/src/ArchimedesCore/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.cpp @@ -0,0 +1,268 @@ + +#ifdef RENDERER_OPENGL +#ifndef RENDERER_OPENGL_H +#define RENDERER_OPENGL_H + +#include "pch.hpp" + +#include "utils/Renderer/Renderer.h" + +#define GLEW_STATIC +#include + + +namespace Archimedes { + + class RendererOpenGL : public Renderer { + + public: + typedef void renderCmd(); + + RendererOpenGL() {}; + ~RendererOpenGL() {}; + + bool init() override { + bool ok = glewInit() == GLEW_OK; + + if(ok) { + glEnable(GL_DEPTH_TEST); + } + + return ok; + }; + + void render() override { + + glViewport(0, 0, w, h); + glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + } + + Shader createShader(const std::string& vs, const std::string& fs, const Shader::LoadType& lt) override { + + + Shader shader(vs, fs, lt); + + std::string vss = shader.getVSource(); + std::string fss = shader.getFSource(); + + const char* vsc = vss.c_str(); + const char* fsc = fss.c_str(); + + unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vsc, NULL); + glCompileShader(vertexShader); + // check for shader compile errors + int success; + char infoLog[512]; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // fragment shader + unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fsc, NULL); + glCompileShader(fragmentShader); + // check for shader compile errors + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // link shaders + unsigned int shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + // check for linking errors + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + shader.id = shaderProgram; + + return shader; + } + + void useShader(Shader& shader) override { + + std::string vss = shader.getVSource(); + std::string fss = shader.getFSource(); + + const char* vsc = vss.c_str(); + const char* fsc = fss.c_str(); + + unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vsc, NULL); + glCompileShader(vertexShader); + // check for shader compile errors + int success; + char infoLog[512]; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // fragment shader + unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fsc, NULL); + glCompileShader(fragmentShader); + // check for shader compile errors + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // link shaders + unsigned int shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + // check for linking errors + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + shader.id = shaderProgram; + + } + + RenderTarget createRenderTarget(VertexBuffer vb, IndexArray ia, VertexLayout layout, Shader& s) override { + + auto rt = RenderTarget(vb, ia, layout, s); + + glGenVertexArrays(1, &rt.vertexArray.id); + + glGenBuffers(1, &rt.vertexBuffer.id); + + glBindVertexArray(rt.vertexArray.id); + + glBindBuffer(GL_ARRAY_BUFFER, rt.vertexBuffer.id); + glBufferData(GL_ARRAY_BUFFER, vb.getSize(), vb.getData(), GL_STATIC_DRAW); + + + glGenBuffers(1, &rt.indexArray.id); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.getCount() * sizeof(unsigned int), rt.indexArray.getIndicies(), GL_STATIC_DRAW); + + + glUseProgram(s.id); + + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + return rt; + }; + + void setupRenderTarget(RenderTarget& rt) override { + + glGenVertexArrays(1, &rt.vertexArray.id); + + glGenBuffers(1, &rt.vertexBuffer.id); + + glGenBuffers(1, &rt.indexArray.id); + + updateRenderTarget(rt); + }; + + void updateRenderTarget(RenderTarget& rt) override { + + glBindVertexArray(rt.vertexArray.id); + + glBindBuffer(GL_ARRAY_BUFFER, rt.vertexBuffer.id); + glBufferData(GL_ARRAY_BUFFER, rt.vertexBuffer.getSize(), rt.vertexBuffer.getData(), GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.getCount() * sizeof(unsigned int), rt.indexArray.getIndicies(), GL_STATIC_DRAW); + + glUseProgram(rt.shader.id); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + }; + + void freeRenderTarget(RenderTarget& rt) override { + + glDeleteVertexArrays(1, &rt.vertexArray.id); + glDeleteBuffers(1, &rt.vertexBuffer.id); + glDeleteBuffers(1, &rt.indexArray.id); + }; + + void draw( + const RenderTarget& rt, + const glm::mat4 world = glm::mat4(1.0f), + const glm::mat4 view = glm::mat4(1.0f), + const glm::mat4 proj = glm::mat4(1.0f), + glm::vec4 color = { 1.0f, 0.0f, 1.0f, 1.0f }, + RenderMode mode = RenderMode::Triangles + ) override { + + glUseProgram(rt.shader.id); + + unsigned int modelLoc = glGetUniformLocation(rt.shader.id, "model"); + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(world)); + + unsigned int viewLoc = glGetUniformLocation(rt.shader.id, "view"); + glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); + + unsigned int projLoc = glGetUniformLocation(rt.shader.id, "proj"); + glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj)); + + unsigned int colorLoc = glGetUniformLocation(rt.shader.id, "color"); + glUniform4f(colorLoc, color.r, color.g, color.b, color.a); + + glBindVertexArray(rt.vertexArray.id); + + switch(mode) { + case RenderMode::Triangles: + glDrawElements(GL_TRIANGLES, rt.indexArray.getCount(), GL_UNSIGNED_INT, nullptr); + break; + case RenderMode::Lines: + glDrawElements(GL_LINES, rt.indexArray.getCount(), GL_UNSIGNED_INT, nullptr); + break; + case RenderMode::ConnectedLines: + glDrawElements(GL_LINE_STRIP, rt.indexArray.getCount(), GL_UNSIGNED_INT, nullptr); + break; + case RenderMode::ConnectedLinesLooped: + glDrawElements(GL_LINE_LOOP, rt.indexArray.getCount(), GL_UNSIGNED_INT, nullptr); + break; + case RenderMode::Points: + glDrawElements(GL_POINTS, rt.indexArray.getCount(), GL_UNSIGNED_INT, nullptr); + break; + default: + break; + } + + + glBindVertexArray(0); + } + + RendererOpenGL* getRendererImpl() override { return this; } + }; +} + +#endif +#endif diff --git a/src/ArchimedesCore/utils/Renderer/RendererImpl/RendererSDL3/RendererSDL3.cpp b/src/ArchimedesCore/utils/Renderer/RendererImpl/RendererSDL3/RendererSDL3.cpp new file mode 100644 index 0000000..e2536e6 --- /dev/null +++ b/src/ArchimedesCore/utils/Renderer/RendererImpl/RendererSDL3/RendererSDL3.cpp @@ -0,0 +1,43 @@ +#ifdef RENDERER_SDL3 +#ifndef RENDERER_SDL3_H +#define RENDERER_SDL3_H + +#include "pch.hpp" + +#include + + +namespace Archimedes { + + class RendererSDL3 { + + public: + typedef void renderCmd(); + + RendererSDL3() {}; + ~RendererSDL3() { SDL_DestroyRenderer(renderer); }; + + bool init(void* window) { + renderer = SDL_CreateRenderer((SDL_Window*) window, nullptr); + SDL_SetRenderVSync(renderer, 1); + return renderer != nullptr; + }; + + void render(std::list> cmdList, int& w, int& h) { + + //SDL_SetRenderScale(renderer, w, h); + + SDL_RenderClear(renderer); + + for(auto f : cmdList) + f(); + + SDL_RenderPresent(renderer); + } + + SDL_Renderer* renderer = nullptr; + }; +} + +#endif +#endif diff --git a/src/ArchimedesCore/utils/Window/Window.cpp b/src/ArchimedesCore/utils/Window/Window.cpp new file mode 100644 index 0000000..bdbd14f --- /dev/null +++ b/src/ArchimedesCore/utils/Window/Window.cpp @@ -0,0 +1,66 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include "WindowEvents.h" + +#include "utils/Renderer/Renderer.h" + +namespace Archimedes { + + class Window { + + public: + + Window(const std::function& sendEventFn) : eventFn(sendEventFn) {} + + virtual ~Window() {}; + + + void doFrame() { + + swapBuffers(); + + renderer->render(); + + pollEvents(); + + } + + virtual bool shouldClose() = 0; + + virtual void swapBuffers() = 0; + + virtual void pollEvents() = 0; + + virtual void restoreContext() = 0; + + virtual void getSize(int& w, int& h) { + w = this->w; + h = this->h; + } + + virtual void setSize(const int& w, const int& h) { + this->w = w; + this->h = h; + } + + Renderer* getRenderer() { return renderer; } + void setRenderer(Renderer* r) { + renderer = r; + renderer->w = w; + renderer->h = h; + } + + virtual Window* getWindowImpl() = 0; + + protected: + + int w, h; + + Renderer* renderer; + + std::function eventFn; + }; +} + +#endif diff --git a/src/ArchimedesCore/utils/Window/WindowEvents.cpp b/src/ArchimedesCore/utils/Window/WindowEvents.cpp new file mode 100644 index 0000000..1868f40 --- /dev/null +++ b/src/ArchimedesCore/utils/Window/WindowEvents.cpp @@ -0,0 +1,220 @@ +#ifndef WINDOWEVENTS_H +#define WINDOWEVENTS_H + +#include "utils/Events/Event.h" + +//implimentation independent events + +namespace Archimedes { + + class Window; + + struct WindowData { + Window* window; + std::list eventList; + std::function sendEvent; + }; + + class ResizeWindowEvent : public Event { + + public: + + ResizeWindowEvent() : width(0), height(0) {} + + ResizeWindowEvent(int w, int h) : width(w), height(h) {} + ResizeWindowEvent(int w, int h, std::any userData) : Event(userData), width(w), height(h) {} + + ~ResizeWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::ResizeWindowEvent"; } + + int width, height; + + }; + + class CloseWindowEvent : public Event { + + public: + + CloseWindowEvent() : Event(nullptr), window(nullptr) {} + + CloseWindowEvent(const Window* w) : window(w) {} + CloseWindowEvent(const Window* w, std::any userData) : Event(userData), window(w) {} + + ~CloseWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::CloseWindowEvent"; } + + const Window* window; + }; + + class KeyPressedWindowEvent : public Event { + + public: + + KeyPressedWindowEvent() : key(0), repeat(0) {} + + KeyPressedWindowEvent(unsigned int k, unsigned int r) : key(k), repeat(r) {} + KeyPressedWindowEvent(unsigned int k, unsigned int r, std::any userData) : Event(userData), key(k), repeat(r) {} + + ~KeyPressedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::KeyPressedWindowEvent"; } + + unsigned int key; + unsigned int repeat; + }; + + class KeyReleasedWindowEvent : public Event { + + public: + + KeyReleasedWindowEvent() : Event(nullptr), key(0) {} + + KeyReleasedWindowEvent(unsigned int k) : key(k) {} + KeyReleasedWindowEvent(unsigned int k, std::any userData) : Event(userData), key(k) {} + + ~KeyReleasedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::KeyReleasedWindowEvent"; } + + unsigned int key; + }; + + class MouseButtonPressedWindowEvent : public Event { + + public: + + MouseButtonPressedWindowEvent() : button(0) {} + + MouseButtonPressedWindowEvent(unsigned int b) : button(b) {} + MouseButtonPressedWindowEvent(unsigned int b, std::any userData) : Event(userData), button(b) {} + + ~MouseButtonPressedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::MouseButtonPressedWindowEvent"; } + + unsigned int button; + }; + + class MouseButtonReleasedWindowEvent : public Event { + + public: + + MouseButtonReleasedWindowEvent() : button(0) {} + + MouseButtonReleasedWindowEvent(unsigned int b) : button(b) {} + MouseButtonReleasedWindowEvent(unsigned int b, std::any userData) : Event(userData), button(b) {} + + ~MouseButtonReleasedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::MouseButtonReleasedWindowEvent"; } + + unsigned int button; + }; + + class ScrollWindowEvent : public Event { + + public: + + ScrollWindowEvent() : dx(0), dy(0) {} + + ScrollWindowEvent(double x, double y) : dx(x), dy(y) {} + ScrollWindowEvent(double x, double y, std::any userData) : Event(userData), dx(x), dy(y) {} + + ~ScrollWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::ScrollWindowEvent"; } + + double dx, dy; + }; + + class MouseMovedWindowEvent : public Event { + + public: + + MouseMovedWindowEvent() : x(0), y(0) {} + + MouseMovedWindowEvent(double x, double y) : x(x), y(y) {} + MouseMovedWindowEvent(double x, double y, std::any userData) : Event(userData), x(x), y(y) {} + + ~MouseMovedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::MouseMovedWindowEvent"; } + + double x, y; + }; + + class FocusedWindowEvent : public Event { + + public: + + FocusedWindowEvent() : window(nullptr) {} + + FocusedWindowEvent(const Window* w) : window(w) {} + FocusedWindowEvent(const Window* w, std::any userData) : Event(userData), window(w) {} + + ~FocusedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::FocusedWindowEvent"; } + + const Window* window; + }; + + class FocusLostWindowEvent : public Event { + + public: + + FocusLostWindowEvent() : window(nullptr) {} + + FocusLostWindowEvent(const Window* w) : window(w) {} + FocusLostWindowEvent(const Window* w, std::any userData) : Event(userData), window(w) {} + + ~FocusLostWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::FocusLostWindowEvent"; } + + const Window* window; + }; + + class MovedWindowEvent : public Event { + + public: + + MovedWindowEvent() : x(0), y(0) {} + + MovedWindowEvent(int x, int y) : x(x), y(y) {} + MovedWindowEvent(int x, int y, std::any userData) : Event(userData), x(x), y(y) {} + + ~MovedWindowEvent() { + + } + + operator std::string() const override { return "Archimedes::MovedWindowEvent"; } + + int x, y; + }; + +} + +#endif diff --git a/src/ArchimedesCore/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.cpp b/src/ArchimedesCore/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.cpp new file mode 100644 index 0000000..d19e0c1 --- /dev/null +++ b/src/ArchimedesCore/utils/Window/WindowImpl/WindowGLFW/WindowGLFW.cpp @@ -0,0 +1,146 @@ +#ifdef WINDOW_GLFW +#ifndef WINDOW_GLFW_H +#define WINDOW_GLFW_H + +#include "pch.hpp" + +#include "utils/Window/Window.h" + +#define GLFW_INCLUDE_NONE +#include + + +namespace Archimedes { + + class WindowGLFW : public Window { + + public: + + WindowGLFW(const std::function& sendEvent) : Window(sendEvent) { + + data.window = this; + data.sendEvent = sendEvent; + + glfwSetErrorCallback([](int e, const char* m){ + std::cout << "GLFW Error " << e << ": " << m << std::endl; + }); + + if(!glfwInit()) { + std::cout << "glfwInit failed!\n"; + std::abort(); + } +#ifdef RENDERER_OPENGL + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1); +#endif + + window = glfwCreateWindow(640, 480, "Archimedes", NULL, NULL); + + if(!window) { + std::cout << "glfwCreateWindow failed!\n"; + glfwTerminate(); + std::abort(); + } + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + glfwSetWindowUserPointer(window, &data); + + glfwSetWindowSizeCallback(window, [](GLFWwindow* window, int w, int h){ + WindowData& d = *(WindowData*) glfwGetWindowUserPointer(window); + + d.sendEvent(new ResizeWindowEvent(w, h)); + }); + + glfwSetWindowCloseCallback(window, [](GLFWwindow* window){ + WindowData& d = *(WindowData*) glfwGetWindowUserPointer(window); + + d.sendEvent(new CloseWindowEvent(d.window)); + }); + + glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){ + WindowData& d = *(WindowData*) glfwGetWindowUserPointer(window); + + switch(action) { + case GLFW_PRESS: + d.sendEvent(new KeyPressedWindowEvent(key, 0)); + break; + case GLFW_RELEASE: + d.sendEvent(new KeyReleasedWindowEvent(key)); + break; + case GLFW_REPEAT: + d.sendEvent(new KeyPressedWindowEvent(key, 1)); + break; + } + }); + + glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){ + WindowData& d = *(WindowData*) glfwGetWindowUserPointer(window); + + switch(action) { + case GLFW_PRESS: + d.sendEvent(new MouseButtonPressedWindowEvent(button)); + break; + case GLFW_RELEASE: + d.sendEvent(new MouseButtonReleasedWindowEvent(button)); + break; + } + }); + + glfwSetScrollCallback(window, [](GLFWwindow* window, double dx, double dy){ + WindowData& d = *(WindowData*) glfwGetWindowUserPointer(window); + + d.sendEvent(new ScrollWindowEvent(dx, dy)); + }); + + glfwSetCursorPosCallback(window, [](GLFWwindow* window, double dx, double dy){ + WindowData& d = *(WindowData*) glfwGetWindowUserPointer(window); + + d.sendEvent(new MouseMovedWindowEvent(dx, dy)); + }); + } + + ~WindowGLFW() { + glfwTerminate(); + } + + + void swapBuffers() override { restoreContext(); glfwSwapBuffers(window); }; + + void pollEvents() override { glfwPollEvents(); } + + bool shouldClose() override { + return glfwWindowShouldClose(window); + } + + void setSize(const int& w, const int& h) override { + this->w = w; + this->h = h; + + glfwSetWindowSize(window, w, h); + } + + void restoreContext() override { glfwMakeContextCurrent(window); } + + void getSize(int& w, int& h) override { + glfwGetFramebufferSize(window, &w, &h); + } + + GLFWwindow* getWindow() { return window; } + + WindowData data; + + virtual WindowGLFW* getWindowImpl() override { return this; } + + private: + GLFWwindow* window; + + }; + +} + +#endif +#endif diff --git a/src/ArchimedesCore/utils/Window/WindowImpl/WindowSDL3/WindowSDL3.cpp b/src/ArchimedesCore/utils/Window/WindowImpl/WindowSDL3/WindowSDL3.cpp new file mode 100644 index 0000000..7667fc0 --- /dev/null +++ b/src/ArchimedesCore/utils/Window/WindowImpl/WindowSDL3/WindowSDL3.cpp @@ -0,0 +1,161 @@ +#ifdef WINDOW_SDL3 +#ifndef WINDOW_SDL3_H +#define WINDOW_SDL3_H + +#include "pch.hpp" + +#include "utils/Window/Window.h" + +#include + +#ifdef RENDERER_OPENGL + +#include + +#endif + +namespace Archimedes { + + static bool EventCallback(void* ptr, SDL_Event* e) { + + WindowData& data = *(WindowData*) ptr; + + switch(e->type) { + + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + case SDL_EVENT_QUIT: + data.sendEvent(new CloseWindowEvent(data.window, e)); + break; + case SDL_EVENT_WINDOW_RESIZED: + data.sendEvent(new ResizeWindowEvent(e->window.data1, e->window.data2, e)); + break; + case SDL_EVENT_WINDOW_MOUSE_ENTER: + case SDL_EVENT_WINDOW_FOCUS_GAINED: + data.sendEvent(new FocusedWindowEvent(data.window, e)); + break; + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + case SDL_EVENT_WINDOW_FOCUS_LOST: + data.sendEvent(new FocusLostWindowEvent(data.window, e)); + break; + case SDL_EVENT_KEY_DOWN: + data.sendEvent(new KeyPressedWindowEvent(e->key.key, e->key.repeat ? 1 : 0, e)); + break; + case SDL_EVENT_KEY_UP: + data.sendEvent(new KeyReleasedWindowEvent(e->key.key, e)); + break; + case SDL_EVENT_MOUSE_MOTION: + data.sendEvent(new MouseMovedWindowEvent(e->motion.x, e->motion.y, e)); + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + data.sendEvent(new MouseButtonPressedWindowEvent(e->button.button, e)); + break; + case SDL_EVENT_MOUSE_BUTTON_UP: + data.sendEvent(new MouseButtonReleasedWindowEvent(e->button.button, e)); + break; + case SDL_EVENT_MOUSE_WHEEL: + data.sendEvent(new ScrollWindowEvent(e->wheel.x, e->wheel.y, e)); + break; + default: + data.sendEvent(new AnonymousEvent(e)); + break; + } + + return true; + } + + class WindowSDL3 : public Window { + + public: + + WindowSDL3(const std::function& sendEvent) : Window(sendEvent) { + + data.window = this; + data.sendEvent = sendEvent; + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) { + std::cerr << "Error: SDL_Init(): " << SDL_GetError() << std::flush; + std::abort(); + } + +#ifdef RENDERER_OPENGL + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; +#endif +#ifdef RENDERER_SDL3 + SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; +#endif + + window = SDL_CreateWindow("Archimedes", 1280, 720, window_flags); + if (window == nullptr) + { + std::cerr << "Error: SDL_CreateWindow(): " << SDL_GetError() << std::endl; + std::abort(); + } + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + +#ifdef RENDERER_OPENGL + gl_context = SDL_GL_CreateContext(window); + + if (gl_context == nullptr) + { + std::cerr << "Error: SDL_GL_CreateContext(): " << SDL_GetError() << std::endl; + std::abort(); + } + + SDL_GL_MakeCurrent(window, gl_context); + SDL_GL_SetSwapInterval(1); // Enable vsync +#endif + SDL_AddEventWatch(EventCallback, &data); + + SDL_ShowWindow(window); + } + + ~WindowSDL3() { +#ifdef RENDERER_OPENGL + SDL_GL_DestroyContext(gl_context); +#endif + SDL_RemoveEventWatch(EventCallback, &data); + SDL_DestroyWindow(window); + SDL_Quit(); + } + + bool shouldClose() override { return false; } + + void swapBuffers() override { +#ifdef RENDERER_OPENGL + restoreContext(); + SDL_GL_SwapWindow(window); +#endif + } + + void pollEvents() override { + static SDL_Event e; + while(SDL_PollEvent(&e)); + } + + WindowSDL3* getWindowImpl() override { return this; }; + +#ifdef RENDERER_OPENGL + void restoreContext() override { SDL_GL_MakeCurrent(window, gl_context); } +#endif + + SDL_Window* getWindow() { return window; } +#ifdef RENDERER_OPENGL + SDL_GLContext getContext() { return gl_context; } +#endif + WindowData data; + + private: + SDL_Window* window; +#ifdef RENDERER_OPENGL + SDL_GLContext gl_context; +#endif + + }; +} + +#endif +#endif diff --git a/src/include/utils/Objects/Body.h b/src/include/utils/Objects/Body.h index 2b2d726..0e83063 100644 --- a/src/include/utils/Objects/Body.h +++ b/src/include/utils/Objects/Body.h @@ -12,14 +12,16 @@ namespace Archimedes { class Body : public Object { public: - Body(RenderTarget rt, glm::mat4 t = glm::mat4(1.0f)) : mesh(rt), Object(t) {}; + Body(RenderTarget rt, glm::mat4 t = glm::mat4(1.0f)) : Object(t), mesh(rt) {}; Body(VertexBuffer vb, IndexArray ia, VertexLayout vl, Shader s, glm::mat4 t = glm::mat4(1.0f)) - : mesh(vb, ia, vl, s), Object(t) {} + : Object(t), mesh(vb, ia, vl, s) {} - Body() {} + Body() : Object(glm::mat4(1.0f)) {} ~Body() {}; + + RenderTarget& getMesh() { return mesh; } private: diff --git a/src/include/utils/Objects/Camera.h b/src/include/utils/Objects/Camera.h index 50f5588..ea21dd0 100644 --- a/src/include/utils/Objects/Camera.h +++ b/src/include/utils/Objects/Camera.h @@ -12,7 +12,7 @@ namespace Archimedes { class Camera : public Object { public: - Camera() {} + Camera() : Object(glm::mat4(1.0f)) {} Camera(glm::mat4 t) : Object(t) {} diff --git a/src/include/utils/Objects/Object.h b/src/include/utils/Objects/Object.h index 0aa0924..d6abf33 100644 --- a/src/include/utils/Objects/Object.h +++ b/src/include/utils/Objects/Object.h @@ -13,22 +13,57 @@ namespace Archimedes { public: - Object() {}; - Object(glm::mat4 t) : worldTransform(t) {} ~Object() {}; ///scales an object absolutely - //void scaleTo() {} - void scaleRel(float scale) { worldTransform = glm::scale(worldTransform, glm::vec3(scale)); } + ///scale factors less than zero do nothing + float scaleTo(float s) { + if(s > 0) { + worldTransform = glm::scale(worldTransform, glm::vec3(s / scale)); + scale = s; + } - //void moveTo(glm::vec3 pos) { worldTransform = glm::translate(worldTransform, pos); } - void moveRel(glm::vec3 pos) { worldTransform = glm::translate(worldTransform, pos); } + return scale; + } - //void rotateTo() {} - void rotateRel(float radians, glm::vec3 axis) { worldTransform = glm::rotate(worldTransform, radians, axis); } + float scaleRel(float s) { + return scaleTo(scale * s); + } + + float scaleAdd(float s) { + return scaleTo(scale + s); + } + + glm::vec3 moveTo(glm::vec3 pos) { + worldTransform = glm::translate(worldTransform, pos - position); + position = pos; + + return position; + } + + glm::vec3 moveRel(glm::vec3 pos) { + return moveTo(pos + position); + } + + glm::vec3 rotateTo(glm::vec3 angles) { + worldTransform = glm::rotate(worldTransform, angles.x - rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)); + worldTransform = glm::rotate(worldTransform, angles.y - rotation.y, glm::vec3(0.0f, 1.0f, 0.0f)); + worldTransform = glm::rotate(worldTransform, angles.z - rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)); + rotation = angles; + + return rotation; + } + + glm::vec3 rotateRel(glm::vec3 angles) { + return rotateTo(angles + rotation); + } + + glm::vec3& getPosition() { return position; } + glm::vec3& getRotation() { return rotation; } + float& getScale() { return scale; } const glm::mat4& getTransform() { return worldTransform; } @@ -36,6 +71,7 @@ namespace Archimedes { glm::vec3 position = glm::vec3(0); glm::vec3 rotation = glm::vec3(0); + float scale = 1.0f; glm::mat4 worldTransform = glm::mat4(1.0f); diff --git a/src/include/utils/Renderer/RenderTarget.h b/src/include/utils/Renderer/RenderTarget.h index f6d445b..02981ff 100644 --- a/src/include/utils/Renderer/RenderTarget.h +++ b/src/include/utils/Renderer/RenderTarget.h @@ -41,20 +41,19 @@ namespace Archimedes { class VertexBuffer { public: - VertexBuffer(const void* data, size_t size) : data(data), size(size) { + VertexBuffer(const std::vector data) : data(data) { } VertexBuffer() {} ~VertexBuffer() {} - const void* getData() const { return data; } - size_t getSize() const { return size; } + const void* getData() const { return data.data(); } + size_t getSize() const { return data.size() * sizeof(float); } unsigned int id; private: - const void* data; - size_t size; + std::vector data; }; class VertexArray { @@ -73,20 +72,19 @@ namespace Archimedes { class IndexArray { public: - IndexArray(const unsigned int* indices, size_t count) : indices(indices), count(count) { + IndexArray(const std::vector indices) : indices(indices) { } IndexArray() {} ~IndexArray() {} - const void* getIndicies() const { return indices; } - size_t getCount() const { return count; } + const void* getIndicies() const { return indices.data(); } + size_t getCount() const { return indices.size(); } unsigned int id; private: - const unsigned int* indices; - size_t count; + std::vector indices; }; class Shader { @@ -156,9 +154,9 @@ namespace Archimedes { class RenderTarget { public: - RenderTarget(const void* data, size_t size, unsigned int* indices, size_t count, VertexLayout layout, const std::string& vs, const std::string& fs) - : vertexBuffer(data, size), - indexArray(indices, count), + RenderTarget(const std::vector data, const std::vector indices, VertexLayout layout, const std::string& vs, const std::string& fs) + : vertexBuffer(data), + indexArray(indices), layout(layout), shader(vs, fs, Shader::LoadType::FromFileSource) { @@ -188,7 +186,6 @@ namespace Archimedes { Shader shader; - glm::mat4 transform = glm::mat4(1.0f); }; } diff --git a/src/include/utils/Renderer/Renderer.h b/src/include/utils/Renderer/Renderer.h index b3fef06..e867e69 100644 --- a/src/include/utils/Renderer/Renderer.h +++ b/src/include/utils/Renderer/Renderer.h @@ -50,7 +50,14 @@ namespace Archimedes { virtual void freeRenderTarget(RenderTarget& rt) = 0; - virtual void draw(const RenderTarget& rt, glm::vec4 color = { 1.0f, 0.0f, 1.0f, 1.0f }, RenderMode mode = RenderMode::Triangles) = 0; + virtual void draw( + const RenderTarget& rt, + const glm::mat4 world = glm::mat4(1.0f), + const glm::mat4 view = glm::mat4(1.0f), + const glm::mat4 proj = glm::mat4(1.0f), + glm::vec4 color = { 1.0f, 0.0f, 1.0f, 1.0f }, + RenderMode mode = RenderMode::Triangles + ) = 0; virtual Renderer* getRendererImpl() = 0; diff --git a/src/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h b/src/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h index 0dff107..875f23e 100644 --- a/src/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h +++ b/src/include/utils/Renderer/RendererImpl/RendererOpenGL/RendererOpenGL.h @@ -211,16 +211,25 @@ namespace Archimedes { glDeleteBuffers(1, &rt.indexArray.id); }; - void draw(const RenderTarget& rt, glm::vec4 color = { 1.0f, 0.0f, 1.0f, 1.0f }, RenderMode mode = RenderMode::Triangles) override { + void draw( + const RenderTarget& rt, + const glm::mat4 world = glm::mat4(1.0f), + const glm::mat4 view = glm::mat4(1.0f), + const glm::mat4 proj = glm::mat4(1.0f), + glm::vec4 color = { 1.0f, 0.0f, 1.0f, 1.0f }, + RenderMode mode = RenderMode::Triangles + ) override { glUseProgram(rt.shader.id); - unsigned int transformLoc = glGetUniformLocation(rt.shader.id, "model"); - glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(rt.transform)); + unsigned int modelLoc = glGetUniformLocation(rt.shader.id, "model"); + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(world)); + unsigned int viewLoc = glGetUniformLocation(rt.shader.id, "view"); + glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - unsigned int resLoc = glGetUniformLocation(rt.shader.id, "res"); - glUniform2ui(resLoc, w, h); + unsigned int projLoc = glGetUniformLocation(rt.shader.id, "proj"); + glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj)); unsigned int colorLoc = glGetUniformLocation(rt.shader.id, "color"); glUniform4f(colorLoc, color.r, color.g, color.b, color.a); diff --git a/src/include/utils/Renderer/concepts.h b/src/include/utils/Renderer/concepts.h deleted file mode 100644 index 2b2b5f9..0000000 --- a/src/include/utils/Renderer/concepts.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef RENDERER_CONCEPTS -#define RENDERER_CONCEPTS - -#include "pch.hpp" - -namespace Archimedes { - - class RendererOpenGL; - - class RendererSDL3; - - template - concept allowed_renderers = requires (RendererImpl r) { -#ifndef CUSTOM_RENDERER - requires std::same_as - || std::same_as; -#endif - }; -} - -#endif diff --git a/src/include/utils/Window/concepts.h b/src/include/utils/Window/concepts.h deleted file mode 100644 index dff5edb..0000000 --- a/src/include/utils/Window/concepts.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef WINDOW_CONCEPTS -#define WINDOW_CONCEPTS - -#include "pch.hpp" - -#include "utils/Renderer/concepts.h" - -namespace Archimedes { - - template - class WindowGLFW; - - template - class WindowSDL3; - - template - concept allowed_windows = requires (WindowImpl a, R b) { -#ifndef CUSTOM_WINDOW - requires std::same_as> - || std::same_as>; -#endif - }; -} - -#endif diff --git a/src/modules/Archimedes-Modules/Sandbox/JObject.h b/src/modules/Archimedes-Modules/Sandbox/JObject.h index 347a760..62b7a99 100644 --- a/src/modules/Archimedes-Modules/Sandbox/JObject.h +++ b/src/modules/Archimedes-Modules/Sandbox/JObject.h @@ -1,16 +1,85 @@ #include "pch.hpp" -#include "Object.h" +#include "utils/Objects/Body.h" namespace Archimedes { + Body readOBJ(std::string path, Shader shader) { + + std::ifstream file(path); + + if(!file.is_open()) return Body(); + + std::string s; + + std::vector verticies; + std::vector indicies; + + unsigned int i = 0; + unsigned int j = 0; + + float point; + unsigned int idx; + + while(!file.eof()) { + getline(file, s, ' '); + + //std::cout << "\nline start: " << s << std::endl; + + if(s == "v") { + file >> point; + verticies.push_back(point); + //std::cout << "point1: " << point << std::endl; + + file >> point; + verticies.push_back(point); + //std::cout << "point2: " << point << std::endl; + + file >> point; + verticies.push_back(point); + //std::cout << "point3: " << point << std::endl; + + //std::cout << "index: " << j << std::endl; + + getline(file, s); + //file.ignore(); + } else if(s == "f") { + + file >> idx; + indicies.push_back(--idx); + file.ignore(5, ' '); + + file >> idx; + indicies.push_back(--idx); + file.ignore(5, ' '); + + file >> idx; + indicies.push_back(--idx); + getline(file, s); + + } else { + getline(file, s); + } + } + + file.close(); + + return Body( + VertexBuffer(verticies), + IndexArray(indicies), + VertexLayout(), + shader + ); + } + using json = nlohmann::json; class JObject { public: - JObject(std::string path) { + JObject() {} + void load(std::string path) { std::ifstream file(path); if (!file.is_open()) goodJSON = false; document = json::parse(file); @@ -25,9 +94,41 @@ namespace Archimedes { bool isValid() const { return goodJSON; } - std::vector buildObjects() { + Body createCircle(json& element, std::string name) { + std::vector v; + std::vector i; - std::vector v; + for(int it = 0; it < resolution; it++) { + v.push_back(glm::cos(2.0f * glm::pi() / resolution)); + v.push_back(glm::sin(2.0f * glm::pi() / resolution)); + v.push_back(0.0f); + + i.push_back(it); + } + + return Body( + VertexBuffer(v), + IndexArray(i), + VertexLayout(), + shader + ); + } + + Body createRect(json& element, std::string name) { + return Body(); + } + + Body createPoly(json& element, std::string name) { + return Body(); + } + + Body createText(json& element, std::string name) { + return Body(); + } + + std::vector buildObjects() { + + std::vector v; for (json::const_iterator it = templates.cbegin(); it != templates.cend(); it++) @@ -35,7 +136,9 @@ namespace Archimedes { json element = *it; std::string name = element["name"]; std::string type = element["type"]; - if (type == "CIRCLE") {} + if (type == "CIRCLE") { + objectMap[name] = createCircle(element, name); + } if (type == "SQUARE") {} if (type == "RECTANGLE") {} if (type == "POLYGON") {} @@ -47,8 +150,16 @@ namespace Archimedes { private: + std::unordered_map objectMap; + + std::unordered_map templateMap; + bool goodJSON = true; + Shader shader; + + unsigned int resolution = 50; + json document, templates, objects, setup, cameras, lights, actions; }; } diff --git a/src/modules/Archimedes-Modules/Sandbox/Sandbox.cpp b/src/modules/Archimedes-Modules/Sandbox/Sandbox.cpp index da24ee2..fc9dca4 100644 --- a/src/modules/Archimedes-Modules/Sandbox/Sandbox.cpp +++ b/src/modules/Archimedes-Modules/Sandbox/Sandbox.cpp @@ -2,7 +2,7 @@ #include "Sandbox.h" - +#include "JObject.h" Sandbox::Sandbox(Archimedes::App* a, void* h) : Archimedes::Module(a, h) { @@ -56,101 +56,74 @@ void Sandbox::onLoad() { window->getRenderer()->useShader(cubeShader); - cube = Archimedes::RenderTarget( - Archimedes::VertexBuffer(vertices, 24 * sizeof(float)), - Archimedes::IndexArray(indices, 36), + cube = Archimedes::Body( + Archimedes::VertexBuffer(vertices), + Archimedes::IndexArray(indices), Archimedes::VertexLayout(), cubeShader ); - window->getRenderer()->setupRenderTarget(cube); + window->getRenderer()->setupRenderTarget(cube.getMesh()); - grid = Archimedes::RenderTarget( - Archimedes::VertexBuffer(gridVertices, 12 * sizeof(float)), - Archimedes::IndexArray(gridIndices, 6), + grid = Archimedes::Body( + Archimedes::VertexBuffer(gridVertices), + Archimedes::IndexArray(gridIndices), Archimedes::VertexLayout(), cubeShader ); - window->getRenderer()->setupRenderTarget(grid); + window->getRenderer()->setupRenderTarget(grid.getMesh()); int w, h; window->getSize(w, h); app->emitEvent(new Archimedes::ResizeWindowEvent(w, h)); + hexagon = Archimedes::readOBJ("/home/nathan/Projects/tests/buildzone/hexagon_pad.obj", cubeShader); + + window->getRenderer()->setupRenderTarget(hexagon.getMesh()); + + + hexagon.scaleTo(0.01f); } void Sandbox::run() { - static float scale = 1.0f; + static float scale = 1.0f, scalePrev = 1.0f; static glm::vec3 pos(0), rot(0); + static glm::vec3 posPrev(0), rotPrev(0); static glm::vec4 color = { 0.4f, 0.0f, 0.3f, 1.0f }; static glm::vec3 camPos(0.0f, 0.0f, 3.0f), camRot(0.0f, glm::pi(), 0.0f); - static glm::mat4 orthoCamera, perspCamera, cameraTransform; - -/* - cameraTransform = glm::mat4(1.0f); - cameraTransform = glm::translate(cameraTransform, camPos); - cameraTransform = glm::rotate(cameraTransform, camRot.x, glm::vec3(1.0f, 0.0f, 0.0f)); - cameraTransform = glm::rotate(cameraTransform, camRot.y, glm::vec3(0.0f, 1.0f, 0.0f)); - cameraTransform = glm::rotate(cameraTransform, camRot.z, glm::vec3(0.0f, 0.0f, 1.0f)); -*/ + static glm::mat4 orthoMat, perspMat, cameraTransform; cameraTransform = glm::lookAt( camPos, camPos + glm::normalize(glm::vec3(glm::sin(camRot.y) * glm::cos(camRot.x), glm::sin(camRot.x), glm::cos(camRot.y) * glm::cos(camRot.x))), glm::vec3(0.0f, 1.0f, 0.0f) ); -/* - cameraTransform = glm::lookAt( - camPos, - glm::vec3(0.0f, 0.0f, 0.0f), - glm::vec3(0.0f, 1.0f, 0.0f) - ); -*/ + int w, h; window->getSize(w, h); - orthoCamera = glm::ortho(-(float)w / 2.0f, (float)w / 2.0f, -(float)h / 2.0f, (float)h / 2.0f, 0.1f, 100.0f) - * cameraTransform; + orthoMat = glm::ortho(-(float)w / 2.0f, (float)w / 2.0f, -(float)h / 2.0f, (float)h / 2.0f, 0.1f, 100.0f); - perspCamera = glm::perspective(glm::radians(45.0f), (float)w/(float)h, 0.1f, 100.0f) - * cameraTransform; + perspMat = glm::perspective(glm::radians(45.0f), (float)w/(float)h, 0.1f, 100.0f); - glm::mat4& cubeTransform = cube.transform; - //glm::mat4& gridTransform = grid.transform; - - cubeTransform = glm::mat4(1.0f); - cubeTransform = glm::translate(cubeTransform, pos); - cubeTransform = glm::rotate(cubeTransform, rot.x, glm::vec3(1.0f, 0.0f, 0.0f)); - cubeTransform = glm::rotate(cubeTransform, rot.y, glm::vec3(0.0f, 1.0f, 0.0f)); - cubeTransform = glm::rotate(cubeTransform, rot.z, glm::vec3(0.0f, 0.0f, 1.0f)); - cubeTransform = glm::scale(cubeTransform, glm::vec3(scale)); - + pos = cube.moveRel(pos - posPrev); + rot = cube.rotateRel(rot - rotPrev); + scale = cube.scaleRel(scale / scalePrev); - //gridTransform = glm::mat4(1.0f); - //gridTransform = glm::scale(gridTransform, glm::vec3(800.0f)); - - - //cubeTransform = orthoCamera * cubeTransform; - cubeTransform = perspCamera * cubeTransform; - - //gridTransform = orthoCamera * gridTransform; - -/* - cubeTransform = glm::perspective(glm::radians(45.0f), (float)w/(float)h, 0.1f, 100.0f) - * glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)) - * cubeTransform; -*/ - - - //window->getRenderer()->draw(grid); - window->getRenderer()->draw(cube, color, Archimedes::Renderer::RenderMode::Triangles); + posPrev = pos; + rotPrev = rot; + scalePrev = scale; + + //window->getRenderer()->draw(grid.getMesh(), grid.getTransform(), cameraTransform, perspMat, glm::vec4(0.7f)); + //window->getRenderer()->draw(cube.getMesh(), cube.getTransform(), cameraTransform, perspMat, color, Archimedes::Renderer::RenderMode::Triangles); + window->getRenderer()->draw(hexagon.getMesh(), hexagon.getTransform(), cameraTransform, perspMat, color); { @@ -161,10 +134,10 @@ void Sandbox::run() { ImGui::Text("Pick a clear color!"); - ImGui::SliderFloat("r", &clearColor.r, 0.0f, 1.0f); - ImGui::SliderFloat("g", &clearColor.g, 0.0f, 1.0f); - ImGui::SliderFloat("b", &clearColor.b, 0.0f, 1.0f); - ImGui::SliderFloat("a", &clearColor.a, 0.0f, 1.0f); + ImGui::SliderFloat("clear r", &clearColor.r, 0.0f, 1.0f); + ImGui::SliderFloat("clear g", &clearColor.g, 0.0f, 1.0f); + ImGui::SliderFloat("clear b", &clearColor.b, 0.0f, 1.0f); + ImGui::SliderFloat("clear a", &clearColor.a, 0.0f, 1.0f); ImGui::Text("Properties"); @@ -178,20 +151,20 @@ void Sandbox::run() { ImGui::SliderFloat("y", &pos.y, -10.0f, 10.0f); ImGui::SliderFloat("z", &pos.z, -10.0f, 10.0f); - ImGui::SliderFloat("cube r", &color.r, 0.0f, 1.0f); - ImGui::SliderFloat("cube g", &color.g, 0.0f, 1.0f); - ImGui::SliderFloat("cube b", &color.b, 0.0f, 1.0f); - ImGui::SliderFloat("cube a", &color.a, 0.0f, 1.0f); + ImGui::SliderFloat("r", &color.r, 0.0f, 1.0f); + ImGui::SliderFloat("g", &color.g, 0.0f, 1.0f); + ImGui::SliderFloat("b", &color.b, 0.0f, 1.0f); + ImGui::SliderFloat("a", &color.a, 0.0f, 1.0f); ImGui::Text("Camera Properties"); - ImGui::SliderFloat("c_pitch", &camRot.x, -glm::pi(), glm::pi()); - ImGui::SliderFloat("c_yaw", &camRot.y, 0, 2 * glm::pi()); - ImGui::SliderFloat("c_roll", &camRot.z, -glm::pi(), glm::pi()); + ImGui::SliderFloat("cam pitch", &camRot.x, -glm::pi(), glm::pi()); + ImGui::SliderFloat("cam yaw", &camRot.y, 0, 2 * glm::pi()); + ImGui::SliderFloat("cam roll", &camRot.z, -glm::pi(), glm::pi()); - ImGui::SliderFloat("c_x", &camPos.x, -10.0f, 10.0f); - ImGui::SliderFloat("c_y", &camPos.y, -10.0f, 10.0f); - ImGui::SliderFloat("c_z", &camPos.z, -10.0f, 10.0f); + ImGui::SliderFloat("cam x", &camPos.x, -10.0f, 10.0f); + ImGui::SliderFloat("cam y", &camPos.y, -10.0f, 10.0f); + ImGui::SliderFloat("cam z", &camPos.z, -10.0f, 10.0f); if(ImGui::Button("Reset Window Size")) { @@ -209,23 +182,32 @@ bool Sandbox::onEvent(const Archimedes::Event& e) { unsigned int type = app->getEventType(e); + ImGuiIO& io = ImGui::GetIO(); (void)io; - if(type == app->getEventType(Archimedes::KeyPressedWindowEvent())) { + if(type == app->getEventType(Archimedes::KeyPressedWindowEvent()) && !io.WantCaptureKeyboard) { return false; - } else if(type == app->getEventType(Archimedes::KeyReleasedWindowEvent())) { + } else if(type == app->getEventType(Archimedes::KeyReleasedWindowEvent()) && !io.WantCaptureKeyboard) { return false; - } else if(type == app->getEventType(Archimedes::MouseButtonPressedWindowEvent())) { + } else if(type == app->getEventType(Archimedes::MouseButtonPressedWindowEvent()) && !io.WantCaptureMouse) { return false; - } else if(type == app->getEventType(Archimedes::MouseButtonReleasedWindowEvent())) { + } else if(type == app->getEventType(Archimedes::MouseButtonReleasedWindowEvent()) && !io.WantCaptureMouse) { return false; - } else if(type == app->getEventType(Archimedes::ScrollWindowEvent())) { + } else if(type == app->getEventType(Archimedes::ScrollWindowEvent()) && !io.WantCaptureMouse) { - return false; - } else if(type == app->getEventType(Archimedes::MouseMovedWindowEvent())) { + Archimedes::ScrollWindowEvent event = (Archimedes::ScrollWindowEvent&) e; + + //cube.rotateRel(glm::vec3(glm::pi() * event.dy / 50.0f, 0.0f, 0.0f)); + + //cube.rotateRel(glm::vec3(0.0f, glm::pi() * event.dx / 50.0f, 0.0f)); + + hexagon.scaleAdd(0.001f * event.dy); + + return true; + } else if(type == app->getEventType(Archimedes::MouseMovedWindowEvent()) && !io.WantCaptureMouse) { return false; } diff --git a/src/modules/Archimedes-Modules/Sandbox/Sandbox.h b/src/modules/Archimedes-Modules/Sandbox/Sandbox.h index ae82b47..6730854 100644 --- a/src/modules/Archimedes-Modules/Sandbox/Sandbox.h +++ b/src/modules/Archimedes-Modules/Sandbox/Sandbox.h @@ -6,6 +6,9 @@ #include "modules/WindowModule/WindowModule.h" #include "modules/ImguiModule/ImguiModule.h" +#include "utils/Objects/Body.h" +#include "utils/Objects/Camera.h" + class Sandbox : public Archimedes::Module { public: @@ -28,17 +31,19 @@ class Sandbox : public Archimedes::Module { std::string cubeVS = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "uniform mat4 model;\n" - "uniform uvec2 res;\n" + "uniform mat4 view;\n" + "uniform mat4 proj;\n" "uniform vec4 color;\n" "void main()\n" "{\n" - " gl_Position = model * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" + " gl_Position = proj * view * model * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" "}\0"; std::string cubeFS = "#version 330 core\n" "out vec4 FragColor;\n" "uniform mat4 model;\n" - "uniform uvec2 res;\n" + "uniform mat4 view;\n" + "uniform mat4 proj;\n" "uniform vec4 color;\n" "void main()\n" "{\n" @@ -47,16 +52,16 @@ class Sandbox : public Archimedes::Module { Archimedes::Shader cubeShader, gridShader; - Archimedes::RenderTarget cube, grid; + Archimedes::Body cube, grid, hexagon; - float gridVertices[24] = { + std::vector gridVertices = { -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, -1.0f, }; - unsigned int gridIndices[6] = { + std::vector gridIndices = { 0, 1, 2, @@ -65,7 +70,7 @@ class Sandbox : public Archimedes::Module { 0 }; - float vertices[24] = { + std::vector vertices = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, @@ -79,7 +84,7 @@ class Sandbox : public Archimedes::Module { }; - unsigned int indices[36] = { + std::vector indices = { 0, 1, 2,