【问题标题】:Drawing 2D text over 3D scene with OpenGLES2?使用 OpenGLES2 在 3D 场景上绘制 2D 文本?
【发布时间】:2021-07-27 01:30:23
【问题描述】:

我正在尝试在 3D 场景上渲染 2D 文本。 2D 文本使用来自 TTF 字体的 freetype 加载,并使用正交投影进行渲染,场景使用我的相机使用透视投影。我已经从this Learn OpenGL tutorial for text rendering 修改了代码。我可以单独渲染文本和 3D 场景,但是将它们绘制在一起时不会出现 2D 文本。

我的渲染函数:

void Engine::render()
{
    std::string fpsStr = std::to_string(fps).substr(0, std::to_string(fps).find(".") + 3);
    glViewport(0, 0, surface_width, surface_height);
    glClearColor(0.53f, 0.8f, 0.92f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // 3D scene gets rendered here
    scene->render(display, surface, deltaTime);
    //
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    // Text gets rendered here
    debugText.renderText(fpsStr,25.0f, 25.0f, 1.0f, glm::vec3(0.0, 0.0, 0.0));
    //
    glDisable(GL_BLEND);
    eglSwapBuffers(display, surface);
}

文本投影是一个成员变量(glm::mat4),在创建文本渲染类时初始化,如下所示:

...
projection = glm::ortho(0.0f, static_cast<float>(screenWidth), 0.0f, static_cast<float>(screenHeight));
...

我的渲染文本功能:

void Font::renderText(std::string text, float x, float y, float scale, glm::vec3 colour)
{
    // activate corresponding render state
    textShader.use();
    textShader.setMat4("projection", projection);
    textShader.setVec3("textColor", colour);
    glActiveTexture(GL_TEXTURE0);

    // iterate through all characters
    std::string::const_iterator c;
    for (c = text.begin(); c != text.end(); c++)
    {
        Character ch = characters[*c];

        float xpos = x + ch.bearing.x * scale;
        float ypos = y - (ch.size.y - ch.bearing.y) * scale;

        float w = ch.size.x * scale;
        float h = ch.size.y * scale;
        // update VBO for each character
        float vertices[6][4] = {
                { xpos,     ypos + h,   0.0f, 0.0f },
                { xpos,     ypos,       0.0f, 1.0f },
                { xpos + w, ypos,       1.0f, 1.0f },

                { xpos,     ypos + h,   0.0f, 0.0f },
                { xpos + w, ypos,       1.0f, 1.0f },
                { xpos + w, ypos + h,   1.0f, 0.0f }
        };
        // render glyph texture over quad
        glBindTexture(GL_TEXTURE_2D, ch.textureID);
        // update content of VBO memory
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        // render quad
        glDrawArrays(GL_TRIANGLES, 0, 6);
        // now advance cursors for next glyph (note that advance is number of 1/64 pixels)
        x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
    }
    glBindTexture(GL_TEXTURE_2D, 0);
}

这是两张图片,in this one I'm only rendering the text,在这张图片中,我启用了 3D 场景和文字,however only the 3D scene is displayed

如何将这个 2D 透视图覆盖在 3D 场景上,以便它们都被渲染?

【问题讨论】:

    标签: c++ opengl-es opengl-es-2.0 freetype2


    【解决方案1】:

    您说过单独渲染它们(2D 四边形和 3D 场景)可以正常工作,但将它们一起渲染会导致 2D 四边形无法渲染。嗯,尝试检查对象的渲染顺序;确保正确绑定和解除绑定着色器。 您是否有特殊原因禁用了文本的深度测试(尝试启用它,看看是否能解决问题)?

    【讨论】:

    • 是的,与交换渲染顺序相同的问题。着色器正在正确绑定和解除绑定。我禁用了深度测试,希望它只会渲染文本而不用担心它,但是禁用它或启用它没有任何区别
    • 我无法弄清楚确切的问题。如何从一个简单的调试过程开始。注释掉 scene-&gt;renderONLY (不要一次注释掉超过 1 行),看看它是否有效。如果是这样,那么您的问题在于该功能。然后在函数本身中再次重复该过程(如果您有很多代码,可能会很长;因此请尝试优化您将调试的行)。
    • 确实如此,我在帖子底部提到过(请参阅第一个屏幕截图,因为我可以自己渲染文本,只有当我进入场景->渲染时它才会搞砸)。我认为这与相互冲突的预测有关,但我不完全确定
    • 我知道这不是一个直接的答案,但看看这个link 是否有帮助(特别是答案 2),
    • 谢谢,不幸的是 OpenGL ES 2(至少是我在 Vita 上使用的版本)不支持 glLoadIdentiy 或 glMatrixMode 等函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多