# Why aren't VAOs/VBOs needed here?

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

// Create and compile the fragment shader

}

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
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..

• 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. – Andrew Wilson Dec 31 '17 at 8:21
• @AndrewWilson - note also that glDrawElements sources it's data from a client memory array - this is compatibility profile OpenGL. – Maximus Minimus Dec 31 '17 at 11:26
• What do you mean @MaximusMinimus – alex1997 Dec 31 '17 at 12:55

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

• 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 – alex1997 Dec 31 '17 at 12:58
• @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. – Nicol Bolas Jan 2 '18 at 6:40