Home > Net >  Draw colored quad as background in OpenGL Program
Draw colored quad as background in OpenGL Program

Time:10-20

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;
    }

But this results in: Output

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: Latest output

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);

And it's working now Working Output

  • Related