在3D渲染场景上绘制2D HUD元素

时间:2020-05-25 16:39:12

标签: c++ opengl

我搜索了此内容,但只发现了2014年以来的一则帖子,询问类似情况。但是,由于我不明白那里所做的事情,因此我再次询问,特别是对于我的实现,希望这也能从总体上阐明该主题。我对c ++和openGL还是很陌生,所以请别客气,以免愚蠢的错误。

我正在尝试为我的3D游戏实现一个简单的2D HUD。现在,我的游戏已完全渲染,由于游戏中具有绽放效果,我什至在屏幕四边形上渲染了游戏。 我现在想要做的就是将HUD放置在此渲染的场景上,但是我似乎无法做到这一点。

我的游戏屏幕画面如下所示:

unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{
    if (quadVAO == 0)
    {
        float quadVertices[] = {
            // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
            // texCoords
            0.0f, 1.0f,
            0.0f, 0.0f,
            1.0f, 0.0f,

            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f
        };
        // setup plane VAO
        glGenVertexArrays(1, &quadVAO);
        glGenBuffers(1, &quadVBO);
        glBindVertexArray(quadVAO);
        glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    }
    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);
}

我尝试执行的操作是,只需将四边形的尺寸更改为使其出现在屏幕的左下角,即可将我的renderQuad方法更改为renderHUDquad。 代码如下:

unsigned int HUDquadVAO = 0;
unsigned int HUDquadVBO;
void renderHUDQuad()
{
    if (HUDquadVAO == 0)
    {
        float HUDquadVertices[] = {
            // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
            // texCoords
            0.0f, 0.02f,
            0.0f, 0.0f,
            0.2f, 0.0f,

            0.0f, 0.02f,
            0.2f, 0.0f,
            0.2f, 0.02f
        };
        // setup plane VAO
        glGenVertexArrays(1, &HUDquadVAO);
        glGenBuffers(1, &HUDquadVBO);
        glBindVertexArray(HUDquadVAO);
        glBindBuffer(GL_ARRAY_BUFFER, HUDquadVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(HUDquadVertices), &HUDquadVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    }
    glBindVertexArray(HUDquadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);
}

由于这只需要是一个小的绿色方块,即玩家的健康栏,所以我正在考虑只为其分配绿色纹理或其他东西。 但是,当绘制这样的两个四边形时:

// Third pass = Combined bloom pictures
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            bloomShader->use();
            // Set uniform for multiple layout uniforms
            bloomShader->setUniform("scene", 0);
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, colorAndLightBuffers[0]);
            // Set uniform for multiple layout uniforms
            bloomShader->setUniform("bloomBlur", 1);
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, pingpongBuffer[horizontal == 0 ? 1 : 0]);
            bloomShader->setUniform("bloom", bloom);
            bloomShader->setUniform("exposure", exposure);
            renderQuad();

            renderHUDQuad();

            // Swap buffers
            glfwSwapBuffers(window);

我只得到HUD元素,而没有之前画过的任何东西,好像屏幕的其余部分都变成了黑色。我以为可以将其添加到旧缓冲区中,因为有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

您确实严重破坏了GL状态:

void renderHUDQuad() {
    if (HUDquadVAO == 0)
    {
        [...]
        glGenVertexArrays(1, &quadVAO);

在此功能的其余部分中实际上使用了quadVAO,因此您用较小的一个覆盖了全屏四边形,这意味着其余场景将从下一帧开始按比例缩小到该四边形。