I am working on a little project in C++ using OpenGL. I want to be able to render multiple 2D rectangles either in some color or with texture as efficiently as possible.
However, I am doing this in modern C++, so I am writing many wrappers over OpenGL API so that I have better logical structure, RAII, ...
In this spirit I wanted to create a class Rectangle, which would have a method draw() and this method would activate corresponding OpenGL context and call glDrawArrays(). This works fine, but then I realized, that if I wanted to render more rectangles, I would have to cycle through many instances. They would each switch context and I don't think this is an effective solution.
After a bit of thinking my solution was to create a Renderer object, which would hold a single VAO for all Rectangles, associated program, and huge buffer in which I would hold all coordinates for my objects (Rectangle instance would then be like a smarter pointer to this buffer) and then draw them all at once. Of course it would add me a lot of work with managing the buffer itself (adding/removing rectangles). Would it be better?
Also, do you have any tips what else should I focus on?
change the design. Class rectangle may make sense but draw inside each one does not; you don't want to draw them one at a time, so don't do it that way.
Your graphics class can instead have a single draw function that accepts a vector or something of rectangle class (or better, a generic structure that can be anything that can be drawn, with its type stamped inside itself, ... that is thing[0] might be a rectangle, thing[1] might be a circle, etc).
Seconding Helios... this stuff already exists and has been done for efficiency. The only reason to write your own is if you plan to make your own engine/library. I fully support doing that to learn it (somebody has to do this stuff, and if you enjoy it..). You just learned something. Now apply it and see if you can do it better with a different approach. Often, learning what not to do is almost as good as learning good approaches. This same issue hits outside of graphics ... anywhere you need to process large amounts of data, bulk processing in a tight loop with good memory access etc is going to beat one at a time hopping... and you won't forget that now that you have seen it in action.