Original Post
I'm doing a different project right now, but can't keep my thoughts off that thing. I've written one or two OpenGL-based 2d graphic frameworks so far. I always used OpenGLs immediate mode although knowing it was deprecated and shouldn't be used any more. It was just so damn well fitting the way how vertex data comes in when doing a typical 2d game!
Now, the next time I'll be doing this I won't use immediate mode anymore. I will use VBOs or the DirectX-equivalent to that. The question now is, how to structure all that. Currently, I imagine the following:
-> Allocate one or two VBOs (two in case of VBO double buffering) in the graphics core
--> Wait for draw calls (DrawRect, DrawCircle, ..) and state change calls (SetTexture, SetColor, ...) and queue them in a buffer.
--> When calling "Flip", "Flush" or a similar "frame ended" command: Remove redundant or unneccessary state changes, submit all vertices to the current VBO, then iterate through the buffer and make a DrawArrays for each chunk without state change. In the worst case, there'll be one chunk a triangle, in the best case one chunk per frame.
So far, so good. Or isn't it? If not, tell me! However, some questions come into my mind:
1. How to deal with different vertex formats? For a simple textured rect, I'll need xy, uv per vertex. However, for a multitextured, vertex-colored one with additional z info, it'll be xyz, rgba, u0v0, u1v1, u2v2, ... which i a LOT more. It can't be too good to use the most complex format for ALL cases. Is there a way I can use a single VBO with multiple vertex formats and switch inbetween two DrawArrays-calls?
2. Optimization idea: Z-Prepass. What about drawing the frame two times, once z-sorted from front to back and a second time from back to front? First pass: Z write and Z testing, fully textured and colored with alpha testing for "anything below 1.0". This way, the z prepass only draws completely opaque pixels. Second pass: Draw the scene regularily from back to front. Will this improve performance or just make it worse?
3. The main problem for 2d games: Everything has alpha and usually sorting shapes by state to grow batch sizes isn't possible because of screwing the z order. Does anyone have an idea of how to deal with this? At least, some kind of partial, conditional sorting seems possible: If the current blendmode is "A + B", sorting has no visual effect --> Do it! Are there similar cases in which sorting is okay?
Now, the next time I'll be doing this I won't use immediate mode anymore. I will use VBOs or the DirectX-equivalent to that. The question now is, how to structure all that. Currently, I imagine the following:
-> Allocate one or two VBOs (two in case of VBO double buffering) in the graphics core
--> Wait for draw calls (DrawRect, DrawCircle, ..) and state change calls (SetTexture, SetColor, ...) and queue them in a buffer.
--> When calling "Flip", "Flush" or a similar "frame ended" command: Remove redundant or unneccessary state changes, submit all vertices to the current VBO, then iterate through the buffer and make a DrawArrays for each chunk without state change. In the worst case, there'll be one chunk a triangle, in the best case one chunk per frame.
So far, so good. Or isn't it? If not, tell me! However, some questions come into my mind:
1. How to deal with different vertex formats? For a simple textured rect, I'll need xy, uv per vertex. However, for a multitextured, vertex-colored one with additional z info, it'll be xyz, rgba, u0v0, u1v1, u2v2, ... which i a LOT more. It can't be too good to use the most complex format for ALL cases. Is there a way I can use a single VBO with multiple vertex formats and switch inbetween two DrawArrays-calls?
2. Optimization idea: Z-Prepass. What about drawing the frame two times, once z-sorted from front to back and a second time from back to front? First pass: Z write and Z testing, fully textured and colored with alpha testing for "anything below 1.0". This way, the z prepass only draws completely opaque pixels. Second pass: Draw the scene regularily from back to front. Will this improve performance or just make it worse?
3. The main problem for 2d games: Everything has alpha and usually sorting shapes by state to grow batch sizes isn't possible because of screwing the z order. Does anyone have an idea of how to deal with this? At least, some kind of partial, conditional sorting seems possible: If the current blendmode is "A + B", sorting has no visual effect --> Do it! Are there similar cases in which sorting is okay?