diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj
index fa4aaab..6cfa75b 100644
--- a/CopiumEngine/CopiumEngine.vcxproj
+++ b/CopiumEngine/CopiumEngine.vcxproj
@@ -172,16 +172,20 @@
+
+
+
+
@@ -236,8 +240,10 @@
+
+
@@ -246,6 +252,10 @@
+
+
+
+
@@ -259,6 +269,10 @@
+
+
+
+
diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters
index 9558e2a..36e42e6 100644
--- a/CopiumEngine/CopiumEngine.vcxproj.filters
+++ b/CopiumEngine/CopiumEngine.vcxproj.filters
@@ -198,6 +198,18 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
@@ -410,5 +422,35 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/asset/AssetRef.cpp b/CopiumEngine/src/copium/asset/AssetRef.cpp
new file mode 100644
index 0000000..9842da7
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/AssetRef.cpp
@@ -0,0 +1,58 @@
+#include "copium/asset/AssetRef.h"
+
+#include "copium/asset/AssetManager.h"
+
+namespace Copium
+{
+ AssetRef::AssetRef(AssetHandle handle)
+ : handle{handle}, refCounter{new int{1}}
+ {}
+
+ AssetRef::~AssetRef()
+ {
+ if (refCounter == nullptr)
+ return;
+
+ (*refCounter)--;
+ if (*refCounter == 0)
+ {
+ AssetManager::UnloadAsset(handle);
+ delete refCounter;
+ }
+ }
+
+ AssetRef::AssetRef(const AssetRef& other)
+ : handle{other.handle}, refCounter{other.refCounter}
+ {
+ (*refCounter)++;
+ }
+
+ AssetRef::AssetRef(AssetRef&& other)
+ : handle{other.handle}, refCounter{other.refCounter}
+ {
+ other.refCounter = nullptr;
+ }
+
+ AssetRef& AssetRef::operator=(const AssetRef& rhs)
+ {
+ handle = rhs.handle;
+ refCounter = rhs.refCounter;
+
+ (*refCounter)++;
+ return *this;
+ }
+
+ AssetRef& AssetRef::operator=(AssetRef&& rhs)
+ {
+ handle = rhs.handle;
+ refCounter = rhs.refCounter;
+ rhs.refCounter = nullptr;
+ return *this;
+ }
+
+ AssetRef::operator AssetHandle() const
+ {
+ return handle;
+
+ }
+}
diff --git a/CopiumEngine/src/copium/asset/AssetRef.h b/CopiumEngine/src/copium/asset/AssetRef.h
new file mode 100644
index 0000000..2885265
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/AssetRef.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "copium/asset/AssetMeta.h"
+
+namespace Copium
+{
+ class AssetRef
+ {
+ private:
+ AssetHandle handle;
+ int* refCounter;
+
+ public:
+ AssetRef(AssetHandle handle);
+ ~AssetRef();
+
+ AssetRef(const AssetRef& other);
+ AssetRef(AssetRef&& other);
+
+ AssetRef& operator=(const AssetRef& rhs);
+ AssetRef& operator=(AssetRef&& rhs);
+
+ operator AssetHandle() const;
+ };
+
+}
diff --git a/CopiumEngine/src/copium/core/Application.cpp b/CopiumEngine/src/copium/core/Application.cpp
index 8af67c0..d5e6b33 100644
--- a/CopiumEngine/src/copium/core/Application.cpp
+++ b/CopiumEngine/src/copium/core/Application.cpp
@@ -48,20 +48,18 @@ namespace Copium
{
EventDispatcher::AddEventHandler(this);
InitializeFrameBuffer();
- InitializeRenderer();
InitializeGraphicsPipeline();
InitializeTextureSampler();
InitializeDescriptorSets();
InitializeMesh();
InitializeCommandBuffer();
+ InitializeScene();
}
Application::~Application()
{
vkDeviceWaitIdle(Vulkan::GetDevice());
AssetManager::UnloadAsset(texture2D);
- AssetManager::UnloadAsset(texture2D2);
- AssetManager::UnloadAsset(font);
AssetManager::UnloadAsset(graphicsPipeline);
AssetManager::UnloadAsset(graphicsPipelinePassthrough);
AssetManager::UnloadAsset(framebuffer);
@@ -92,6 +90,7 @@ namespace Copium
EventResult Application::OnEvent(const Event& event)
{
+ scene->OnEvent(event);
switch (event.GetType())
{
case EventType::WindowResize:
@@ -150,16 +149,14 @@ namespace Copium
framebuffer = AssetManager::LoadAsset("framebuffer.meta");
}
- void Application::InitializeRenderer()
+ void Application::InitializeScene()
{
- renderer = std::make_unique();
+ scene = std::make_unique(*commandBuffer, *descriptorPool);
}
void Application::InitializeTextureSampler()
{
texture2D = AssetManager::LoadAsset("fox.meta");
- texture2D2 = AssetManager::LoadAsset("fox2.meta");
- font = AssetManager::LoadAsset("font.meta");
}
void Application::InitializeDescriptorSets()
@@ -171,8 +168,6 @@ namespace Copium
descriptorSetPassthrough = AssetManager::GetAsset(graphicsPipelinePassthrough).CreateDescriptorSet(*descriptorPool, 0);
descriptorSetPassthrough->SetSampler(AssetManager::GetAsset(framebuffer).GetColorAttachment(), 0);
-
- descriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(*descriptorPool, 1);
}
void Application::InitializeGraphicsPipeline()
@@ -209,25 +204,7 @@ namespace Copium
mesh->Bind(*commandBuffer);
mesh->Render(*commandBuffer);
- renderer->SetDescriptorSet(*descriptorSetRenderer);
- renderer->Begin(*commandBuffer);
- for (int y = 0; y < 10; y++)
- {
- for (int x = 0; x < 10; x++)
- {
- renderer->Quad(glm::vec2{-1 + x * 0.2 + 0.05, -1 + y * 0.2 + 0.05}, glm::vec2{0.1, 0.1}, glm::vec3{x * 0.1, y * 0.1, 1.0});
- }
- }
- float aspect = fb.GetWidth() / (float)fb.GetHeight();
- renderer->Quad(glm::vec2{-0.8, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset(texture2D));
- renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset(font));
- renderer->Quad(mousePos - glm::vec2(0.1), glm::vec2{0.2}, AssetManager::GetAsset(texture2D2));
- std::string s = std::to_string(fps) + " fps";
- BoundingBox boundingBox = AssetManager::GetAsset(font).GetTextBoundingBox(s, 0.06);
- glm::vec2 pos = glm::vec2{-aspect + 0.01, 0.94};
- renderer->Quad(pos + boundingBox.lb, boundingBox.GetSize());
- renderer->Text(s, pos, AssetManager::GetAsset(font), 0.06, glm::vec3{0.0f});
- renderer->End();
+ scene->Update();
fb.Unbind(*commandBuffer);
@@ -252,7 +229,6 @@ namespace Copium
float time = startTimer.Elapsed();
Framebuffer& fb = AssetManager::GetAsset(framebuffer);
float aspect = fb.GetWidth() / (float)fb.GetHeight();
- time = 0;
{
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 10.0f);
@@ -265,13 +241,5 @@ namespace Copium
uniformBuffer.Set("lightPos", (glm::vec3)(glm::rotate(glm::mat4{1.0f}, time * glm::radians(45.0f), glm::vec3(0, 1, 0)) * glm::vec4{0.3, 0.1, 0, 1}));
uniformBuffer.Update();
}
-
- {
- UniformBuffer& uniformBuffer = descriptorSetRenderer->GetUniformBuffer("ubo");
- uniformBuffer.Set("projection", glm::ortho(-aspect, aspect, 1.0f, -1.0f));
- // uniformBuffer.Set("view", glm::translate(glm::mat4(1), glm::vec3(0.1 * glm::sin(4 * time), 0.1 * glm::cos(4 * time), 0.0)));
- uniformBuffer.Set("view", glm::mat4(1));
- uniformBuffer.Update();
- }
}
}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/core/Application.h b/CopiumEngine/src/copium/core/Application.h
index 73df2d9..e397f2a 100644
--- a/CopiumEngine/src/copium/core/Application.h
+++ b/CopiumEngine/src/copium/core/Application.h
@@ -1,6 +1,7 @@
#pragma once
#include "copium/asset/AssetMeta.h"
+#include "copium/core/Scene.h"
#include "copium/buffer/Framebuffer.h"
#include "copium/event/EventHandler.h"
#include "copium/mesh/Mesh.h"
@@ -15,7 +16,6 @@ namespace Copium
{
CP_DELETE_COPY_AND_MOVE_CTOR(Application);
private:
- std::unique_ptr renderer;
AssetHandle framebuffer;
AssetHandle texture2D;
AssetHandle texture2D2;
@@ -25,7 +25,7 @@ namespace Copium
std::unique_ptr descriptorPool;
std::unique_ptr descriptorSet;
std::unique_ptr descriptorSetPassthrough;
- std::unique_ptr descriptorSetRenderer;
+ std::unique_ptr scene;
std::unique_ptr mesh;
std::unique_ptr meshPassthrough;
std::unique_ptr commandBuffer;
@@ -42,7 +42,7 @@ namespace Copium
EventResult OnEvent(const Event& event) override;
private:
void InitializeFrameBuffer();
- void InitializeRenderer();
+ void InitializeScene();
void InitializeTextureSampler();
void InitializeDescriptorSets();
void InitializeGraphicsPipeline();
diff --git a/CopiumEngine/src/copium/core/Scene.cpp b/CopiumEngine/src/copium/core/Scene.cpp
new file mode 100644
index 0000000..572343a
--- /dev/null
+++ b/CopiumEngine/src/copium/core/Scene.cpp
@@ -0,0 +1,73 @@
+#include "copium/core/Scene.h"
+
+#include "copium/asset/AssetManager.h"
+#include "copium/asset/AssetMeta.h"
+#include "copium/asset/AssetRef.h"
+#include "copium/core/Vulkan.h"
+#include "copium/ecs/Entity.h"
+#include "copium/ecs/System.h"
+#include "copium/event/MouseMoveEvent.h"
+#include "copium/example/FrameCountSystem.h"
+#include "copium/example/MouseFollowSystem.h"
+#include "copium/example/RenderSystem.h"
+#include "copium/example/Components.h"
+
+#include
+#include
+#include
+
+namespace Copium
+{
+ Scene::Scene(CommandBuffer& commandBuffer, DescriptorPool& descriptorPool)
+ {
+ renderer = std::make_unique();
+ descriptorSetRenderer = renderer->GetGraphicsPipeline().CreateDescriptorSet(descriptorPool, 1);
+ ecs = std::make_unique();
+ ecs->AddSystem();
+ ecs->AddSystem(renderer.get(), descriptorSetRenderer.get(), &commandBuffer); // better way to store the RenderSystem data?
+
+ // TODO: Load from scene file
+ for (int y = 0; y < 10; y++)
+ {
+ for (int x = 0; x < 10; x++)
+ {
+ Entity entity = Entity::Create(ecs.get());
+ entity.AddComponent(glm::vec2{-1 + x * 0.2 + 0.05, -1 + y * 0.2 + 0.05}, glm::vec2{0.1, 0.1});
+ entity.AddComponent(glm::vec3{x * 0.1f, y * 0.1f, 1.0f});
+ }
+ }
+
+ float aspect = Vulkan::GetSwapChain().GetExtent().width / (float)Vulkan::GetSwapChain().GetExtent().height;
+ Entity entityFox = Entity::Create(ecs.get());
+ entityFox.AddComponent(glm::vec2{-0.9f, -0.4f}, glm::vec2{0.8f, 0.8f});
+ entityFox.AddComponent(AssetRef{AssetManager::LoadAsset("fox.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
+
+ Entity entityFontAtlas = Entity::Create(ecs.get());
+ entityFontAtlas.AddComponent(glm::vec2{0.1f, -0.4f}, glm::vec2{0.8, 0.8});
+ entityFontAtlas.AddComponent(AssetRef{AssetManager::LoadAsset("font.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
+
+ Entity entityMouse = Entity::Create(ecs.get());
+ entityMouse.AddComponent(glm::vec2(0.1), glm::vec2{0.2});
+ entityMouse.AddComponent(AssetRef{AssetManager::LoadAsset("fox2.meta")}, glm::vec2{0.0f, 0.0f}, glm::vec2{1.0f, 1.0f});
+ entityMouse.AddComponent();
+
+ glm::vec2 pos = glm::vec2{-aspect + 0.01, 0.94};
+
+ Entity entityText = Entity::Create(ecs.get());
+ entityText.AddComponent(glm::vec2{-aspect + 0.01, 0.94}, glm::vec2{1.0});
+ entityText.AddComponent(AssetRef{AssetManager::LoadAsset("font.meta")}, std::to_string(0) + " fps", 0.06f);
+ entityText.AddComponent();
+ }
+
+ void Scene::Update()
+ {
+ ecs->UpdateSystems();
+ }
+
+ EventResult Scene::OnEvent(const Event& event)
+ {
+ // ecs->UpdateEventSystems(event);
+ MouseFollowSystem{ecs.get(), event}.Run(); // TODO: Remove when I figure out how to handle events in systems
+ return EventResult::Continue;
+ }
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/core/Scene.h b/CopiumEngine/src/copium/core/Scene.h
new file mode 100644
index 0000000..4495054
--- /dev/null
+++ b/CopiumEngine/src/copium/core/Scene.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "copium/renderer/Renderer.h"
+#include "copium/ecs/ECSManager.h"
+#include "copium/event/Event.h"
+#include "copium/event/EventResult.h"
+
+#include
+
+namespace Copium
+{
+ class Scene
+ {
+ private:
+ std::unique_ptr renderer;
+ std::unique_ptr ecs;
+ std::unique_ptr descriptorSetRenderer;
+ int frameCounter = 0;
+ int fps = 0;
+ public:
+ Scene(CommandBuffer& commandBuffer, DescriptorPool& descriptorPool);
+ void Update();
+ EventResult OnEvent(const Event& event);
+ };
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/ecs/ECSManager.cpp b/CopiumEngine/src/copium/ecs/ECSManager.cpp
index 0ddccb2..90d6ca9 100644
--- a/CopiumEngine/src/copium/ecs/ECSManager.cpp
+++ b/CopiumEngine/src/copium/ecs/ECSManager.cpp
@@ -4,6 +4,10 @@
namespace Copium
{
+ ECSManager::ECSManager()
+ : systemPool{std::make_unique(this)}
+ {}
+
ECSManager::~ECSManager()
{
for (auto&& components : componentPool)
@@ -13,6 +17,11 @@ namespace Copium
componentPool.clear();
}
+ void ECSManager::UpdateSystems()
+ {
+ systemPool->Update();
+ }
+
size_t ECSManager::GetEntityCount() const
{
return entities.size();
diff --git a/CopiumEngine/src/copium/ecs/ECSManager.h b/CopiumEngine/src/copium/ecs/ECSManager.h
index ecc69c1..5bf691f 100644
--- a/CopiumEngine/src/copium/ecs/ECSManager.h
+++ b/CopiumEngine/src/copium/ecs/ECSManager.h
@@ -3,6 +3,7 @@
#include "copium/ecs/ComponentPool.h"
#include "copium/ecs/Config.h"
+#include "copium/ecs/SystemPool.h"
#include "copium/util/Common.h"
#include
@@ -18,10 +19,21 @@ namespace Copium
private:
std::unordered_set entities;
std::map componentPool;
+
+ std::unique_ptr systemPool;
int currentEntityId = 1;
public:
+ ECSManager();
~ECSManager();
+ template
+ SystemOrderer AddSystem(const Args&... args)
+ {
+ return systemPool->AddSystem(typeid(SystemClass), new SystemClass{args...});
+ }
+
+ void UpdateSystems();
+
EntityID CreateEntity();
void DestroyEntity(EntityID entity);
size_t GetEntityCount() const;
@@ -37,7 +49,7 @@ namespace Copium
template
Component& AddComponent(EntityID entity, Args&&... args)
{
- return AddComponent(entity, Component(args...));
+ return AddComponent(entity, Component{args...});
}
template
@@ -76,7 +88,7 @@ namespace Copium
{
auto pool = GetComponentPoolAssure();
Component* component = pool->FindComponent(entity);
- ASSERT(component, "Entity did not contain component (entity=%u, Component=%s)", entity, typeid(Component).name());
+ CP_ASSERT(component, "Entity did not contain component (entity=%u, Component=%s)", entity, typeid(Component).name());
return *component;
}
diff --git a/CopiumEngine/src/copium/ecs/System.h b/CopiumEngine/src/copium/ecs/System.h
new file mode 100644
index 0000000..0c38f43
--- /dev/null
+++ b/CopiumEngine/src/copium/ecs/System.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "copium/ecs/ECSManager.h"
+#include "copium/ecs/SystemBase.h"
+#include "copium/ecs/Entity.h"
+
+namespace Copium
+{
+ template
+ class System : public SystemBase
+ {
+ public:
+ void Run() override
+ {
+ manager->Each([&](EntityID entityId, Components&... components) { RunEntity(Entity{manager, entityId}, components...); });
+ }
+
+ virtual void RunEntity(Entity entity, Components&... components) = 0;
+ };
+}
diff --git a/CopiumEngine/src/copium/ecs/SystemBase.h b/CopiumEngine/src/copium/ecs/SystemBase.h
new file mode 100644
index 0000000..87cc114
--- /dev/null
+++ b/CopiumEngine/src/copium/ecs/SystemBase.h
@@ -0,0 +1,16 @@
+#pragma once
+
+namespace Copium
+{
+ class ECSManager;
+
+ class SystemBase
+ {
+ friend class SystemPool;
+ protected:
+ ECSManager* manager;
+
+ public:
+ virtual void Run() = 0;
+ };
+}
diff --git a/CopiumEngine/src/copium/ecs/SystemOrderer.cpp b/CopiumEngine/src/copium/ecs/SystemOrderer.cpp
new file mode 100644
index 0000000..b212c13
--- /dev/null
+++ b/CopiumEngine/src/copium/ecs/SystemOrderer.cpp
@@ -0,0 +1,21 @@
+#include "copium/ecs/SystemOrderer.h"
+
+#include "copium/ecs/SystemPool.h"
+
+namespace Copium
+{
+ SystemOrderer::SystemOrderer(std::type_index systemId, SystemPool* systemPool)
+ : systemId{systemId},
+ systemPool{systemPool}
+ {}
+
+ void SystemOrderer::Before(const std::type_index& otherSystemId)
+ {
+ systemPool->MoveSystemBefore(systemId, otherSystemId);
+ }
+
+ void SystemOrderer::After(const std::type_index& otherSystemId)
+ {
+ systemPool->MoveSystemAfter(systemId, otherSystemId);
+ }
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/ecs/SystemOrderer.h b/CopiumEngine/src/copium/ecs/SystemOrderer.h
new file mode 100644
index 0000000..d0d1e0e
--- /dev/null
+++ b/CopiumEngine/src/copium/ecs/SystemOrderer.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include
+#include