Good day folks,
I’m busy learning OpenGL while trying to build my own immediate mode 2D shape drawing library. But I’m having trouble figuring out the role the VAO plays in all of this. To explain the basics of the library. The user calls DrawCircle, DrawLine, DrawRectangle etc and each of those methods in turn create a VBO and write the vertices for that shape to the VBO. Once all shapes have been “drawn”, the user calls EndFrame, which renders the data to the screen. All shapes have the same basic structure: 3 float vertices which describe their position. Thats it, everything else needed to draw the shape is sent to the fragment shader in a uniform block.
Firstly, My understanding of VAOs is that they describe to the vertex shader the structure of the data sitting in the VBOs via attributes. Do I have that basic aspect correct? Secondly, If my VBOs all contain data with the same structure, I should really only need a single VAO for all shapes rendered, do I have that right?
Going on my understanding of the VAO, the workflow for the shape library works as so:
- During instantiation of the library, I create the VAO:
glGenVertexArrays(1, &GLShapeVertexArray); glBindVertexArray(GLShapeVertexArray); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexArrayAttrib(GLShapeVertexArray, 0);
- whenever the user calls any of the Draw* functions I create the VBO like so:
glGenBuffers(1, &Circle.GLFillVertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, Circle.GLFillVertexBufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(float) *(VertexCount * 3), RawVertices, GL_STATIC_DRAW);
- When the user calls the EndFrame method, I first bind the VAO:
- I then iterate over the various shapes and render with:
glDrawArrays(GL_TRIANGLE_FAN, 0, Shape.VertexCount);
This method of rendering crashes quite spectacularly with an access violation trying to read address 0x0000000000 once the glDrawArrays method returns. Before I tried rendering like this, I would define a VAO per shape and bind that VAO just before drawing the shape, that worked perfectly, but I was concerned that I was doing it incorrectly.
So have I misunderstood the purpose of VAOs? If so, for this particular context, what would be a better way to handle the VAO?