I am trying to draw a quad as the background and set it to a constant color in the fragment shader. However, only one triangle of the quad gets drawn and its scaled weirdly. My vertices for the triangle are:
const glm::vec3 background_vertices[6] =
{
glm::vec3(-1.0f, -1.0f, 1.0f),
glm::vec3(1.0f, -1.0f, 1.0f),
glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-1.0f, 1.0f, 1.0f),
glm::vec3(-1.0f, -1.0f, 1.0f)
};
I generate a VAO and VBO for this quad with:
// For background
glGenVertexArrays(1, &background_vao);
glGenBuffers(1, &background_vbo);
glBindVertexArray(background_vao);
glBindBuffer(GL_ARRAY_BUFFER, background_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(background_vertices), background_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
glEnableVertexAttribArray(0);
And I finally draw it in my display
function with:
glUniform1i(UniformLocs::pass, BACKGROUND);
glBindVertexArray(background_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
I also load a mesh and render that with some transparency so I have multiple shader passes (for background and for other calculations).
My vertex shader takes in pos_attrib
and shoots out position
which gets set in:
position = (pass == 0) ? pos_attrib : vec3(M * vec4(pos_attrib, 1.0));
And gl_Position
is
gl_Position = (pass == 0) ? vec4(position, 1.0) : PV * vec4(position, 1.0);
Since my vertices are in NDC range, I don't apply any transformation to them and send them to the fragment shader as is.
My fragment shader either applies a constant color or calculates the object's transparency through:
switch(pass)
{
case 0: // Render Background
fragcolor = vec4(0.9f, 0.45f, 0.25f, 1.0f);
break;
default:
fragcolor = min(HackTransparency(), vec4(1.0));
break;
}
It seems straightforward but I am not able to figure out what I'm doing wrong.
How do I display a colored quad as the background? Any pointers for this will be helpful.
Edit: The output now looks like:
CodePudding user response:
Only one triangle is drawn because you put the same coordinates twice, but in a different order, which doesn't matter (unless you have turned on GL_CULL_FACE
). To draw two triangles, you have to draw two different triangles.
It's "scaled weirdly" because 0,0 is the middle of the screen, not the bottom-left corner. The bottom-left is -1,-1 and the top-right is 1,1. 0,0 is the middle.
CodePudding user response:
I changed the vertices to:
const glm::vec3 background_vertices[4] =
{
glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(1.0f, -1.0f, 1.0f),
glm::vec3(-1.0f, -1.0f, 1.0f),
glm::vec3(-1.0f, 1.0f, 1.0f)
};
Added indices:
const int indices[] =
{
0, 1, 3, // First triangle
1, 2, 3 // Second triangle
};
And used an element buffer object:
// For background
glGenVertexArrays(1, &background_vao);
glGenBuffers(1, &background_vbo);
glGenBuffers(1, &background_ebo);
glBindVertexArray(background_vao);
glBindBuffer(GL_ARRAY_BUFFER, background_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(background_vertices), background_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, background_ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
And changed the draw call to:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);