0

我会尽量保持简短

上下文

我的基本 C++(SDL 和 OpenGL)2D 游戏引擎有一个 ECS。我有一个名为TextSystem的系统,它需要 3 个组件。变换组件、渲染组件文本组件

这是为系统设置的签名的代码片段。

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需要的所有组件,即转换渲染组件。

因此,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中注册的实体重新分配渲染组件中的纹理变量时,应用的最新纹理(通过 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 小时......),谷歌搜索没有产生预期的结果。

如果需要任何东西(更多代码片段和/或上下文),请告诉我!我不确定这个问题是否适合 Stack Overflow 或 Game Development。

4

1 回答 1

0

从 GetTextureFromFont 返回的“Texture”变量是一个全局变量。

于 2020-11-08T05:43:13.737 回答