I am currently trying to write a (very simple) queued renderer using OpenGL. My current idea looks like this:
struct RenderCommand {
GLUint vao;
GLUint texture;
GLUint shader;
GLInt zOrder;
};
void Renderer::addCommand(const RenderCommand& cmd) { /* add to queue */}
void Renderer::render() {
/* sort the command queue to try and z-sort, batch textures, etc. */
for(const auto& cmd: queue_) {
// Bind shader/vao/texture when necessary, issue draw calls
}
}
Now my problem is this: for sprites for example, I only have one set of quad vertices on the GPU, and I send the sprite vertex shader the sprite size using a uniform. Same goes for the model transform matrix for literally any object. That's okay when render calls issued when iterating over scene objects, but becomes a problem when everything is queued: since most sprites will use the same shader, how do I set the uniform?
I've had a few ideas for solutions, but none of them feels right:
Add data in
RenderCommand
for size, model matrix, etc. The big problem with that is flexibility: it supports the engine's default sprite (or 3D model or text) shader, but custom shaders with other uniforms won't work.Add a custom data pointer to
RenderCommand
to point to uniform data to send before rendering. This is probably the most flexible option.Add a
UniformCommand
type, which only uploads a uniform to the currently bound shader. It'll have to be handled carefully when the queue is sorted, to ensure it stays contiguous with whatever shader and model it corresponds to, but that sounds feasible.