Reputation: 159
I searched for this and only found a post from 2014 asking about a somewhat similar situation. However, as I couldn't understand what was done there, I'm asking again, specifically for my implementation, hoping this sheds some light on the topic in general as well. I am fairly new to c++ and openGL, so please be so kkind as to excuse stupid mistakes.
I'm trying to implement a simple 2D HUD for my 3D game. Now, my game is fully rendered, due to having a bloom effect in my game, I even rendered my game on a screen quad. What I now want to do ist placing a HUD over this rendered scene, I, however, can't seem to do that.
My screen quad for the game is drawn like so:
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);
}
What I tried to do, ist change my renderQuad
method to a renderHUDquad
one by basically just changing the dimensions of the quad to make it appear in the bottom left corner of the screen.
The code looks as follows:
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);
}
As this only needs to be a small green quad, i.e. a health bar for the player, I was thinking about just assigning it a green texture or sth.. However, when drawing my two quads like this:
// 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);
I only get the HUD element without any of the stuff I drew before as if the rest of the screen was rendered black. I thought I could just add this to the old buffer, as there a way to do this?
Upvotes: 1
Views: 431
Reputation: 45332
You did screw up your GL state very badly:
void renderHUDQuad() { if (HUDquadVAO == 0) { [...] glGenVertexArrays(1, &quadVAO);
You actually use quadVAO
in the rest of this function, so you overwrite your fullscreen quad by the smaller one, which means the rest of your scene will be scaled down to this quad from the next frame on...
Upvotes: 1