Yes, glEnable/glDisable are also slow. Think of how many enable/disable states there are in OpenGL (in unextended GL, there must be about 50 or so), and then consider that they are not contiguous enumerant values. That means you end up with a big switch statement. Not only that, but sending a redundant Enable or Disable will cause us to set dirty bits, etc., causing more work at a later time.
I will repeat what I said before. If you care about performance, follow the advice of my previous post:
[b]
Don’t send redundant state changes. Just don’t.
Either design your code to avoid them or wrap GL functions to mirror state in your app. Test whether you’re doing a redundant state change, and if you are, don’t call into GL.
[/b]
Obviously, it is preferable to design your code such that you never send a redundant state change in the first place rather than to use a wrapper.
Any wrapper will have a break-even point. If more than X% of the GL calls it replaces would have been redundant, the wrapper will be a speedup. Depending on the implementation and the wrapper, I’d generally peg X between around 2% to 20%. This is not a scientific estimate. You might want to do your own tests. But if, say, 50% of your Enable or Disable calls are redundant (which could be true if the values were completely random), a wrapper is a CLEAR win.
Note also that you can make wrappers be inline functions, and if you’re wrapping Enable/Disable, you should have a separate function for each enable you wrap so you don’t need a big switch statement:
int lightingEnabled = 0;
inline static void MyEnableLighting(void)
{
if (!lightingEnabled) {
glEnable(GL_LIGHTING);
lightingEnabled = 1;
}
}
inline static void MyDisableLighting(void)
{
if (lightingEnabled) {
glDisable(GL_LIGHTING);
lightingEnabled = 0;
}
}
Or, alternately, if you prefer:
int lightingEnabled = 0;
// because this is an inline function, the compiler should optimize the case where enabled is a constant value 0 or 1
inline static void MySetEnableLighting(int enabled)
{
if (enabled == lightingEnabled) {
return;
}
if (enabled) {
glEnable(GL_LIGHTING);
} else {
glDisable(GL_LIGHTING);
}
lightingEnabled = enabled;
}
Watch out, if you sometimes bypass your wrapper, your program will get confused. If you wrap a GL state function, ALWAYS use the wrapper.