render obj file

This commit is contained in:
2026-02-19 07:54:54 -06:00
parent fec99fc737
commit 74c980adb0
21 changed files with 1 additions and 1865 deletions

View File

@@ -1,11 +0,0 @@
#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

View File

@@ -1 +0,0 @@
#include "pch.hpp"

View File

@@ -1,285 +0,0 @@
#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<std::string> 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<std::string>::iterator roInsert;
inline static App* instance = nullptr;
unsigned int nextEventType = 0;
protected:
bool done = false;
std::unordered_map<std::string, Module*> modules;
std::unordered_map<std::string, unsigned int> eventTypes;
std::list<Event*> events;
std::list<std::string> runOrder;
std::list<std::string> toClose;
std::list<std::variant<std::string, Module*>> 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<std::string, Module*> 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<std::string>(*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<std::string>(it.second))
m->moduleInstances[it.first] = load(std::get<std::string>(it.second));
else
m->moduleInstances[it.first] = load(std::get<Module*>(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

View File

@@ -1,51 +0,0 @@
#ifndef AUDIO_H
#define AUDIO_H
#include "pch.hpp"
#include <SDL3/SDL.h>
#include <SDL3/SDL_audio.h>
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<SDL_AudioStream*> streams;
std::vector<SDL_AudioSpec> specs;
};
}
#endif

View File

@@ -1,88 +0,0 @@
#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<std::string, Module*> n) : module(n) {}
~DoLoadModuleEvent() {}
operator std::string() const override { return "DoLoadModuleEvent"; }
std::variant<std::string, Module*> 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

View File

@@ -1,25 +0,0 @@
#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

View File

@@ -1,59 +0,0 @@
#ifndef NETWORKEVENTS_H
#define NETWORKEVENTS_H
#include "Event.h"
#include <steam/steamnetworkingsockets.h>
#include <steam/isteamnetworkingutils.h>
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

View File

@@ -1,48 +0,0 @@
#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<std::string, std::variant<std::string, Module*>> deps;
std::unordered_map<std::string, std::variant<std::string, Module*>> exts;
std::unordered_map<std::string, Module*> moduleInstances;
};
}
#endif

View File

@@ -1,32 +0,0 @@
#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

View File

@@ -1,25 +0,0 @@
#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

View File

@@ -1,75 +0,0 @@
#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

View File

@@ -1,194 +0,0 @@
#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<LayoutElement>& getElements() const { return elements; }
private:
std::vector<LayoutElement> 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

View File

@@ -1,67 +0,0 @@
#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

View File

@@ -1,268 +0,0 @@
#ifdef RENDERER_OPENGL
#ifndef RENDERER_OPENGL_H
#define RENDERER_OPENGL_H
#include "pch.hpp"
#include "utils/Renderer/Renderer.h"
#define GLEW_STATIC
#include <GL/glew.h>
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

View File

@@ -1,43 +0,0 @@
#ifdef RENDERER_SDL3
#ifndef RENDERER_SDL3_H
#define RENDERER_SDL3_H
#include "pch.hpp"
#include <SDL3/SDL.h>
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<std::function<void()>> 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

View File

@@ -1,66 +0,0 @@
#ifndef WINDOW_H
#define WINDOW_H
#include "WindowEvents.h"
#include "utils/Renderer/Renderer.h"
namespace Archimedes {
class Window {
public:
Window(const std::function<void(Event*)>& 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<void(Event*)> eventFn;
};
}
#endif

View File

@@ -1,220 +0,0 @@
#ifndef WINDOWEVENTS_H
#define WINDOWEVENTS_H
#include "utils/Events/Event.h"
//implimentation independent events
namespace Archimedes {
class Window;
struct WindowData {
Window* window;
std::list<Event*> eventList;
std::function<void(Event*)> 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

View File

@@ -1,146 +0,0 @@
#ifdef WINDOW_GLFW
#ifndef WINDOW_GLFW_H
#define WINDOW_GLFW_H
#include "pch.hpp"
#include "utils/Window/Window.h"
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
namespace Archimedes {
class WindowGLFW : public Window {
public:
WindowGLFW(const std::function<void(Event*)>& 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

View File

@@ -1,161 +0,0 @@
#ifdef WINDOW_SDL3
#ifndef WINDOW_SDL3_H
#define WINDOW_SDL3_H
#include "pch.hpp"
#include "utils/Window/Window.h"
#include <SDL3/SDL.h>
#ifdef RENDERER_OPENGL
#include <SDL3/SDL_opengl.h>
#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<void(Event*)>& 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

View File

@@ -2,6 +2,7 @@
#define PCH_HPP
#include <iostream>
#include <memory>
#include <fstream>
#include <cstring>
#include <cassert>