#c #opengl #2d #sdl #entity-component-system
#c #opengl #2d #sdl #Сущность-компонент-система
Вопрос:
Я постараюсь изложить это кратко
КОНТЕКСТ
Мой базовый движок 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, это устанавливает переменную «texture» в renderComponent на текстуру, созданную из текста / шрифта. Это делается с помощью функции с именем LoadTextureFromFont .
Другая система, которая обрабатывает визуализацию, RenderingSystem, автоматически добавляет объект, если он уже зарегистрирован в текстовой системе, поскольку в системе визуализации есть все компоненты, необходимые текстовой системе, компонент преобразования и визуализации.
Итак, текстовая система изменяет текстуру сущности, чтобы обновить ее в соответствии с вводом текста (переменная «output» в TextComponent), а система визуализации отображает эту сущность.
void TextSystem::Update()
{
for (auto constamp; entity : mEntities)
{
autoamp; render = ECSHandler::Instance()->GetComponent<RenderComponent>(entity);
autoamp; text = ECSHandler::Instance()->GetComponent<TextComponent>(entity);
render.texture = ResourceManager::LoadTextureFromFont(text.output, true, text.font);
}
}
void RenderSystem::Draw()
{
for (auto constamp; entity : mEntities)
{
autoamp; transform = ECSHandler::Instance()->GetComponent<TransformComponent>(entity);
autoamp; render = ECSHandler::Instance()->GetComponent<RenderComponent>(entity);
...
glBindVertexArray(mQuadVAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
}
}
Обновление текстовой системы вызывается перед отрисовкой RenderingSystem.
ПРОБЛЕМА
При переназначении переменной текстуры в компоненте рендеринга для объекта, зарегистрированного в TextSystem, последняя текстура, которая применяется (через LoadTextureFromFont), применяется ко ВСЕМ сущностям, имеющим текстовый компонент. По сути, последний текстовый компонент становится текстовым компонентом для всех объектов, у которых есть указанный компонент. Размер текстуры определяется в соответствии с размером исходного текста, поэтому длинные тексты, которые были заменены новым текстом, будут выглядеть непропорционально.
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 не дал желаемых результатов.
Если что-либо вообще необходимо (дополнительные фрагменты кода и / или контекст), пожалуйста, дайте мне знать! Я не уверен, подходит ли этот вопрос для Stack Overflow или разработки игр.
Ответ №1:
Переменная «Texture», возвращаемая из GetTextureFromFont, была глобальной переменной.