From c40746b58420fb3413947d1530a17b45f0c11ea3 Mon Sep 17 00:00:00 2001 From: Joseph Walton-Rivers <joseph@walton-rivers.uk> Date: Sun, 7 Nov 2021 15:17:12 +0000 Subject: [PATCH] support for prototyping --- demo/main.cpp | 199 ++++++++++++++++++++---------------- fggl/data/storage.hpp | 5 +- fggl/debug/debug.cpp | 5 +- fggl/ecs/component.hpp | 26 +++++ fggl/ecs3/prototype/world.h | 105 +++++++++++++++++-- fggl/ecs3/types.hpp | 25 ++++- fggl/gfx/camera.hpp | 1 + fggl/gfx/common.hpp | 1 + fggl/gfx/ogl/compat.hpp | 11 +- fggl/gfx/ogl/renderer.cpp | 12 ++- fggl/gfx/ogl/renderer.hpp | 1 + fggl/gfx/ogl/shader.cpp | 7 +- fggl/math/types.hpp | 1 + tests/testfggl/ecs/ecs.cpp | 8 +- tests/testfggl/ecs3/ecs.cpp | 10 +- 15 files changed, 302 insertions(+), 115 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index 381e4b3..f58a635 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -206,7 +206,10 @@ void process_edgescroll(fggl::ecs3::World& ecs, InputManager input, fggl::ecs::e } -void process_camera(fggl::gfx::Window& window, fggl::ecs3::World& ecs, InputManager input, fggl::ecs::entity_t cam) { +void process_camera(fggl::gfx::Window& window, fggl::ecs3::World& ecs, InputManager input) { + auto cameras = ecs.findMatching<fggl::gfx::Camera>(); + fggl::ecs3::entity_t cam = cameras[0]; + auto camTransform = ecs.get<fggl::math::Transform>(cam); auto camComp = ecs.get<fggl::gfx::Camera>(cam); @@ -251,7 +254,7 @@ int main(int argc, char* argv[]) { auto glModule = modules.load<fggl::gfx::ecsOpenGLModule>(win, storage); fggl::gfx::loadPipeline(glModule, "unlit", false); - fggl::gfx::loadPipeline(glModule, "lighting/phong", false); + fggl::gfx::loadPipeline(glModule, "phong", false); fggl::gfx::loadPipeline(glModule, "normals", false); // debug layer @@ -261,56 +264,63 @@ int main(int argc, char* argv[]) { // create ECS types.make<fggl::math::Transform>(); - // make camera - auto camEnt = ecs.create(); - { - auto cameraTf = ecs.add<fggl::math::Transform>(camEnt); - cameraTf->origin( glm::vec3(0.0f, 3.0f, 3.0f) ); - - ecs.add<fggl::gfx::Camera>(camEnt); - } - - auto floorEnt = ecs.create(); + // create camera using strings + { + auto prototype = ecs.create(false); + ecs.add(prototype, types.find(fggl::math::Transform::name)); + ecs.add(prototype, types.find(fggl::gfx::Camera::name)); + + auto camTf = ecs.get<fggl::math::Transform>(prototype); + camTf->origin( glm::vec3(0.0f, 3.0f, 3.0f) ); + } + + // create building prototype + fggl::ecs3::entity_t bunker; + { + bunker = ecs.create(true); + ecs.add(bunker, types.find(fggl::math::Transform::name)); + + // mesh + int nSections = 2; + constexpr float HALF_PI = M_PI / 2.0f; + constexpr char shader[] = "phong"; + + fggl::data::Mesh mesh; + for (int j=-(nSections/2); j<=nSections/2; j++) { + const auto shapeOffset = glm::vec3( 0.0f, 0.0f, j * 1.0f ); + + const auto cubeMat = glm::translate( fggl::math::mat4( 1.0f ) , shapeOffset ); + const auto leftSlope = fggl::math::modelMatrix( + glm::vec3(-1.0f, 0.0f, 0.0f) + shapeOffset, + glm::vec3( 0.0f, -HALF_PI, 0.0f) ); + const auto rightSlope = fggl::math::modelMatrix( + glm::vec3( 1.0f, 0.0f, 0.0f) + shapeOffset, + glm::vec3( 0.0f, HALF_PI, 0.0f) ); + + fggl::data::make_cube( mesh, cubeMat ); + fggl::data::make_slope( mesh, leftSlope ); + fggl::data::make_slope( mesh, rightSlope ); + } + mesh.removeDups(); + + fggl::gfx::StaticMesh staticMesh{mesh, shader}; + ecs.set<fggl::gfx::StaticMesh>(bunker, &staticMesh); + } + + auto floorEnt = ecs.create(false); { ecs.add<fggl::math::Transform>( floorEnt ); fggl::data::Mesh mesh = fggl::data::make_quad_xz(); - fggl::gfx::StaticMesh sMesh{mesh, "lighting/phong"}; + fggl::gfx::StaticMesh sMesh{mesh, "phong"}; ecs.set<fggl::gfx::StaticMesh>(floorEnt, &sMesh); } - int nCubes = 3; - int nSections = 2; - - constexpr float HALF_PI = M_PI / 2.0f; - + int nCubes = 3; for ( int i=0; i<nCubes; i++ ) { - auto entity = ecs.create(); - - // set the position - auto result = ecs.add<fggl::math::Transform>(entity); + auto bunkerClone = ecs.copy(bunker); + auto result = ecs.get<fggl::math::Transform>(bunkerClone); result->origin( glm::vec3( i * 5.0f, 0.0f, 0.0f) ); - - fggl::data::Mesh mesh; - for (int j=-(nSections/2); j<=nSections/2; j++) { - const auto shapeOffset = glm::vec3( 0.0f, 0.0f, j * 1.0f ); - - const auto cubeMat = glm::translate( fggl::math::mat4( 1.0f ) , shapeOffset ); - const auto leftSlope = fggl::math::modelMatrix( - glm::vec3(-1.0f, 0.0f, 0.0f) + shapeOffset, - glm::vec3( 0.0f, -HALF_PI, 0.0f) ); - const auto rightSlope = fggl::math::modelMatrix( - glm::vec3( 1.0f, 0.0f, 0.0f) + shapeOffset, - glm::vec3( 0.0f, HALF_PI, 0.0f) ); - - fggl::data::make_cube( mesh, cubeMat ); - fggl::data::make_slope( mesh, leftSlope ); - fggl::data::make_slope( mesh, rightSlope ); - } - mesh.removeDups(); - - fggl::gfx::StaticMesh staticMesh{mesh, "lighting/phong"}; - ecs.set<fggl::gfx::StaticMesh>(entity, &staticMesh); } bool gamepadWindow = true; @@ -333,51 +343,68 @@ int main(int argc, char* argv[]) { // // update step // - process_camera(win, ecs, inputs, camEnt); + process_camera(win, ecs, inputs); + + // ECS3 inspector + ImGui::Begin("Entities"); + auto entityItr = ecs.all(); + for (auto& entity : entityItr) { + std::string label = "entity-" + std::to_string(entity); + if ( ImGui::TreeNode(label.c_str()) ){ + auto entComp = ecs.getComponents(entity); + for ( auto comp : entComp ){ + auto meta = types.meta(comp); + ImGui::Text("%s (%d) - %lu bytes", meta->name(), comp, meta->size()); + } + ImGui::TreePop(); + } + } + ImGui::End(); // imgui gamepad debug - auto& gamepads = inputs->gamepads; - ImGui::Begin("GamePad", &gamepadWindow); - for ( int i=0; i<16; i++ ) { - std::string title = gamepads.name(i); - - bool present = gamepads.present(i); - if ( ImGui::TreeNode(title.c_str()) ) { - ImGui::Text("present: %s", present ? "yes" : "no" ); - - if ( present ) { - - if ( ImGui::TreeNode("buttons##2") ) { - for ( auto& btn : fggl::input::GamepadButtonsMicrosoft ) { - ImGui::Text( "%s: %i %i %i", btn.name, - gamepads.button(i, btn.id), - gamepads.buttonPressed(i, btn.id), - gamepads.buttonReleased(i, btn.id) - ); - } - ImGui::TreePop(); - } - - if ( ImGui::TreeNode("axes##2") ) { - for ( auto& axis : fggl::input::GamepadAxes ) { - ImGui::Text("%s: %f %f", axis.name, - gamepads.axis(i, axis.id), - gamepads.axisDelta(i, axis.id) - ); - - } - ImGui::TreePop(); - } - - } - - ImGui::TreePop(); - ImGui::Separator(); - } - - } - ImGui::End(); - debug.showDemo(); + if ( gamepadWindow ) { + auto &gamepads = inputs->gamepads; + ImGui::Begin("GamePad", &gamepadWindow); + for (int i = 0; i < 16; i++) { + std::string title = gamepads.name(i); + + bool present = gamepads.present(i); + if (ImGui::TreeNode(title.c_str())) { + ImGui::Text("present: %s", present ? "yes" : "no"); + + if (present) { + + if (ImGui::TreeNode("buttons##2")) { + for (auto &btn: fggl::input::GamepadButtonsMicrosoft) { + ImGui::Text("%s: %i %i %i", btn.name, + gamepads.button(i, btn.id), + gamepads.buttonPressed(i, btn.id), + gamepads.buttonReleased(i, btn.id) + ); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("axes##2")) { + for (auto &axis: fggl::input::GamepadAxes) { + ImGui::Text("%s: %f %f", axis.name, + gamepads.axis(i, axis.id), + gamepads.axisDelta(i, axis.id) + ); + + } + ImGui::TreePop(); + } + + } + + ImGui::TreePop(); + ImGui::Separator(); + } + + } + ImGui::End(); + } // // render step diff --git a/fggl/data/storage.hpp b/fggl/data/storage.hpp index a963642..9e2ba22 100644 --- a/fggl/data/storage.hpp +++ b/fggl/data/storage.hpp @@ -21,10 +21,9 @@ namespace fggl::data { bool load(StorageType pool, const std::string& name, T* out) { auto path = resolvePath(pool, name); if ( !std::filesystem::exists(path) ) { - std::cerr << "path does not exist! " << path << std::endl; + std::cerr << "path " << path << " does not exist! " << std::endl; return false; } - return fggl_deserialize<T>(path, out); } @@ -39,7 +38,7 @@ namespace fggl::data { switch ( pool ) { case Data: - path = std::filesystem::current_path() / "res"; + path = std::filesystem::current_path() / "data"; break; case User: path = "./user-data/"; diff --git a/fggl/debug/debug.cpp b/fggl/debug/debug.cpp index a9117e0..399fa24 100644 --- a/fggl/debug/debug.cpp +++ b/fggl/debug/debug.cpp @@ -11,7 +11,10 @@ DebugUI::DebugUI(Window& win) : m_visible(false) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); - ImGui_ImplGlfw_InitForOpenGL(win.handle(), true); + ImGuiIO& io = ImGui::GetIO(); + io.IniFilename = NULL; + + ImGui_ImplGlfw_InitForOpenGL(win.handle(), true); ImGui_ImplOpenGL3_Init("#version 130"); } diff --git a/fggl/ecs/component.hpp b/fggl/ecs/component.hpp index 36e5a5f..51edda3 100644 --- a/fggl/ecs/component.hpp +++ b/fggl/ecs/component.hpp @@ -5,6 +5,7 @@ #include <cassert> #include <cstring> +#include <string> #include <new> #include <utility> @@ -18,11 +19,19 @@ namespace fggl::ecs { using data_t = unsigned char; virtual ~ComponentBase() {}; + // in place virtual void destroy(data_t* data) const = 0; virtual void move(data_t* src, data_t* dest) const = 0; virtual void bulkMove(data_t* src, data_t* dest, std::size_t count) = 0; virtual void construct(data_t* data) const = 0; + // virtual + virtual void* construct() const = 0; + virtual void* copyConstruct(const void* src) = 0; + + virtual const char* name() const = 0; + virtual const component_type_t id() const = 0; + virtual std::size_t size() const = 0; }; @@ -34,10 +43,27 @@ namespace fggl::ecs { location->~C(); } + virtual const char* name() const override { + return C::name; + } + + virtual const component_type_t id() const { + return Component<C>::typeID(); + } + virtual void construct(unsigned char* data) const override { new (data) C(); } + void* copyConstruct(const void* src) override { + const C* srcPtr = (C*)src; + return new C(*srcPtr); + } + + void* construct() const override { + return new C(); + } + virtual void move(data_t* src, data_t* dest) const override { assert(src != nullptr); assert(dest != nullptr); diff --git a/fggl/ecs3/prototype/world.h b/fggl/ecs3/prototype/world.h index 52000ee..74b59b2 100644 --- a/fggl/ecs3/prototype/world.h +++ b/fggl/ecs3/prototype/world.h @@ -18,7 +18,12 @@ namespace fggl::ecs3::prototype { class Entity { public: - Entity(entity_t id) : m_id() {}; + bool m_abstract; + + explicit Entity(entity_t id) : m_id(id), m_abstract(false) {}; + Entity(const Entity& entity) : m_id(entity.m_id), m_components(entity.m_components) { + std::cerr << "someone be doing one of them copy things: " << m_id << std::endl; + } ~Entity() = default; template<typename C> @@ -28,6 +33,12 @@ namespace fggl::ecs3::prototype { return ptr; } + void* add(std::shared_ptr<ComponentBase> t) { + void* ptr = t->construct(); + m_components[t->id()] = ptr; + return ptr; + } + template<typename C> C* set(const C* ptr) { C* newPtr = new C(*ptr); @@ -35,12 +46,30 @@ namespace fggl::ecs3::prototype { return newPtr; } + void* set(const std::shared_ptr<ComponentBase>& t, const void* ptr) { + void* newPtr = t->copyConstruct(ptr); + m_components[t->id()] = newPtr; + return newPtr; + } + template<typename C> C* get() { void* ptr = m_components.at(Component<C>::typeID()); return (C*)ptr; } + inline void* get(component_type_t t){ + return m_components.at(t); + } + + std::vector<component_type_t> getComponentIDs() { + std::vector<component_type_t> comps{}; + for (auto& [k,_] : m_components) { + comps.push_back(k); + } + return comps; + } + bool hasComponents(std::vector<component_type_t>& Cs) { for (auto c : Cs) { if ( m_components.find(c) == m_components.end() ) { @@ -58,20 +87,59 @@ namespace fggl::ecs3::prototype { class World { public: - World(TypeRegistry& reg) : m_types(reg), m_next(0), m_entities() {}; + explicit World(TypeRegistry& reg) : m_types(reg), m_next(1), m_entities() {}; ~World() = default; - entity_t create() { + entity_t create(bool abstract) { auto nextID = m_next++; m_entities.emplace(nextID, nextID); + + auto& entity = m_entities.at(nextID); + entity.m_abstract = abstract; + + // meta data + auto* meta = entity.add<ecs3::EntityMeta>(); + meta->id = nextID; + meta->abstract = abstract; + return nextID; } + entity_t copy(entity_t prototype) { + auto clone = create(false); + + auto components = getComponents(prototype); + for (auto component : components) { + auto protoComp = get(prototype, component); + set(clone, component, protoComp); + } + + return clone; + } + void destroy(entity_t entity) { // TOOD resolve and clean components m_entities.erase(entity); } + std::vector<entity_t> all() { + std::vector<entity_t> entities{}; + for( auto& [eid, entity] : m_entities) { + entities.push_back(eid); + } + return entities; + } + + std::vector<component_type_t> getComponents(entity_t entityID){ + std::vector<component_type_t> components{}; + auto& entity = m_entities.at(entityID); + auto comps = entity.getComponentIDs(); + for (auto id : comps) { + components.push_back(id); + } + return components; + } + template<typename... Cs> std::vector<entity_t> findMatching() { // construct the key @@ -81,7 +149,7 @@ namespace fggl::ecs3::prototype { // entities std::vector<entity_t> entities{}; for( auto& [eid, entity] : m_entities) { - if ( entity.hasComponents(key) ) { + if ( entity.hasComponents(key) && !entity.m_abstract ) { entities.push_back(eid); } } @@ -91,19 +159,39 @@ namespace fggl::ecs3::prototype { template<typename C> C* add(entity_t entity_id) { + std::cerr << "[>>] adding comp " << C::name << " to " << entity_id << std::endl; auto& entity = m_entities.at(entity_id); auto comp = entity.template add<C>(); - m_types.fireAdd(*this, entity_id, Component<C>::typeID()); + m_types.fireAdd(this, entity_id, Component<C>::typeID()); return comp; } + void* add(entity_t entity_id, component_type_t component_id) { + auto meta = m_types.meta(component_id); + auto& entity = m_entities.at(entity_id); + + void* ptr = entity.add(meta); + m_types.fireAdd(this, entity_id, meta->id()); + return ptr; + } + template<typename C> C* set(entity_t entity_id, const C* ptr) { + std::cerr << "[>>] setting comp " << C::name << " to " << entity_id << std::endl; auto& entity = m_entities.at(entity_id); auto comp = entity.set<C>(ptr); - m_types.fireAdd(*this, entity_id, Component<C>::typeID()); + m_types.fireAdd(this, entity_id, Component<C>::typeID()); + return comp; + } + + void* set(entity_t entity_id, component_type_t cid, const void* ptr){ + auto& entity = m_entities.at(entity_id); + auto cMeta = m_types.meta(cid); + + auto comp = entity.set(cMeta, ptr); + m_types.fireAdd(this, entity_id, cid); return comp; } @@ -113,6 +201,11 @@ namespace fggl::ecs3::prototype { return entity.get<C>(); } + void* get(entity_t entity_id, component_type_t t){ + auto& entity = m_entities.at(entity_id); + return entity.get(t); + } + private: TypeRegistry& m_types; entity_t m_next; diff --git a/fggl/ecs3/types.hpp b/fggl/ecs3/types.hpp index 14aff89..fb0fe4f 100644 --- a/fggl/ecs3/types.hpp +++ b/fggl/ecs3/types.hpp @@ -26,14 +26,16 @@ namespace fggl::ecs3 { using fggl::ecs::component_type_t; class ModuleManager; - using callback_t = std::function<void(prototype::World&, ecs3::entity_t)>; + using callback_t = std::function<void(prototype::World*, ecs3::entity_t)>; struct TypeCallbacks { std::vector<callback_t> add; }; // core component types struct EntityMeta { + constexpr static const char name[] = "meta"; entity_t id; + bool abstract; }; struct RecordIdentifier { @@ -175,6 +177,15 @@ namespace fggl::ecs3 { return m_types.at( type_id ); } + inline component_type_t find(const char* name) const { + for (auto& [type, meta] : m_types) { + if ( std::strcmp(name, meta->name()) == 0) { + return type; + } + } + return 0; + } + inline void make_virtual(std::shared_ptr<ComponentBase> vtype) { auto type_id = m_last_virtual++; m_types[type_id] = std::move(vtype); @@ -184,10 +195,14 @@ namespace fggl::ecs3 { m_callbacks[component].add.push_back(callback); } - void fireAdd(prototype::World& world, entity_t entity, component_type_t type) { - auto& callbacks = m_callbacks[type].add; - for ( auto& callback : callbacks) { - callback(world, entity); + void fireAdd(prototype::World* world, entity_t entity, component_type_t type) { + try { + auto& callbacks = m_callbacks.at(type).add; + for ( auto& callback : callbacks) { + callback(world, entity); + } + } catch ( std::out_of_range& e) { + std::cerr << "no callbacks for: " << m_types[type]->name() << std::endl; } } diff --git a/fggl/gfx/camera.hpp b/fggl/gfx/camera.hpp index 0e0a48e..c1eaa43 100644 --- a/fggl/gfx/camera.hpp +++ b/fggl/gfx/camera.hpp @@ -6,6 +6,7 @@ namespace fggl::gfx { struct Camera { + constexpr const static char name[] = "Camera"; math::vec3 target = math::vec3(0.0f, 0.0f, 0.0f); float aspectRatio = 1280.0f / 720.0f; float fov = glm::radians(45.0f); diff --git a/fggl/gfx/common.hpp b/fggl/gfx/common.hpp index c8376f3..71101f5 100644 --- a/fggl/gfx/common.hpp +++ b/fggl/gfx/common.hpp @@ -14,6 +14,7 @@ namespace fggl::gfx { struct StaticMesh { + constexpr static const char name[] = "StaticMesh"; data::Mesh mesh; std::string pipeline; diff --git a/fggl/gfx/ogl/compat.hpp b/fggl/gfx/ogl/compat.hpp index d84a05e..fd761c6 100644 --- a/fggl/gfx/ogl/compat.hpp +++ b/fggl/gfx/ogl/compat.hpp @@ -36,15 +36,14 @@ namespace fggl::gfx { return "gfx::opengl"; } - void uploadMesh(ecs3::World& world, ecs::entity_t entity) { - std::cerr << "[!!] I be firein me shaders!" << std::endl; - auto meshData = world.get<gfx::StaticMesh>(entity); + void uploadMesh(ecs3::World* world, ecs::entity_t entity) { + auto meshData = world->get<gfx::StaticMesh>(entity); auto pipeline = cache.get(meshData->pipeline); auto glMesh = renderer.upload(meshData->mesh); glMesh.pipeline = pipeline; - world.set<fggl::gfx::GlRenderToken>(entity, &glMesh); + world->set<fggl::gfx::GlRenderToken>(entity, &glMesh); } void onLoad(ecs3::ModuleManager& manager, ecs3::TypeRegistry& types) override { @@ -84,7 +83,8 @@ namespace fggl::gfx { // // fake module/callbacks - our ECS doesn't have module/callback support yet. // - inline void onStaticMeshAdded(ecs3::World& ecs, ecs::entity_t entity, OglModule& mod) { + void onStaticMeshAdded(ecs3::World& ecs, ecs::entity_t entity, OglModule& mod) { + std::cerr << "[CALLBACK] static mesh added, renderable?" << std::endl; /* auto meshData = ecs.get<gfx::StaticMesh>(entity); auto pipeline = mod->cache.get(meshData->pipeline); @@ -106,6 +106,7 @@ namespace fggl::gfx { // get the models auto renderables = ecs.findMatching<fggl::gfx::GlRenderToken>(); + for ( auto renderable : renderables ) { mod->renderer.render(ecs, camera, dt); } diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp index 0e8e983..eff7e8e 100644 --- a/fggl/gfx/ogl/renderer.cpp +++ b/fggl/gfx/ogl/renderer.cpp @@ -48,7 +48,7 @@ static GLuint createIndexBuffer(std::vector<uint32_t>& indexData) { } GlRenderToken MeshRenderer::upload(fggl::data::Mesh& mesh) { - GlRenderToken token; + GlRenderToken token{}; glGenVertexArrays(1, &token.vao); glBindVertexArray(token.vao); @@ -67,10 +67,16 @@ GlRenderToken MeshRenderer::upload(fggl::data::Mesh& mesh) { } void MeshRenderer::render(fggl::ecs3::World& ecs, ecs3::entity_t camera, float dt) { - if ( camera == ecs::NULL_ENTITY ) return; + if ( camera == ecs::NULL_ENTITY ){ + std::cerr << "no camera" << std::endl; + return; + } auto entities = ecs.findMatching<GlRenderToken>(); - if ( entities.size() == 0 ) return; + if ( entities.empty() ) { + std::cerr << "no entities with render tokens" << std::endl; + return; + } total += dt; diff --git a/fggl/gfx/ogl/renderer.hpp b/fggl/gfx/ogl/renderer.hpp index 5932068..b13647f 100644 --- a/fggl/gfx/ogl/renderer.hpp +++ b/fggl/gfx/ogl/renderer.hpp @@ -10,6 +10,7 @@ namespace fggl::gfx { struct GlRenderToken { + constexpr static const char name[] = "RenderToken"; GLuint vao; GLuint buffs[2]; GLuint idxOffset; diff --git a/fggl/gfx/ogl/shader.cpp b/fggl/gfx/ogl/shader.cpp index 3d91705..c3558de 100644 --- a/fggl/gfx/ogl/shader.cpp +++ b/fggl/gfx/ogl/shader.cpp @@ -10,9 +10,12 @@ bool ShaderCache::compileShader(const std::string& fname, GLuint sid) { std::string source; bool result = m_storage.load(fggl::data::Data, fname, &source); if ( !result ) { + std::cerr << ">> Error loading file: " << fname << std::endl; return false; } + std::cerr << "source for " << fname << " is " << source << std::endl; + // upload and compile shader const auto *src_cstr = (const GLchar *)source.c_str(); glShaderSource(sid, 1, &src_cstr, 0); @@ -85,6 +88,8 @@ GLuint ShaderCache::get(const std::string& name) { GLuint ShaderCache::load(const ShaderConfig& config) { + std::cerr << "Starting program generation: " << config.name << std::endl; + GLuint pid = glCreateProgram(); if ( m_binary ) { @@ -95,7 +100,7 @@ GLuint ShaderCache::load(const ShaderConfig& config) { return pid; } - std::cerr << "could not load cached shader, taking the long route" << std::endl; + std::cerr << ">> could not load cached shader, taking the long route" << std::endl; } // TODO actual shader loading diff --git a/fggl/math/types.hpp b/fggl/math/types.hpp index e4b3c46..0f75cf6 100644 --- a/fggl/math/types.hpp +++ b/fggl/math/types.hpp @@ -32,6 +32,7 @@ namespace fggl::math { } struct Transform { + constexpr static const char name[] = "Transform"; Transform() : m_local(1.0f), m_origin(0.0f), m_model(1.0f), m_rotation() { } diff --git a/tests/testfggl/ecs/ecs.cpp b/tests/testfggl/ecs/ecs.cpp index ed8ab1b..86c4e3e 100644 --- a/tests/testfggl/ecs/ecs.cpp +++ b/tests/testfggl/ecs/ecs.cpp @@ -7,15 +7,19 @@ using fggl::ecs::Component; namespace { - class DummyComp1 : public Component<DummyComp1> { + class DummyComp1 { + public: + constexpr static const char* name = "DummyComp1"; }; - class DummyComp2 : public Component<DummyComp2> { + class DummyComp2 { public: + constexpr static const char* name = "DummyComp2"; int x; DummyComp2() : x(0) {} DummyComp2(int tmp) : x(tmp) { } + DummyComp2( const DummyComp2& other) : x(other.x) {} DummyComp2( DummyComp2&& other ) : x(other.x) {} }; diff --git a/tests/testfggl/ecs3/ecs.cpp b/tests/testfggl/ecs3/ecs.cpp index 74d5cab..e5689c1 100644 --- a/tests/testfggl/ecs3/ecs.cpp +++ b/tests/testfggl/ecs3/ecs.cpp @@ -8,17 +8,21 @@ using fggl::ecs::Component; namespace { class DummyComp4 { - bool a; - bool b; - bool c; + public: + constexpr static const char* name = "DummyComp2"; + bool a; + bool b; + bool c; }; class DummyComp3 { public: + constexpr static const char* name = "DummyComp2"; int x; DummyComp3() = default; DummyComp3(int tmp) : x(tmp) { } + DummyComp3( const DummyComp3& other ) : x(other.x) {} DummyComp3( DummyComp3&& other ) : x(other.x) {} }; -- GitLab