Hi all,
Just a quick question about material batching under OpenGL. What are some of the best practices or submitting batches of geometry to OpenGL for rendering, while minimising state changes? I’m currently looking at a solution where a model is broken up into in a set of MaterialBatches, which then consist of a list of BatchMeshes for that material batch, eg:
struct MaterialBatch {
...
Shader *pShader;
Material *pMaterial; // Set of shader bindings for batch
BatchMesh *pMeshBatchList;
...
}
struct BatchMesh {
...
Matrix *pTransform;
VIBuffer *pBuffer;
BatchMesh *pNext;
...
}
I would submit each batch to the render which would then sort based on the applied material, which I’m currently tossing up the idea of supplying a kind of ClsId for each material as the sorting value. The sorter would perform something like:
void submitBatch(MaterialBatch *pBatch) {
pBatch = getQueuedBatchForMaterial(pBatch->pMaterial);
if (pQueuedBatch == NULL) {
// Material is not currently in the render queue - add it
addBatchToQueue(pBatch)
} else {
// Material is already in the render queue - attach the list of meshes to this queue entry
pBatch->pNext = pQueuedBatch->pMeshBatchList;
pQueuedBatch->pMeshBatchList = pBatch;
}
}
Rendering would then be a matter of:
void renderQueue(RenderQueue *pQueue) {
pBatch = pQueue->pBatchQueue;
while (pBatch) {
// Configure the material for rendering
configureMaterial(pBatch->pShader, pBatch->pMaterial);
// Render the mesh batches
pMesh = pBatch->pMeshBatchList;
while (pMesh) {
// Set modelview transform for rendering the mesh
pShader->setUniformMat3x3(pMesh->pTransform);
// Bind the vertex / index buffer, and submit the lists
pMesh->pBuffer->render();
}
}
}
Is it worth sorting on vertex and index buffers as well in order to minimise state changes? Anyone have any tips on geometry / material / mesh / buffer sorting?
Thanks,
Paul