【发布时间】:2021-02-20 01:29:37
【问题描述】:
我会尽量保持简短
背景
我的基本 C++(SDL 和 OpenGL)2D 游戏引擎有一个 ECS。我有一个名为 TextSystem 的系统,它需要 3 个组件。 TransformComponent、RenderComponent、&TextComponent。
这是为系统设置的签名的代码 sn-p。
ECSHandler::Instance()->Init();
//Register components.
ECSHandler::Instance()->RegisterComponent<TransformComponent>();
ECSHandler::Instance()->RegisterComponent<RenderComponent>();
ECSHandler::Instance()->RegisterComponent<TextComponent>();
//movement signature here
renderSignature.set(ECSHandler::Instance()->GetComponentType<TransformComponent>());
renderSignature.set(ECSHandler::Instance()->GetComponentType<RenderComponent>());
textSignature.set(ECSHandler::Instance()->GetComponentType<TransformComponent>());
textSignature.set(ECSHandler::Instance()->GetComponentType<RenderComponent>());
textSignature.set(ECSHandler::Instance()->GetComponentType<TextComponent>());
//Register systems.
//mpMovementSystem = ECSHandler::Instance()->RegisterSystem<MovementSystem>();
mpRenderSystem = ECSHandler::Instance()->RegisterSystem<RenderSystem>();
mpTextSystem = ECSHandler::Instance()->RegisterSystem<TextSystem>();
//ECSHandler::Instance()->SetSystemSignature<MovementSystem>(signature);
ECSHandler::Instance()->SetSystemSignature<RenderSystem>(renderSignature);
ECSHandler::Instance()->SetSystemSignature<TextSystem>(textSignature);
//mpSystems.insert({ typeid(MovementSystem).name(), mpMovementSystem });
mpSystems.insert({ typeid(RenderSystem).name(), mpRenderSystem });
mpSystems.insert({ typeid(TextSystem).name(), mpTextSystem });
TextSystem 所做的只是将RenderComponent 中的“纹理”变量设置为由文本/字体构成的纹理。这是使用名为 LoadTextureFromFont 的函数完成的。
另一个处理渲染的系统,RenderingSystem,如果它已经像 RenderingSystem 一样注册到 TextSystem,它会自动添加实体TextSystem 需要的所有组件,transform 和 render 组件。
因此,TextSystem 会根据文本输入(TextComponent 中的“输出”变量)和 更改实体的纹理以更新它RenderSystem 渲染该实体。
void TextSystem::Update()
{
for (auto const& entity : mEntities)
{
auto& render = ECSHandler::Instance()->GetComponent<RenderComponent>(entity);
auto& text = ECSHandler::Instance()->GetComponent<TextComponent>(entity);
render.texture = ResourceManager::LoadTextureFromFont(text.output, true, text.font);
}
}
void RenderSystem::Draw()
{
for (auto const& entity : mEntities)
{
auto& transform = ECSHandler::Instance()->GetComponent<TransformComponent>(entity);
auto& render = ECSHandler::Instance()->GetComponent<RenderComponent>(entity);
...
glBindVertexArray(mQuadVAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
}
}
TextSystem 的 Update 在 RenderingSystem 的 Draw 之前调用。
问题
当为在 TextSystem 中注册的实体重新分配 render 组件中的纹理变量时,最新应用的纹理(通过 LoadTextureFromFont)应用到所有实体有一个 TextComponent。本质上,最后一个 TextComponent 成为所有具有该组件的实体的 TextComponent。纹理的大小是根据原始文本的大小制作的,因此较长但已被最新文本替换的文本看起来不成比例。
ResourceManager::AddText("testText", "Message", glm::vec2(200.f, 200.f), ResourceManager::GetFont("CircularMedium"));
ResourceManager::AddText("testText2", "This is a message.", glm::vec2(300.f, 200.f), ResourceManager::GetFont("CircularMedium"));
这不会发生在任何其他组件上,严格来说,这个组件(它只包含一个字符串和字体对象)似乎不是实体专有的。
我已尽我所能解决此问题(10 到 12 小时...),但谷歌搜索没有产生预期的结果。
如果需要任何东西(更多代码 sn-ps 和/或上下文),请告诉我!我不确定这个问题是否适合 Stack Overflow 或 Game Development。
【问题讨论】:
标签: c++ opengl 2d sdl entity-component-system