On Mon, Sep 27, 2010 at 8:05 PM, Christopher Night
<cosmologi...@gmail.com>wrote:

> Thanks for the response! Assuming that rendering means what I think it
> means (actually drawing the thing on the screen, right?),
>
Absolutely.

> I was able to improve the rendering performance significantly using vertex
> arrays in the test I did a few months ago. I was still using a display list
> as well, but I greatly reduced the number of GL commands within the display
> list. The trick was to triangulate all the faces, and render all the faces
> for a given material using a single call to glDrawArrays(GL_TRIANGLES...). I
> realize this is hardware-dependent, but the speedup was dramatic on 2 out of
> 2 systems that I've tried. Maybe it's not the vertex arrays that matter, and
> triangulating all the faces and using a single call to glBegin(GL_TRIANGLES)
> would yield the same speedup. Either way, it's worth looking into I
> think....
>
You must not be using the calls as you think you are, then.  Graphics cards
have a "graphics bus" that handles data transfer to and from the card.
Unfortunately, this graphics bus is slower than either the CPU or the GPU
themselves.

Fixed function (glVertex3f(...), glNormal3f(...), etc.) sends the data to
the card on each call.  So, if you have 900 such calls, you send 900 state
changes to OpenGL across the graphics bus each time the data is drawn.  This
can get slow.

Vertex arrays work similarly, except the data is stored as an array, and the
equivalent of the 900 fixed function calls are sent across the graphics bus
each frame.  Although this batched approach is faster than fixed function,
all the data is still transferred to the card each time the data is drawn.

Display lists work by caching operations on the graphics card.  You can
specify nearly anything "inside" a display list, including fixed function
(and I think) vertex arrays.  To use display lists, you wrap the drawing
code in glGenLists()/glNewList() and glEndList() calls.  The code inside,
after being transferred to the GPU, is stored for later use.  Later, you can
call glCallLists(), with the appropriate list argument.  The list's NUMBER
is transferred to the GPU, and the relevant set of cached operations is
executed.  The practical upshot of all this is that each time you draw the
object, you pass a single number to the graphics card, and the appropriate
cached operations are executed.  This is the way the Wiki .obj loader
works.

Vertex Buffer Objects are a more advanced topic, but they work by caching
vertex arrays on the GPU.

> Improved loading performance comes from the fact that these arrays can be
> pickled, so you don't have to read them directly from the OBJ file after the
> first time. You only need to distribute the pickled OBJ/MTL files with your
> actual game. Psyco or C might be just as good, but this solution was pretty
> simple, and reduces the (subsequent) load times to almost nothing.
>
This is actually a fantastic idea; I love it!

> -Christopher
>
Ian

Reply via email to