Replacing display lists when porting from OpenGL to OpenGL ES


M-HT

Very Active Member
Joined
Nov 30, 2007
Messages
663
Location
Bratislava
Website
github.com
Hi,

I want to confirm the answers to two questions regarding the replacement of display lists when porting from OpenGL 1.x to OpenGL ES 1.x.

Q1: The best (in the sense of most efficient execution) way to replace a display list is to use vertex buffer objects, if they are available, and if they are not available use vertex arrays ?

Q2: If the display list contains disjointed objects (i.e. two polygons - triangle strips or triange fans), I have to use draw command (i.e.glDrawArrays) for each of the objects - there isn't a way to use just one draw command to display more polygons ?
 
Last edited by a moderator:
1. I haven't found vertex arrays themselves to be a significant bottleneck in my optimizations.

The SGX is using shared memory, but I don't know whether the driver internally copies your glVertexPointer when you do a glDrawArrays call or operates on it in-place. Might be worth investigating.

There are also some pretty good arguments for interleaved arrays, which is represented in memory as a list of "pixel = {vertex, color, tex coord, normal}" instead of separate lists for each attribute. This is nice because the GPU has everything it needs to render each pixel in the same area of memory.

2. I don't know of a way in fixed function ES to render two separate modes with one call.

(Shameless plug: have you tried libGL?)
 
Last edited by a moderator:
A1: yes vbo's are the way to go to efficiently draw with GLES. just try to avoid transferring vertex data from the main ram to the gpu's memory for never changing models, whatever you use for it.


some good info about it here: http://developer.apple.com/library/ios/documentation/3ddrawing/conceptual/opengles_programmingguide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html


A2: glDrawArrays takes the primitive as an argument, so yes, you can only draw one type of primitives with one call. the only solution would be converting from one primitive type to the other abd combine the vertex data.
 
Last edited by a moderator:
Last edited by a moderator:
Thanks for the answers.

The SGX is using shared memory, but I don't know whether the driver internally copies your glVertexPointer when you do a glDrawArrays call or operates on it in-place. Might be worth investigating.

There are also some pretty good arguments for interleaved arrays, which is represented in memory as a list of "pixel = {vertex, color, tex coord, normal}" instead of separate lists for each attribute. This is nice because the GPU has everything it needs to render each pixel in the same area of memory.
I think I'll do some tests with these.

(Shameless plug: have you tried libGL?)
I know about it, but I haven't tried it yet.

I try to avoid additional dependencies if it's not neccessary.

The amount of OpenGL -> OpenGL ES conversions wasn't yet so big, but if I run across such case, I'll take a look at libGL.

I'll have a look at these.
 
Last edited by a moderator:
/>


VBO's don't give you any/significant performance improvements in Pandora over vertex arrays as it uses slow shared memory (no vram for GPU).


You might save some memory copying in driver, but I doubt it.
thought the driver has some memory reserved for it's use, so at least you'll save copying over from applications memory to the gpu ones. but i havent really compared performance.
 
Just a quick notice - glGetString(GL_EXTENSIONS) reveals that Pandora supports GL_EXT_multi_draw_arrays extension, so it's possible to draw multiple triange strips (and other types) with one call without using degenerate triangles (using functions glMultiDrawArraysEXT and glMultiDrawElementsEXT). I don't know whether it's actually faster than multiple calls to glDrawArrays / glDrawElements.
 
I did some tests using vertex arrays (I'll do tests with VBOs tomorrow).

I was testing drawing single-colored polygons.

using triangle fans:

fastest was glColor4f + glVertexPointer + glDrawArrays per polygon

glVertexPointer + glColorPointer + glDrawArrays per polygon was slower, using interleaved vertex data didn't help here - it was slightly slower

glVertexPointer + glColorPointer + glMultiDrawArraysEXT (drawing all polygons with one call) was slowest, using interleaved vertex data helped here - it was slightly faster (when drawing a lot of polygons)

using triangle stripes:

results were similiar, only results with using interleaved vertex data were reversed

I also tested version with degenerate polygons (I duplicated the first and last vertex of every polygon in the array) - drawing all polygons with one glDrawArrays call - and this was much faster that even glColor4f + glVertexPointer + glDrawArrays per polygon (when drawing a lot of polygons, the difference was smaller). Using interleaved vertex data didn't help here - it was a bit slower (but still much faster than glColor4f + glVertexPointer + glDrawArrays per polygon).

Note: to use glMultiDrawArraysEXT I had to call eglGetProcAddress("glMultiDrawArrays") and not eglGetProcAddress("glMultiDrawArraysEXT")
 
I did the tests using VBOs.

Using VBO for every polygon is really slow.

Using single VBO for all polygons and calling glDrawArrays for every polygon is faster than analogous situation using vertex array instead of VBO.

Using single VBO for all polygons and single call to glMultiDrawArraysEXT to draw all polygons was faster than calling glDrawArrays for every polygon, but when drawing a lot of polygons at once (somwhere between 5000 and 10000), the speed went rapidly down - it was much slower than calling glDrawArrays for every polygon.

And like with vertex arrays, when drawing triangle strips using single VBO and using degenerate triangles to draw all polygons using single glDrawArrays call was the fastest option (faster than using vertex arrays).

Using interleaved vertex data was sometimes slightly slower and sometimes slightly faster.

I think I'll just use vertex arrays - it seems to be the best option.
 
Using single VBO for all polygons and single call to glMultiDrawArraysEXT to draw all polygons was faster than calling glDrawArrays for every polygon, but when drawing a lot of polygons at once (somwhere between 5000 and 10000), the speed went rapidly down - it was much slower than calling glDrawArrays for every polygon.
Games like Quake 3, Jedi Knight 2 and other games have around 1000-2000 polygons per Model. Since each model is drawn seperately I think multi tex way is a good way when using gl es 2. But I think Jedi Knight 2 is using open gl es 1 (which is faster anyway), or a I wrong?
 
Back
Top