Rendering architecture/optimizations with OpenGL ES 1.1
I'm working on a rendering engine that will hopefully be optimal and robust for the iPhone. I had one minor performance question regarding batching a bunch of quad objects with the same texture but different positions and scales.
My approach is somewhat complicated, but I am trying to use the advantage of interleaved vertex arrays.
1)Each object's render function strictly creates the object's world matrix, multiplies the object's verticies by the matrix, and concatenates them onto a vertex list of the renderer.
2)The renderer concatenates each object's verticies together with degenerate triangles.
3)When the renderer draws the scene there is only one glInterleavedArrays() and glDrawArrays() for each texture bind.
My big question is the extra matrix multiply per object done on the CPU better than many draw calls (vs one interleaved array ptr)?
Or maybe this is just way to complex, I'm trying to mimic hardware instancing as best I can in a fixed function pipeline.
(p.s. I'm much more familiar with DirectX if you cant tell)
If you are just doing 2d ( or perhaps some sort of 3d particles) then preprocessing them on CPU is definitely way to go.
If you are doing just quads then the extra matrix multiply per vertex is going to be cheaper than doing bunch of OpenGL state changes.
I am doing something like that for 2d rendering and also for my 3d particles.
As far as other objects ( say with hundred of vertices) , I generally do that only when dealing with static "background" geometry which, once pretransformed, doesn't change.
If you are just doing 2d ( or perhaps some sort of 3d particles) then preprocessing them on CPU is definitely way to go.
If you are doing just quads then the extra matrix multiply per vertex is going to be cheaper than doing bunch of OpenGL state changes.
I am doing something like that for 2d rendering and also for my 3d particles.
As far as other objects ( say with hundred of vertices) , I generally do that only when dealing with static "background" geometry which, once pretransformed, doesn't change.
Sorry to dig this one up and co-opt your thread, but it's the only place I've been able to find anything similar to what I'm doing now.
I decided (after reading some docs from Apple, and my own testing) to do exactly the same thing you guys are describing. My current engine is all 2D. Although drawable objects are not simply billboard quads, they ARE simple enough that I think the technique of pre-calculating world coordinates and then issuing a single draw call will really help me. I'm building some tests right now, and ran across something I've never had to do before. . . Concatenate all the objects individual vertex arrays into a single large array to be passed to draw.
I've always used memcpy or the like, but that doesn't take an "offset" parameter so I can't append data. It will of course just overwrite it from the beginning. I know I can loop through individual values, but that seems excessively dumb. . .
There has to be a solution out there, but I've been at google for the better part of two hours and can't seem to find it (I guess I just don't have the right keyword today). Sorry if this seems like a newb thing to ask, I'm pretty much self taught. Thanks in advance for a kick in the right direction.
Sorry to dig this one up and co-opt your thread, but it's the only place I've been able to find anything similar to what I'm doing now.
I decided (after reading some docs from Apple, and my own testing) to do exactly the same thing you guys are describing. My current engine is all 2D. Although drawable objects are not simply billboard quads, they ARE simple enough that I think the technique of pre-calculating world coordinates and then issuing a single draw call will really help me. I'm building some tests right now, and ran across something I've never had to do before. . . Concatenate all the objects individual vertex arrays into a single large array to be passed to draw.
I've always used memcpy or the like, but that doesn't take an "offset" parameter so I can't append data. It will of course just overwrite it from the beginning. I know I can loop through individual values, but that seems excessively dumb. . .
There has to be a solution out there, but I've been at google for the better part of two hours and can't seem to find it (I guess I just don't have the right keyword today). Sorry if this seems like a newb thing to ask, I'm pretty much self taught. Thanks in advance for a kick in the right direction.
J "Fireball"
I am not sure what exactly is your vertex format for these objects but in my case all of them are pretty much the same ( being quads and all) and thus I don't really separate them at all.
In other words, I have what I call a dynamic vertex buffer which is just a fancy name for a sufficiently large array of vertex definitions, and anytime I need to draw a sprite I add it to that buffer.
Essentially anytime I call a method like drawSprite(x,y,width,height,textureX,textureY,rota tion,scale) I calculate neccesary vertex values on the fly and store them in the array.
Perhaps this approach won't work for you but I found this to be the most efficient way.
As far as copying with memcpy then you don't really need an additional offset parameter .. your destination pointer is your offset .. all you need to do is calculate it yourself and do some pointer arithmetic and you are done.