Engine design theory question

Okay, this is probably rather simple for many here, but is becoming a troublesome thing for me:

I’m designing a 3D engine as the subject implies. It is a fairly simple engine, but I’m wonder what the quickest (speed - not code) way to hand different materials is in a 3D engine.

Lets say I have an object, made up of all different colors and/or textures. Is it quicker to link polys up with the materials, or vice-versa? If this doesn’t make sense, think of it like:

Option 1:

for each material:
set material
glBegin GL_TRIANGLES
for each triangle in material set:
glVertexfv

Option 2:

glBegin GL_TRIANGLES
for each triangle:
set material of triangle
glVertexfv

The only problem I see with option 2 is that you cannot set a texture inside glBegin/glEnd, but let’s assume I was creating a solid color-only engine.

I’ve read that doing 1 glBegin is up to 3x faster than doing many calls. However, it is also faster to do just 1 glColor than many. So where is the better speed increase?

Thanks!

Jeff

You shouldn’t use immediate mode at all, if performance matters, you should use vertex arrays. Sort the different arrays by material type like this:

for each (material)
glDrawArrays();

There are lots of other performance changes you could make (i.e. use VAR & triangle strips), but the two above should help you a lot and aren’t too difficult to create or maintain.

– Zeno

[This message has been edited by Zeno (edited 02-28-2002).]

Try the third option:

Option 3:

for each object
set material
glBegin(GL_TRIANGLES);
drawTriangles;
glEnd();

Setting a material is basically like changing the state of opengl. State changes are very costly. What most engines do is try to group objects/triangles/polygons but the material and/or texture. what I mean is it is best to do something like this.

for each material
set material
draw all objects for that material
next material

the same type of thing applies to textures as well. Other benefits for faster geometry is definately to use arrays. If the geometry is static try using Display lists too. I really am not a big fan of display lists primarily because you can’t modify whats inside them after creation. But that limiting factor is what allows opengl to cache the list and get the better performance.

Hope this helps.
Happy coding.

Read this:

http://www.delphi3d.net/articles/viewarticle.php?article=stateman.htm

And here’s a quote from the NVOGL performance FAQ:

37. What about state changes?
State changes can severely impact performance. As such, they should be minimized by binding primitives with similar state (textures first, then lights, then blending modes, materials and so on) and drawing them all at the same time.

There’s also a large thread about this at flipCode

And of course, use glDraw(Range)Elements instead of that slow immediate mode.

[This message has been edited by richardve (edited 03-01-2002).]

I strongly recommend that you benchmark the various operations you want to do on the cards that you want to target. If the textures have already been uploaded, and you’re changing your modelview matrix between objects, then changing the texture between objects is practically free on many modern cards. Just as an example :slight_smile: