0
\$\begingroup\$

I have this code where I can draw as many rectangles I want without no VAO/VBOs warm up.

// Shader sources
const GLchar* vs = R"glsl(
    #version 330 core

    vec2[4] position = vec2[4] ( 
        vec2(0.5, 0.5),   vec2(0.5, -0.5), 
        vec2(-0.5, -0.5), vec2(-0.5, 0.5)
    );

    void main()
    {
        gl_Position = vec4(position[gl_VertexID] - 0.5, 0.0, 1.0);
    }
)glsl";

const GLchar* fs = R"glsl(
    #version 330 core
    out vec4 outColor;

    void main()
    {
        const vec3 color = vec3(1.0, 0.5, 0.2);
        outColor = vec4(color, 1.0);
    }
)glsl";

void useShader(const char *vs, const char *fs) {
    // Create and compile the vertex shader
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vs, NULL);
    glCompileShader(vertexShader);

    // Create and compile the fragment shader
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fs, NULL);
    glCompileShader(fragmentShader);

    // Link the vertex and fragment shader into a shader program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    glDeleteShader(fragmentShader);
    glDeleteShader(vertexShader);
}

int main()
{   
    //..window, gl init..
    GLuint elements[6] = {  0, 1, 3,  1, 2, 3 };
    while (true)
    {
        // Clear the screen to black
        glClearColor(0.4f, 0.4f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw a rectangle from the 2 triangles using 6 indices
        useShader(vs, fs);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, elements);

        // Swap buffers
        window.display();
    }
    // cleanup
    return 0;
}

Why aren't any VAOs/VBOs needed. I've understood that VBOs are basically buffers that hold different kind of data that will be sent to the GPU. Basically, are vao/vbo usefull only for loading data into the shaders, since I'm gonna need constant data, wouldn't be better to premake the shaders and use them whenever I need them, or do I need to do it the VAO way.

Also when I'm looking to change the layout origin to upper left it logs me that it needs input data oO..

\$\endgroup\$
3
  • \$\begingroup\$ The vertex buffers are for storing vertices and sending them to the gpu. In this case the vertices are hardcoded into the shader which is on the gpu. \$\endgroup\$ Dec 31 '17 at 8:21
  • \$\begingroup\$ @AndrewWilson - note also that glDrawElements sources it's data from a client memory array - this is compatibility profile OpenGL. \$\endgroup\$ Dec 31 '17 at 11:26
  • \$\begingroup\$ What do you mean @MaximusMinimus \$\endgroup\$
    – alex1997
    Dec 31 '17 at 12:55
0
\$\begingroup\$

Aside from sourcing vertices via gl_VertexId, in a more general sense VAOs/VBOs are not needed in this case because:

  • The shaders may be declared as #version 330 core, but...
  • ...the OpenGL C/C++ code is using the compatibility profile.

In the compatibility profile VAOs and VBOs are not needed because the compatibility profile provides other ways of drawing, including:

  • Using VBOs but without VAOs,
  • Using arrays sourced from client memory,
  • Using the old glBegin/glEnd "immediate mode",
  • Some combination of the above.

It's only in core profiles that the requirement to use VAOs/VBOs was introduced.


How can we be certain that this is compatibility profile OpenGL?

Because of this:

GLuint elements[6] = {  0, 1, 3,  1, 2, 3 };

And this:

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, elements);

If it were core profile it would be illegal for glDrawElements to source it's data from a client memory array, and drawing would fail. A buffer object would have to be created, and a VAO would be necessary to contain the ELEMENT_ARRAY_BUFFER binding.


To summarize:

VAOs/VBOs are not mandatory in compatibility profile OpenGL

\$\endgroup\$
2
  • \$\begingroup\$ What would be better to do, to append the indices to glDrawElements or to create VAO and 1 VBO with the indices and to send them to the gpu. I'm looking for a modern way and to keep efficienty too \$\endgroup\$
    – alex1997
    Dec 31 '17 at 12:58
  • \$\begingroup\$ @Maximus: VAOs are not mandatory period. They're manditory here, but that's only because he's using an index list. But they aren't essential to the operation of the pipeline. \$\endgroup\$ Jan 2 '18 at 6:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .