问题描述
我会尽量保持简短
上下文
我的基本C ++(SDL和OpenGL)2D游戏引擎具有ECS。我有一个名为 TextSystem 的系统,该系统需要3个组件。 TransformComponent , RenderComponent 和 TextComponent 。
这是为系统设置的签名的代码段。
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 中的“ texture”变量设置为由文本/字体制成的纹理。这是使用称为LoadTextureFromFont的函数完成的。
另一个处理渲染的系统 RenderingSystem ,如果该实体已经像 RenderingSystem 一样注册到 TextSystem ,则会自动添加该实体。 TextSystem 需要的所有组件,即 transform 和 render 组件。
因此, TextSystem 更改实体的纹理以根据文本输入( TextComponent 中的“ output”变量)和 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);
}
}
在 RenderingSystem 的绘制之前调用TextSystem 的更新。
问题
在 render 组件中为在 TextSystem 中注册的实体重新分配纹理变量时,所应用的最新纹理(通过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,ResourceManager::GetFont("CircularMedium"));
其他任何组件都不会发生这种情况,严格来说,该组件(仅包含字符串和字体对象)似乎不是实体专有的。
我已经尽力解决了这个问题(10-12小时...),但Google搜索没有产生预期的结果。
如果需要任何内容(更多代码段和/或上下文),请告诉我!我不确定这个问题是否适合Stack Overflow或Game Development。
解决方法
从GetTextureFromFont返回的“ Texture”变量是全局变量。