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\$
  • \$\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\$ – Andrew Wilson 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\$ – Maximus Minimus 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\$
  • \$\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\$ – Nicol Bolas Jan 2 '18 at 6:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.