What does the glEnable and glDisable code look like?

This was asked at gamedev.net so I thought I’d ask it here because of the nvidia crew who posts here often.

Ever since I started OpenGL I’ve heard you should make your own state wrapping code. Is calling enable or diable so expensive that you should write code to remember if it’s enabled already?

For example, enabling and disabling lights. You do this once per frame. Is the function call THAT heavy, or are the people who say that being really paranoid about losing even just a little time on a function call.

Personally I just call glEnable or glDisable whenever it’s needed. Spider3D is modular so if someone uses their own state recorder it would be broken by anything that Spider3D does and vise-versa.

Check the MESA code, it’s all in there.

-SirKnight

Some enables/disables will force a pipeline flush, so yes, it may be a problem. In a once-per-frame scenario it’s definitely not.

But intercepting each and every enable/disable is bound to be counterproductive. If it were a generally applicable solution, driver writers would do that. Last time I heard they didn’t.

The only real ‘solution’ is to sort objects by render states and to not call enable/disable in the first place.

I still don’t believe this issue is real, so I don’t care. My wild guess estimates a performance delta of zero. But as always, you should check a real world scene and benchmark it, maybe you get lucky.

I was just looking through the mesa code to find this and all I have to say is good luck figuring out from that code how it’s done. Crazy stuff in there.

-SirKnight

Thanks guys.

LOL SirKnight!

I’ve never even heard of the MESA code before. I’ll look into it(curiosity ) when I get the chance.

Sort by state, but then only change the state that actually needs to be changed.

One method I’ve used (and heard described on the GDAlgorithms mailing list, so I’m not alone :slight_smile: is to compress all enables we need into a uint, and then run through the list of materials, xoring the requested flags with the current set of flags, and change the enable of the flags that change.

I e, as a mock-up:

#define EnableLighting 0x1
#define EnableAlphaTest 0x2
#define EnableZTest 0x4

foreach( list::iterator ptr( stuff_.begin() ); ptr != stuff_.end(); ++ptr ) {
uint requestedState = (*ptr).state;
uint changed = requestedState ^ currentState_;
if( changed ) {
if( changed & EnableLighting ) {
( ( requestedState & EnableLighting ) ? glEnable : glDisable )( GL_LIGHTING );
}
if( changed & EnableAlphaTest ) {
( ( requestedState & EnableAlphaTest ) ? glEnable : glDisable )( GL_ALPHA_TEST );
}
if( changed & EnableZTest ) {
( ( requestedState & EnableZTest ) ? glEnable : glDisable )( GL_DEPTH_TEST );
}
currentState_ = requestedState;
}
}

Of course the real code has more flags than this :slight_smile: You can actually build this code using a mostly table-driven manner and a for loop that tests bits in the “changed” word.

[This message has been edited by jwatte (edited 01-18-2003).]