Я постараюсь сохранить это кратко
КОНТЕКСТ
Мой базовый движок для 2D-игр на C ++ (SDL и OpenGL) имеет 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 на текстуру, созданную из текста / шрифта. Это делается с помощью функции LoadTextureFromFont.
Другая система, которая обрабатывает рендеринг, RenderingSystem, автоматически добавляет объект, если он уже зарегистрирован в TextSystem, поскольку RenderingSystem имеет все компоненты. необходимые для 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 вызывается перед Draw для RenderingSystem.
ПРОБЛЕМА
При повторном назначении переменной текстуры в компоненте 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, 200.f), ResourceManager::GetFont("CircularMedium"));
Этого не происходит ни с одним другим компонентом, строго этот компонент (который содержит только строку и объект шрифта), по-видимому, не является эксклюзивным для сущностей.
Я пробовал все, что мог, чтобы исправить это (10-12 часов ...), и поиск в Google не дал желаемых результатов.
Если что-нибудь вообще понадобится (дополнительные фрагменты кода и / или контекст), пожалуйста, дайте мне знать! Я не уверен, подходит ли этот вопрос для переполнения стека или разработки игр.