My application (with a modernish OpenGL >= 3.0 and an OpenGL ES 2.0 backend) renders more or less streaming data with up to millions of vertices with different vertex layouts and sizes (some simple, some quite big). Some data is indexed, some is not. I'm currently hitting the problem of draw calls and buffers (index and/or vertex) becoming too large, so I need to split them. I have a hard time understanding when and how I should correctly split draw calls. My questions:
- The limits GL_MAX_ELEMENTS_VERTICES and GL_MAX_ELEMENTS_INDICES, according to the docs, tell the application the maximum value for well-performing glDrawRangeElements calls. Why is this ONLY for glDrawRangeElements, why not glDrawRangeElementsBaseVertex or even glDrawElements?! This does not make sense to me, because glDrawRangeElements is more or less glDrawElements after all. Also I've see a couple of OpenGL implementations reliably crash when rendering indices above that limit, even with glDrawElements. On the other hand some stackoverflow answers say that the limits are not relevant anymore... What else should I use to decide how to split my draw calls then?
- What about glDrawArrays? Is there an upper limit (e.g. GL_MAX_ELEMENTS_VERTICES)?
- For the OpenGL ES 2.0 backend I require the extension "GL_OES_element_index_uint" to use indices above the 65k limit. What limits should I choose there for draw call size?
- I have decided to limit my IBO and VBO sizes to a certain limit (max. 64MB), as there's no way to ask OpenGL about what buffer size I can allocate, else than checking for GL_OUT_OF_MEMORY. That means I have to additionally split according to that buffer size (both IBO and VBO). Is there a better way to check buffer limits?
- What should be the preferred way to split draw calls? Make them small in the application already, then batch them when rendering? This will lead to lots of duplicate vertices in some case, which is not ideal.
Splitting them in the render code can be complicated, because index data has to be analyzed, indices changed or memory copied, but in the end it is the only place where you can be sure all limits are respected...
I'd prefer reliable, stable solutions even if they provide lower performance. I'm targeting OpenGL Desktop hardware newer than ~2010 and Angle as a conversion layer from OpenGL ES 2.0 -> Direct3D in case of Remote Desktop connections.