Batching

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

From what I remember from a nVidia presentation -
most costly -> least costly

setup FBO - shader program - textures - vertex buffer - uniforms

http://timeli.info/item/1266982/r_Technology_on_Reddit/NVIDIA__AMD__Intel_Explain_How_OpenGL_Can_Unlock_15x_Performance_Gains