mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Get ECS to a functional state
This commit is contained in:
parent
2a7a9e54b2
commit
e63e30fd4c
@ -9,50 +9,54 @@ project(engine LANGUAGES CXX
|
||||
)
|
||||
|
||||
set(SRC_FILES
|
||||
"src/ecs_system.cpp"
|
||||
"src/application.cpp"
|
||||
"src/window.cpp"
|
||||
|
||||
"src/input_manager.cpp"
|
||||
"src/scene_manager.cpp"
|
||||
|
||||
"src/resources/texture.cpp"
|
||||
"src/resources/material.cpp"
|
||||
|
||||
"src/gfx_device_vulkan.cpp"
|
||||
"src/resources/texture.cpp"
|
||||
|
||||
"src/scene.cpp"
|
||||
"src/gfx_device_vulkan.cpp"
|
||||
|
||||
"src/util/files.cpp"
|
||||
|
||||
"src/scene_manager.cpp"
|
||||
"src/input_manager.cpp"
|
||||
"src/window.cpp"
|
||||
)
|
||||
|
||||
set(INCLUDE_FILES
|
||||
"include/engine_api.h"
|
||||
"include/application.hpp"
|
||||
"include/util.hpp"
|
||||
"include/log.hpp"
|
||||
"include/logger.hpp"
|
||||
"include/window.hpp"
|
||||
"include/inputs/keyboard.hpp"
|
||||
"include/inputs/mouse.hpp"
|
||||
|
||||
"include/input_manager.hpp"
|
||||
"include/scene_manager.hpp"
|
||||
|
||||
"include/resource_manager.hpp"
|
||||
"include/resources/material.hpp"
|
||||
"include/resources/texture.hpp"
|
||||
"include/resources/shader.hpp"
|
||||
"include/resources/mesh.hpp"
|
||||
|
||||
"include/gfx.hpp"
|
||||
"include/ecs_system.hpp"
|
||||
"include/gfx_device.hpp"
|
||||
|
||||
"include/scene.hpp"
|
||||
"include/ecs/ecs_system.hpp"
|
||||
"include/ecs/transform.hpp"
|
||||
"include/ecs/mesh_renderer.hpp"
|
||||
"include/inputs/mouse.hpp"
|
||||
"include/inputs/keyboard.hpp"
|
||||
"include/input_manager.hpp"
|
||||
|
||||
"include/systems/transform.hpp"
|
||||
"include/systems/render.hpp"
|
||||
|
||||
"include/resources/shader.hpp"
|
||||
"include/resources/material.hpp"
|
||||
"include/resources/mesh.hpp"
|
||||
"include/resources/texture.hpp"
|
||||
|
||||
"include/engine_api.h"
|
||||
|
||||
"include/util/files.hpp"
|
||||
|
||||
"include/util.hpp"
|
||||
"include/logger.hpp"
|
||||
"include/scene_manager.hpp"
|
||||
"include/gfx.hpp"
|
||||
"include/scene.hpp"
|
||||
"include/window.hpp"
|
||||
"include/log.hpp"
|
||||
"include/resource_manager.hpp"
|
||||
"include/application.hpp"
|
||||
|
||||
"include/components/transform.hpp"
|
||||
"include/components/renderable.hpp"
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
|
12
include/components/renderable.hpp
Normal file
12
include/components/renderable.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct RenderableComponent {
|
||||
};
|
||||
|
||||
}
|
22
include/components/transform.hpp
Normal file
22
include/components/transform.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct TransformComponent {
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
glm::vec3 scale;
|
||||
|
||||
glm::mat4 worldMatrix;
|
||||
|
||||
std::string tag;
|
||||
uint32_t parent;
|
||||
};
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Scene;
|
||||
|
||||
template <class T>
|
||||
class EcsSystem {
|
||||
|
||||
public:
|
||||
EcsSystem(Scene* scene)
|
||||
: m_scene(scene)
|
||||
{
|
||||
|
||||
}
|
||||
~EcsSystem() {}
|
||||
EcsSystem(const EcsSystem&) = delete;
|
||||
EcsSystem& operator=(const EcsSystem&) = delete;
|
||||
|
||||
Scene* const m_scene;
|
||||
|
||||
std::map<uint32_t, T> m_components{};
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
#include "resources/material.hpp"
|
||||
#include "resources/shader.hpp"
|
||||
#include "resources/texture.hpp"
|
||||
#include "resources/mesh.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#include "scene.hpp"
|
||||
#include "application.hpp"
|
||||
#include "window.hpp"
|
||||
#include "gfx_device.hpp"
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace engine::ecs {
|
||||
|
||||
struct MeshRendererComponent {
|
||||
std::shared_ptr<resources::Material> material;
|
||||
std::shared_ptr<resources::Mesh> mesh;
|
||||
};
|
||||
|
||||
class RendererSystem : public EcsSystem<MeshRendererComponent> {
|
||||
|
||||
public:
|
||||
RendererSystem(Scene* scene)
|
||||
: EcsSystem<MeshRendererComponent>(scene)
|
||||
{
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
void drawMeshes(const std::map<uint32_t, glm::mat4>& worldTransforms)
|
||||
{
|
||||
|
||||
glm::mat4 cameraTransform{1.0f};
|
||||
// cameraTransform = glm::mat4_cast(m_cameraRot);
|
||||
// reinterpret_cast<glm::vec3&>(cameraTransform[3]) = m_cameraPos;
|
||||
glm::mat4 viewMatrix = glm::inverse(cameraTransform);
|
||||
|
||||
if (m_scene->app()->window()->getWindowResized()) {
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
std::set<resources::Shader*> uniqueShaders{};
|
||||
for (const auto& [id, data] : m_components) {
|
||||
uniqueShaders.insert(data.material->getShader());
|
||||
}
|
||||
for (resources::Shader* shader : uniqueShaders) {
|
||||
DEBUG("TEST {}", (void*)shader);
|
||||
m_scene->app()->gfx()->updateUniformBuffer(shader->getPipeline(), &m_projMatrix, sizeof(m_projMatrix), 0);
|
||||
}
|
||||
|
||||
for (const auto& [id, data] : m_components) {
|
||||
DEBUG("drawing entity {}", id);
|
||||
DEBUG("material shader addr: {}", (void*)data.material->getShader());
|
||||
|
||||
assert(data.material != nullptr);
|
||||
assert(data.mesh != nullptr);
|
||||
|
||||
struct {
|
||||
glm::mat4 model;
|
||||
glm::mat4 view;
|
||||
} pushConsts{};
|
||||
pushConsts.model = worldTransforms.at(id);
|
||||
pushConsts.view = glm::mat4{1.0f};
|
||||
|
||||
m_scene->app()->gfx()->draw(
|
||||
data.material->getShader()->getPipeline(),
|
||||
data.mesh->getVB(),
|
||||
data.mesh->getIB(),
|
||||
data.mesh->getCount(),
|
||||
&pushConsts, sizeof(pushConsts),
|
||||
data.material->m_texture->getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 m_cameraPos;
|
||||
glm::quat m_cameraRot;
|
||||
|
||||
glm::mat4 m_projMatrix;
|
||||
|
||||
private:
|
||||
|
||||
void updateProjectionMatrix()
|
||||
{
|
||||
constexpr float NEAR = 0.1f;
|
||||
constexpr float FAR = 1000.0f;
|
||||
float fovRad = glm::radians(75.0f);
|
||||
uint32_t viewportWidth, viewportHeight;
|
||||
m_scene->app()->gfx()->getViewportSize(&viewportWidth, &viewportHeight);
|
||||
float aspect = (float)viewportWidth / (float)viewportHeight;
|
||||
float fovY = fovRad / aspect;
|
||||
m_projMatrix = glm::perspectiveZO(fovY, aspect, NEAR, FAR);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
namespace engine::ecs {
|
||||
|
||||
struct TransformComponent {
|
||||
uint32_t parent;
|
||||
glm::vec3 scale;
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
};
|
||||
|
||||
class TransformSystem : public EcsSystem<TransformComponent> {
|
||||
|
||||
public:
|
||||
TransformSystem(Scene* scene)
|
||||
: EcsSystem<TransformComponent>(scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<std::map<uint32_t, glm::mat4>> getMatrices()
|
||||
{
|
||||
auto transforms = std::make_unique<std::map<uint32_t, glm::mat4>>();
|
||||
for (const auto& [id, data] : m_components) {
|
||||
glm::mat4 transform;
|
||||
|
||||
// rotation
|
||||
transform = glm::mat4_cast(data.rotation);
|
||||
// position
|
||||
reinterpret_cast<glm::vec3&>(transform[3]) = data.position;
|
||||
// scale (effectively applied first)
|
||||
transform = glm::scale(transform, data.scale);
|
||||
|
||||
if (data.parent != 0) {
|
||||
transform = transforms->at(data.parent) * transform;
|
||||
}
|
||||
|
||||
transforms->emplace(id, transform);
|
||||
}
|
||||
return transforms;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
67
include/ecs_system.hpp
Normal file
67
include/ecs_system.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <assert.h>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Scene;
|
||||
|
||||
constexpr size_t MAX_COMPONENTS = 64;
|
||||
|
||||
class IComponentArray {
|
||||
public:
|
||||
virtual ~IComponentArray() = default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ComponentArray : public IComponentArray {
|
||||
|
||||
public:
|
||||
void insertData(uint32_t entity, T component)
|
||||
{
|
||||
assert(m_componentArray.find(entity) == m_componentArray.end() && "Adding component which already exists to entity");
|
||||
m_componentArray.emplace(entity, component);
|
||||
}
|
||||
|
||||
void deleteData(uint32_t entity)
|
||||
{
|
||||
m_componentArray.erase(entity);
|
||||
}
|
||||
|
||||
T* getData(uint32_t entity)
|
||||
{
|
||||
if (m_componentArray.contains(entity)) {
|
||||
return &(m_componentArray.at(entity));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint32_t, T> m_componentArray{};
|
||||
|
||||
};
|
||||
|
||||
class System {
|
||||
|
||||
public:
|
||||
System(Scene* scene, std::set<size_t> requiredComponentHashes);
|
||||
~System() {}
|
||||
System(const System&) = delete;
|
||||
System& operator=(const System&) = delete;
|
||||
|
||||
virtual void onUpdate(float ts) = 0;
|
||||
|
||||
Scene* const m_scene;
|
||||
|
||||
std::bitset<MAX_COMPONENTS> m_signature;
|
||||
std::set<uint32_t> m_entities{}; // entities that contain the required components
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -33,7 +33,7 @@ namespace engine {
|
||||
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
|
||||
#endif
|
||||
|
||||
auto logger = std::make_shared<spdlog::logger>("sdltest", sinks.begin(), sinks.end());
|
||||
auto logger = std::make_shared<spdlog::logger>(appName, sinks.begin(), sinks.end());
|
||||
|
||||
logger->set_level(spdlog::level::trace);
|
||||
|
||||
|
@ -12,9 +12,58 @@ namespace engine::resources {
|
||||
class Shader {
|
||||
|
||||
public:
|
||||
Shader(GFXDevice* gfx, const char* vertPath, const char* fragPath, const gfx::VertexFormat& vertFormat, bool alphaBlending, bool cullBackFace)
|
||||
|
||||
// defines what vertex inputs are defined, position is always vec3
|
||||
struct VertexParams {
|
||||
bool hasNormal;
|
||||
bool hasUV0;
|
||||
bool hasUV1;
|
||||
bool hasUV2;
|
||||
bool hasUV3;
|
||||
bool hasTangent;
|
||||
bool hasColor;
|
||||
};
|
||||
|
||||
Shader(GFXDevice* gfx, const char* vertPath, const char* fragPath, const VertexParams& vertexParams, bool alphaBlending, bool cullBackFace)
|
||||
: m_gfx(gfx)
|
||||
{
|
||||
int index = 0;
|
||||
uint32_t stride = 0;
|
||||
gfx::VertexFormat vertFormat{};
|
||||
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC3, stride);
|
||||
stride += 3 * sizeof(float);
|
||||
|
||||
if (vertexParams.hasNormal) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC3, stride);
|
||||
stride += 3 * sizeof(float);
|
||||
}
|
||||
if (vertexParams.hasUV0) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC2, stride);
|
||||
stride += 2 * sizeof(float);
|
||||
}
|
||||
if (vertexParams.hasUV1) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC2, stride);
|
||||
stride += 2 * sizeof(float);
|
||||
}
|
||||
if (vertexParams.hasUV2) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC2, stride);
|
||||
stride += 2 * sizeof(float);
|
||||
}
|
||||
if (vertexParams.hasUV3) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC2, stride);
|
||||
stride += 2 * sizeof(float);
|
||||
}
|
||||
if (vertexParams.hasTangent) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC3, stride);
|
||||
stride += 3 * sizeof(float);
|
||||
}
|
||||
if (vertexParams.hasColor) {
|
||||
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::VEC3, stride);
|
||||
stride += 3 * sizeof(float);
|
||||
}
|
||||
vertFormat.stride = stride;
|
||||
|
||||
m_pipeline = m_gfx->createPipeline(vertPath, fragPath, vertFormat, sizeof(glm::mat4), alphaBlending, cullBackFace);
|
||||
}
|
||||
~Shader()
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <typeinfo>
|
||||
#include <assert.h>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Application;
|
||||
|
||||
namespace ecs {
|
||||
class TransformSystem;
|
||||
class RendererSystem;
|
||||
}
|
||||
|
||||
class Scene {
|
||||
|
||||
public:
|
||||
@ -23,13 +23,79 @@ namespace engine {
|
||||
|
||||
void update(float ts);
|
||||
|
||||
uint32_t createEntity()
|
||||
uint32_t createEntity(const std::string& tag, uint32_t parent = 0);
|
||||
|
||||
uint32_t getEntity(const std::string& tag, uint32_t parent = 0);
|
||||
|
||||
size_t getComponentSignaturePosition(size_t hash)
|
||||
{
|
||||
return m_nextEntityID++;
|
||||
return m_componentSignaturePositions.at(hash);
|
||||
}
|
||||
|
||||
std::unique_ptr<ecs::TransformSystem> m_transformSystem;
|
||||
std::unique_ptr<ecs::RendererSystem> m_renderSystem;
|
||||
template <typename T>
|
||||
void registerComponent()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
assert(m_componentArrays.contains(hash) == false && "Registering component type more than once.");
|
||||
m_componentArrays.emplace(hash, std::make_unique<ComponentArray<T>>());
|
||||
|
||||
size_t componentSignaturePosition = m_nextSignaturePosition++;
|
||||
assert(componentSignaturePosition < MAX_COMPONENTS && "Registering too many components!");
|
||||
assert(m_componentSignaturePositions.contains(hash) == false);
|
||||
m_componentSignaturePositions.emplace(hash, componentSignaturePosition);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* getComponent(uint32_t entity)
|
||||
{
|
||||
auto array = getComponentArray<T>();
|
||||
return array->getData(entity);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* addComponent(uint32_t entity)
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
|
||||
auto array = getComponentArray<T>();
|
||||
array->insertData(entity, T{});
|
||||
|
||||
// set the component bit for this entity
|
||||
size_t componentSignaturePosition = m_componentSignaturePositions.at(hash);
|
||||
auto& signatureRef = m_signatures.at(entity);
|
||||
signatureRef.set(componentSignaturePosition);
|
||||
|
||||
for (auto& [systemName, system] : m_systems)
|
||||
{
|
||||
if ((system->m_signature & signatureRef) == system->m_signature) {
|
||||
system->m_entities.insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return array->getData(entity);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void registerSystem()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
assert(m_systems.find(hash) == m_systems.end() && "Registering system more than once.");
|
||||
m_systems.emplace(hash, std::make_unique<T>(this));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* getSystem()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
auto it = m_systems.find(hash);
|
||||
if (it == m_systems.end()) {
|
||||
throw std::runtime_error("Cannot find ecs system.");
|
||||
}
|
||||
auto ptr = it->second.get();
|
||||
auto castedPtr = dynamic_cast<T*>(ptr);
|
||||
assert(castedPtr != nullptr);
|
||||
return castedPtr;
|
||||
}
|
||||
|
||||
Application* app() { return m_app; }
|
||||
|
||||
@ -37,6 +103,30 @@ namespace engine {
|
||||
Application* const m_app;
|
||||
uint32_t m_nextEntityID = 1000;
|
||||
|
||||
size_t m_nextSignaturePosition = 0;
|
||||
// maps component hashes to signature positions
|
||||
std::map<size_t, size_t> m_componentSignaturePositions{};
|
||||
// maps entity ids to their signatures
|
||||
std::map<uint32_t, std::bitset<MAX_COMPONENTS>> m_signatures{};
|
||||
// maps component hashes to their arrays
|
||||
std::map<size_t, std::unique_ptr<IComponentArray>> m_componentArrays{};
|
||||
// maps system hashes to their class instantiations
|
||||
std::map<size_t, std::unique_ptr<System>> m_systems{};
|
||||
|
||||
template <typename T>
|
||||
ComponentArray<T>* getComponentArray()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
auto it = m_componentArrays.find(hash);
|
||||
if (it == m_componentArrays.end()) {
|
||||
throw std::runtime_error("Cannot find component array.");
|
||||
}
|
||||
auto ptr = it->second.get();
|
||||
auto castedPtr = dynamic_cast<ComponentArray<T>*>(ptr);
|
||||
assert(castedPtr != nullptr);
|
||||
return castedPtr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ namespace engine {
|
||||
class Scene; // "scene.hpp"
|
||||
namespace resources {
|
||||
class Texture;
|
||||
class Shader;
|
||||
class Mesh;
|
||||
class Material;
|
||||
}
|
||||
|
||||
class SceneManager {
|
||||
@ -21,21 +24,17 @@ namespace engine {
|
||||
SceneManager(const SceneManager&) = delete;
|
||||
SceneManager& operator=(const SceneManager&) = delete;
|
||||
|
||||
Scene* createScene();
|
||||
// creates an empty scene and sets it as active
|
||||
Scene* createEmptyScene();
|
||||
|
||||
void updateActiveScene(float ts);
|
||||
|
||||
/* getters */
|
||||
ResourceManager<resources::Texture>* getTextureManager() { return m_textureManager.get(); }
|
||||
|
||||
private:
|
||||
Application* const m_app;
|
||||
|
||||
std::vector<std::unique_ptr<Scene>> m_scenes;
|
||||
int m_activeSceneIndex = -1;
|
||||
|
||||
std::unique_ptr<ResourceManager<resources::Texture>> m_textureManager;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
35
include/systems/render.hpp
Normal file
35
include/systems/render.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#include "components/transform.hpp"
|
||||
#include "components/renderable.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class RenderSystem : public System {
|
||||
|
||||
public:
|
||||
RenderSystem(Scene* scene)
|
||||
: System(scene, { typeid(TransformComponent).hash_code(), typeid(RenderableComponent).hash_code() })
|
||||
{
|
||||
}
|
||||
|
||||
void onUpdate(float ts) override
|
||||
{
|
||||
for (uint32_t entity : m_entities) {
|
||||
|
||||
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||
|
||||
TRACE("rendering {}", t->tag);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
67
include/systems/transform.hpp
Normal file
67
include/systems/transform.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
#include "components/transform.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string.h>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class TransformSystem : public System {
|
||||
|
||||
public:
|
||||
TransformSystem(Scene* scene)
|
||||
: System(scene, { typeid(TransformComponent).hash_code() })
|
||||
{
|
||||
}
|
||||
|
||||
void onUpdate(float ts) override
|
||||
{
|
||||
for (uint32_t entity : m_entities) {
|
||||
|
||||
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||
|
||||
TRACE("tag is {}", t->tag);
|
||||
|
||||
glm::mat4 transform;
|
||||
|
||||
// rotation
|
||||
transform = glm::mat4_cast(t->rotation);
|
||||
// position
|
||||
reinterpret_cast<glm::vec3&>(transform[3]) = t->position;
|
||||
// scale (effectively applied first)
|
||||
transform = glm::scale(transform, t->scale);
|
||||
|
||||
if (t->parent != 0) {
|
||||
transform = m_scene->getComponent<TransformComponent>(t->parent)->worldMatrix * transform;
|
||||
}
|
||||
|
||||
t->worldMatrix = transform;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t getChildEntity(uint32_t parent, const std::string& tag)
|
||||
{
|
||||
for (uint32_t entity : m_entities) {
|
||||
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||
if (t->parent == parent) {
|
||||
if (t->tag == tag) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
16
src/ecs_system.cpp
Normal file
16
src/ecs_system.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
#include "scene.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
System::System(Scene* scene, std::set<size_t> requiredComponentHashes)
|
||||
: m_scene(scene)
|
||||
{
|
||||
for (size_t componentHash : requiredComponentHashes) {
|
||||
size_t componentSignaturePosition = m_scene->getComponentSignaturePosition(componentHash);
|
||||
m_signature.set(componentSignaturePosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -567,8 +567,6 @@ namespace engine {
|
||||
swapchain->surfaceFormat = format; // prefer using srgb non linear colors
|
||||
}
|
||||
}
|
||||
INFO("surface format: {}", swapchain->surfaceFormat.format);
|
||||
INFO("surface colorspace: {}", swapchain->surfaceFormat.colorSpace);
|
||||
|
||||
swapchain->presentMode = VK_PRESENT_MODE_FIFO_KHR; // This mode is always available
|
||||
if (vsync == false) {
|
||||
@ -1244,18 +1242,14 @@ namespace engine {
|
||||
VkQueueFamilyProperties family = queueFamilies[i];
|
||||
if (family.queueCount > 0) {
|
||||
if (graphicsFamilyIndex.has_value() == false && family.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
TRACE("GRAPHICS:");
|
||||
graphicsFamilyIndex = i;
|
||||
}
|
||||
if (transferFamilyIndex.has_value() == false && family.queueFlags & VK_QUEUE_TRANSFER_BIT) {
|
||||
TRACE("TRANSFER:");
|
||||
transferFamilyIndex = i;
|
||||
}
|
||||
if (computeFamilyIndex.has_value() == false && family.queueFlags & VK_QUEUE_COMPUTE_BIT) {
|
||||
TRACE("COMPUTE:");
|
||||
computeFamilyIndex = i;
|
||||
}
|
||||
TRACE("\t\ti = {}\t\tcount = {}", i, family.queueCount);
|
||||
}
|
||||
}
|
||||
if (graphicsFamilyIndex.has_value() == false ||
|
||||
@ -1288,7 +1282,6 @@ namespace engine {
|
||||
if (transferFamilyIndex == family) newQueue.supportsTransfer = true;
|
||||
if (computeFamilyIndex == family) newQueue.supportsCompute = true;
|
||||
|
||||
TRACE("Creating queue from family {}", family);
|
||||
VkDeviceQueueCreateInfo queueCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@ -1460,8 +1453,6 @@ namespace engine {
|
||||
|
||||
GFXDevice::~GFXDevice()
|
||||
{
|
||||
TRACE("Destroying GFXDevice...");
|
||||
|
||||
vkDestroyDescriptorSetLayout(pimpl->device, pimpl->samplerSetLayout, nullptr);
|
||||
vkDestroyDescriptorSetLayout(pimpl->device, pimpl->descriptorSetLayout, nullptr);
|
||||
|
||||
|
@ -1,24 +1,48 @@
|
||||
#include "scene.hpp"
|
||||
|
||||
#include "ecs/transform.hpp"
|
||||
#include "ecs/mesh_renderer.hpp"
|
||||
#include "components/transform.hpp"
|
||||
#include "components/renderable.hpp"
|
||||
#include "systems/transform.hpp"
|
||||
#include "systems/render.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
Scene::Scene(Application* app)
|
||||
: m_app(app)
|
||||
{
|
||||
m_renderSystem = std::make_unique<ecs::RendererSystem>(this);
|
||||
m_transformSystem = std::make_unique<ecs::TransformSystem>(this);
|
||||
registerComponent<TransformComponent>();
|
||||
registerComponent<RenderableComponent>();
|
||||
registerSystem<TransformSystem>();
|
||||
registerSystem<RenderSystem>();
|
||||
}
|
||||
|
||||
Scene::~Scene() {}
|
||||
|
||||
uint32_t Scene::createEntity(const std::string& tag, uint32_t parent)
|
||||
{
|
||||
uint32_t id = m_nextEntityID++;
|
||||
|
||||
m_signatures.emplace(id, std::bitset<MAX_COMPONENTS>{});
|
||||
|
||||
auto t = addComponent<TransformComponent>(id);
|
||||
t->tag = tag;
|
||||
t->parent = parent;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t Scene::getEntity(const std::string& tag, uint32_t parent)
|
||||
{
|
||||
return getSystem<TransformSystem>()->getChildEntity(parent, tag);
|
||||
}
|
||||
|
||||
void Scene::update(float ts)
|
||||
{
|
||||
auto transforms = m_transformSystem->getMatrices();
|
||||
|
||||
m_renderSystem->drawMeshes(*transforms);
|
||||
for (auto& [name, system] : m_systems) {
|
||||
system->onUpdate(ts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,12 +10,11 @@ namespace engine {
|
||||
SceneManager::SceneManager(Application* app)
|
||||
: m_app(app)
|
||||
{
|
||||
m_textureManager = std::make_unique<ResourceManager<resources::Texture>>();
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager() {}
|
||||
|
||||
Scene* SceneManager::createScene()
|
||||
Scene* SceneManager::createEmptyScene()
|
||||
{
|
||||
auto scene = std::make_unique<Scene>(m_app);
|
||||
m_scenes.emplace_back(std::move(scene));
|
||||
|
@ -1,92 +0,0 @@
|
||||
#include "sceneroot.hpp"
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
#include "components/custom.hpp"
|
||||
#include "components/camera.hpp"
|
||||
#include "components/mesh_renderer.hpp"
|
||||
#include "components/text_ui_renderer.hpp"
|
||||
|
||||
#include "gfx_device.hpp"
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
SceneRoot::SceneRoot(struct GameIO things) : Object("root", nullptr, *this, things)
|
||||
{
|
||||
}
|
||||
|
||||
SceneRoot::~SceneRoot()
|
||||
{
|
||||
}
|
||||
|
||||
// private methods
|
||||
|
||||
// public methods
|
||||
|
||||
void SceneRoot::updateStuff()
|
||||
{
|
||||
|
||||
using namespace components;
|
||||
using namespace glm;
|
||||
|
||||
struct CompList compList {};
|
||||
|
||||
getAllSubComponents(compList, glm::mat4{ 1.0f });
|
||||
|
||||
// update
|
||||
|
||||
for (const auto& [c, t] : compList.customs) {
|
||||
c->onUpdate(t);
|
||||
}
|
||||
|
||||
// render
|
||||
|
||||
for (const auto& [c, camt] : compList.cameras) {
|
||||
for (int id : m_activeCameras) {
|
||||
if (c->getID() == id) {
|
||||
glm::mat4 view{};
|
||||
c->updateCam(camt, &view);
|
||||
for (const auto& [ren, ren_t] : compList.renderers) {
|
||||
ren->render(ren_t, view);
|
||||
}
|
||||
|
||||
|
||||
for (const auto& [textRen, textRen_t] : compList.uis) {
|
||||
textRen->render(textRen_t, view);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SceneRoot::activateCam(int id)
|
||||
{
|
||||
auto& v = m_activeCameras;
|
||||
|
||||
if (std::find(v.begin(), v.end(), id) == v.end()) {
|
||||
v.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneRoot::deactivateCam(int id)
|
||||
{
|
||||
auto& v = m_activeCameras;
|
||||
|
||||
for (auto it = v.begin(); it != v.end(); it++) {
|
||||
if (*it == id) {
|
||||
v.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,65 +4,26 @@
|
||||
#include "window.hpp"
|
||||
#include "scene_manager.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "resources/material.hpp"
|
||||
#include "resources/shader.hpp"
|
||||
#include "resources/texture.hpp"
|
||||
#include "resources/mesh.hpp"
|
||||
#include "ecs/transform.hpp"
|
||||
#include "ecs/mesh_renderer.hpp"
|
||||
#include "components/transform.hpp"
|
||||
#include "components/renderable.hpp"
|
||||
#include "systems/transform.hpp"
|
||||
|
||||
void playGame()
|
||||
{
|
||||
engine::Application app(PROJECT_NAME, PROJECT_VERSION);
|
||||
|
||||
// configure window
|
||||
app.window()->setRelativeMouseMode(false);
|
||||
app.window()->setRelativeMouseMode(true);
|
||||
|
||||
auto myScene = app.sceneManager()->createScene();
|
||||
auto myScene = app.sceneManager()->createEmptyScene();
|
||||
|
||||
myScene->m_renderSystem->m_cameraPos = { 0.0f, 2.0f, 0.0f };
|
||||
myScene->m_renderSystem->m_cameraRot = glm::angleAxis(0.0f, glm::vec3{ 0.0f, 0.0f, -1.0f });
|
||||
myScene->createEntity("entity1");
|
||||
|
||||
{
|
||||
auto entity1 = myScene->createEntity();
|
||||
engine::gfx::VertexFormat vertFormat{};
|
||||
vertFormat.stride = sizeof(float) * 8;
|
||||
vertFormat.attributeDescriptions.emplace_back(0, engine::gfx::VertexAttribFormat::VEC3, 0);
|
||||
vertFormat.attributeDescriptions.emplace_back(1, engine::gfx::VertexAttribFormat::VEC3, sizeof(float) * 3);
|
||||
vertFormat.attributeDescriptions.emplace_back(2, engine::gfx::VertexAttribFormat::VEC2, sizeof(float) * 6);
|
||||
auto myShader = std::make_unique<engine::resources::Shader>(
|
||||
app.gfx(),
|
||||
app.getResourcePath("engine/shaders/texture.vert").c_str(),
|
||||
app.getResourcePath("engine/shaders/texture.frag").c_str(),
|
||||
vertFormat,
|
||||
false,
|
||||
false
|
||||
);
|
||||
auto myMaterial = std::make_unique<engine::resources::Material>(std::move(myShader));
|
||||
std::vector<engine::Vertex> triVertices{
|
||||
{ { 0.5f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } },
|
||||
{ { -0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } },
|
||||
{ { 0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } },
|
||||
};
|
||||
myMaterial->m_texture = std::make_unique<engine::resources::Texture>(app.gfx(), app.getResourcePath("textures/grass.jpg"));
|
||||
auto myMesh = std::make_unique<engine::resources::Mesh>(app.gfx(), triVertices);
|
||||
myScene->m_renderSystem->m_components.emplace(
|
||||
entity1,
|
||||
engine::ecs::MeshRendererComponent{
|
||||
std::move(myMaterial),
|
||||
std::move(myMesh),
|
||||
}
|
||||
);
|
||||
myScene->m_transformSystem->m_components.emplace(
|
||||
entity1,
|
||||
engine::ecs::TransformComponent{
|
||||
.parent = 0,
|
||||
.scale = {1.0f, 1.0f, 1.0f},
|
||||
.position = {0.0f, 0.0f, -10.0f},
|
||||
.rotation = glm::angleAxis(glm::radians(24.0f), glm::vec3{ 0.0f, 1.0f, 0.0f })
|
||||
}
|
||||
);
|
||||
}
|
||||
auto entity1 = myScene->getEntity("entity1");
|
||||
|
||||
myScene->getComponent<engine::TransformComponent>(entity1)->tag = "HELLO WORLD";
|
||||
|
||||
myScene->addComponent<engine::RenderableComponent>(entity1);
|
||||
|
||||
app.gameLoop();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user