ARTICLE AD BOX
My research yielded mixed results about swapping VAOs, some people saying to avoid it whenever possible, and others saying its a pretty cheap operation.
Many cheap operations make an expensive one. Not that it matters, what's worse about your naive approach is that you're switching shaders every object. That is a truly expensive operation, that also implies additional expensive operations (uploading uniform variables, binding textures on different texture units, (multiple) different VAO's for vertex data, SSBOs, etc etc etc).
Unless you're doing something to group objects by shader and/or texture bindings, your maximum throughput will be severely limited.
I would like to avoid grouping up the objects into one VBO
That is unfortunate.
I also looked into named buffers, but I couldn't find a way to make them fit into my framework.
That is total nonsense, named buffer operations are just regular operations that run without actively binding buffers and polluting your global state. It simplifies code, and is a one to one replacement.
I am not looking to write super optimized code, but I would like to keep it reasonable and proper
Changing state object by object will never be "reasonable", but if all you're rendering is two triangles that change color, your approach will work. It will also be a complete dead-end, because proper architecture will require a complete redesign of your entire object data, update and render loops.
My main concern is the glVertexAttribPointer, which binds to a VBO, and probably has to be re-done for the draw call of every object
You will find that most general purpose engines will define a standard vertex format for the entire application, and then use it in a standardized way. A few bytes more or less to transfer won't impact performance nearly as much as rebinding shaders. By a factor of millions.
