How does OpenGL store it's states?

Do they use 32 bits? I would assume not because there are more than 32 states.

Am I correct when I say that variables created in opengl for states are initialized using this method:

GLenum state_polygon{GL_POLYGON_SMOOTH, GL_POLYGON_STIPPLE};

Or does it look like this:
GLenum states{all state variables};

It’s probably your last suggestion, it’s the one that makes most sense if you take a quick look at gl.h.

But why the heck do you want to know that? OpenGL doesn’t specify how to do it, so each driver could do it differently internally.

My model library is using bits for states. I want to store more than 32 states.

I could do this:
bool StateArray[256];

enum state{Blah1, Blah2…};

StateArray[Blah1]=true;

I’d rather know if there’s a better way…is there?

That seems like an easy straightforward way to do it… what are your problems with doing it like that?

I’m just trying to say that it really doesn’t matter, as long as things are going fast enough and are easy to use in the rest of your code. (Trying to do it ‘modular’ is good too, but in this case you could easily write a class that overloads the [] operator, if you’re into c++.)

If you have loads of bits (256 is not) then you could perhaps use std::vector<bool> which stores bools as bits (instead of taking up a byte, which is the common case) … but you’d lose a lot more performance trying to bit-fiddle like that than you’d gain by having a smaller memory footprint.

I started programming about 5+ years ago. During that time computers weren’t all that fast, and every book I read and every tutorial I saw have brain washed me into thinking “don’t use any more memory than you have to!!!”. In one way it’s helped me to keep things small, but in the other way it’s holding me from doing more things.

I’ll just have to get over it. You can’t push forward unless you push the limits.

Here’s an example of saving to much space. Way back when, when I had been programming for about 3 years, I had a cool idea for 3D models…it was to index vertices so you could share vertices that way. I said to myself “wow, all the indices would take up alota room in memory if I did that…the pros must have a better way”. Gah!!! If I had only pushed my limits. I’ve learned never to hold back sence I found out that that’s how the pros DO do it .

I believe the trade-off was the same then as it is now (I’ve coded in C/C++ for some 8 years now, and was hacking assembly on amiga before that).

Don’t optimize until you know it matters!

What if you optimize the heck out of this to save… say… 4 kb… only to allocate 200kb of stuff in another place… (and I’m being conservative with numbers here…)

[This message has been edited by macke (edited 04-16-2001).]

Idea: Why don’t you go look in the MESA source?

ftp://ftp.mesa3d.org/pub/sourceforge/mesa3d/

It’s all C, but it’s an opengl implementation nevertheless.

little magic trolls do it for you
no need to worry about them.

Man Kaber…

… would my graphics card work faster if I threaten it with a spanking aswell?

Maybe its a little Demon that sits on the other side of the monitor, painting his ass off with a small brush.

Maybe he is the reason why we mistype so often…

Originally posted by Hull:
[b]Man Kaber…

… would my graphics card work faster if I threaten it with a spanking aswell?

Maybe its a little Demon that sits on the other side of the monitor, painting his ass off with a small brush.

Maybe he is the reason why we mistype so often…

[/b]

man, now that’s just silly
of course it would

laterz.

WhatEver,

My <GL/gl.h> uses a lot of #defines and each of the GLenum variables is a 32-bit number (mine are typedef’d unsigned ints). Remember that because the numbers are 32-bits doesn’t mean there are 32 possible values that can be stored in them. Instead there are 2^32 possible values, or 4294967296. Bit patterns are a really good way to save space and store lots of information. For example, if you had a 3-bit variable, it could have 8 (not 3) different values: 000, 001, 010, 011, 100, 101, 110, 111

Hope that helps,
Toby

But you couldn’t easily see wether a feature is enabled or disabled.

But, hey, we’re inside states here. And I don’t think you’d have to check the states for every polygon as opengl drivers might have to do (btw: why do they have big switch statements, when they could alter their code?)… sO I’d think it is best to make it possible that the user can actually change the states easily.

Michael, you could easily test whether a feature is enabled or disabled with an inline function:

// Some hardcoded feature value.
#define SOME_FEATURE 0xSOME_BIT_PATTERN

// Given some global state variable that
// holds the system state.
inline bool isFooEnabled()
{
if ((SOME_FEATURE & global_state_variable) == SOME_FEATURE) return true;
return false;
}

or even better:

inline GLenum isEnabled(GLenum state)
{
return SOME_FEATURE & global_state_variable;
}
// Which you could use like this:

if (GL_DEPTH_TEST == isEnabled(GL_DEPTH_TEST)) PerformAction();

// which would reduce the number of “if”
// statements required plus it would work
// for all the states in the system.

Hmmm, might implement something like this myself. Currently I’ve got a singleton system state manager with wrappers around a whole lot of OpenGL calls. I did this in response to a post of mcraigheads which said to manage system state yourself to avoid the overhead associated with redundant state changes.

Thanks for the new train of thought WhatEver!

ffish
But the use won’t be able to edit the values while the engine is running. That’s why I have runtime-variables.
If you do wrapping of opengl states, that what you propose os really ok!

Hey yeah,

You’re right Michael. I guess I’ll stick with my state manager, since I do update my system state variables.

Thanks

Well, I was relating to variables that have nothing to do with opengl states . Just with engine states.
I’ll most probably use your thing to squeeze some performance out of it for opengl states
So… Thanx to YOU!

How about this for a solution.
Give each state a unique value. Create an array of 32-bit integers (how big of an array will depend on how many unique states you have. Then access bits like this:



unsigned int bits[100]; //holds 3200 bits

unsigend int stateArrayIndex(unsigend int state)
{
   return (state &gt;&gt; 5);
};

unsigend int stateBitIndex(unsigend int state)
{
   return (state & 0x0000001F);
};

void setStateBit(unsigned int state)
{
   unsigned int index = stateArrayIndex(state);
   unsigned int shift = stateBitIndex(state);
   bits[index] |= (1 &lt;&lt; shift);
}

void clearStateBit(unsigned int state)
{
   unsigned int index = stateArrayIndex(state);
   unsigned int shift = stateBitIndex(state);
   bits[index] &= ~(1 &lt;&lt; shift);
}

bool getStateBit(unsigned int state)
{
   unsigned int index = stateArrayIndex(state);
   unsigned int shift = stateBitIndex(state);
   unsigned int bit = bits[index] & (1 &lt;&lt; shift);
   return (bit != 0);
}

This is how I would probably do it

Hey, I think you’re exagurating… After all it’s about little states! you can simply use a char for a state. We aren’T living in the time where we have to use only two digits for a date!
You can have 1024 states, and they will still be only 1kb…
And yours in slower then.

Of course, I should mention this only works for boolean states (glEnable/glDisable/glIsEnabled). Any state that has a value (like color has r,g,b,and a values) would have to be stored in its own variable. And to do something like glGetIntegerv, you would essentially have to do a giant switch statement, which is a killer for performance.

Actually, thinking about the switch, I wonder how good VC++ optimizes switch statements. If you have a switch with 1000 cases, I wonder if it does a binary search to find the case you need. I certainly hope it doesnt just plow right through them.

I’ll stick to my method but I like it LordKronos! Anything with obfuscating binary arithmetic must be good!

Seriously though, I guess the problem boils down to your second line: each state needs a unique value. The problem with the GL states is that there are so many of them that you can’t have a bit pattern that doesn’t overlap others. That’s why my inline functions above can query but not set.

Also, as you mentioned, your solution works for bools but not multivalued states My method (not posted) borrows (or copies) from the excellent Game Programming Gems book. I have a singleton class which wraps some OpenGL calls like glEnable/Disable etc, manages OpenGL states and copes with the multivalued states. As I said, the main reason I implemented this is in response to a post by mcraighead. It’s probably a bit (lot) slower than yours but more readable. I’ll keep yours in mind though.