首先,让我描述一下我的条款/实现。
组件仅包含有关某些内容的数据。例如
class TransformComponent : public Component<TransformComponent> /*CRTP*/ {
public:
/*...*/
private:
Transform mTransform;
}
此外,如果需要,组件可以具有一些关于其自身的便捷功能。
实体是组件的容器,负责创建/删除组件。
class Entity {
public:
template <typename T, typename ...Args>
bool attach(Args ... args);
template <typename T>
bool detach();
template <typename T>
T* get();
/*...*/
private:
ComponentTypeBit mComponentBit;
std::unordered_map<ComponentTypeBit, ComponentIsh> mComponentMap;
}
系统可操纵实体的组件。系统可能对一种或多种组件类型感兴趣。实体可以注册到系统。如果实体具有系统所需的所有组件,则系统将存储实体的指针。
template<typename ... Args>
class System {
public:
/*...*/
void registerEntity(Entity& entity);
void deregisterEntity(Entity& entity);
const std::vector<Entity*>& getEntities() const;
/*...*/
private:
ComponentTypeBit mComponentBit;
std::vector<Entity*> mEntities;
}
class HierarchySystem : public System<HierarchyComponent, TransformComponent> {
/*If a entity has HierarchyComponent and TransformComponent,
address of the entity adds to mEntities*/
}
问题是,不仅仅是渲染类本身。
如果要渲染任意(静态)网格,则需要使用摄像机的视图矩阵和投影矩阵。我的困惑从这里开始。
乍一看,我虽然可以这样定义网格渲染器:
class MeshRenderSystem : public System<TransformComponent, MeshComponent, MaterialComponent>
/*currently, MaterialComponent holds reference to fragment shader*/
因此,我可以设置模型矩阵统一和顶点属性,材料统一。 但是我应该在哪里放置视图和投影矩阵?那抽奖电话呢?
想法1:class Scene
,其中包含实体和摄像机列表。
可能的问题:相机不是实体。那意味着我需要类似CameraTargetComponent
的东西。但是要更新该组件,系统应引用Scene
想法2:CameraComponent
代表相机。因此,相机可以在HierarchyComponent
之前拥有父母或孩子。
可能的问题:如果摄影机是一个实体,则应在哪里存储要渲染的视图和投影矩阵(因为我的系统没有事件队列,反之亦然)?我是否还需要类似Scene
的东西?
想法3:具有SceneManager
和SystemProvider
的{{1}}。并且,如果由EntityProvider
创建并注册到EntityProvider
当前场景的实体,则也注册到系统。 SceneManager
可以容纳相机和渲染器。