Enumerations and alpha blending
by Phil Carlisle · 01/29/2004 (10:16 pm) · 6 comments
Download Code File
Adding Console Enumerated types to Torque objects.
You know when you go to edit an object in the property editor in torque and you see those grey buttons next to an object (the ones like horizontal and vertical alignment).
Well, we're going to learn how to do that!
Why would we want to?
Well, suppose youve got a property of some class that you want to give the user a number of options to choose from, or you've got some kind of base class that you need to produce some property that is used by the derived classes?
In my example case, I'm going to use one of the cases I wanted to use myself. That is alpha blend types. I had a Gui control I wanted to have the option of setting the alpha blend values for.
So how do we setup the enumeration? Lets see!!
First step, is to actually define the enumeration table, this is just the list of available values. Lets look at some example code, this goes in your classes header:
So what does this do? well, it defines an enumeration of values (if you dont know what an enumeration is, please have a look at your compilers docs, theyre useful!). In this case, it defines a number of different blend factors for source and destination blends (again, if you dont know what blend factors are, consult the OpenGL spec). You'll notice that the values for each "FACTOR" is the value that you can find in OpenGL's headers, thats so we can use the blendmode values directly in OpenGL calls (glBlendFunc to be exact).
Then we define two variables, blendSrc and blendDst. There's no real reason we only define two of these variables other than that's what the glBlendFunc function requires.
So these would be made public inside our classes header file, lets go look at the .cc file and see how that works!
First off, we need to initialise the values (remember blendSrc and blendDst are member variables) so we use some code like:
Thats got our initial values setup to SRC_ALPHA and ONE. Note the use of the ClassName::Blah thats there because we defined the enumeration as a public part of the class, so to use one of the blend modes, we have to access its value by specifying the class as part of its name. Dont worry about that too much, its just a syntax thing for C++.
Ok, now lets get onto the meat of the code:
This code goes in its own code block, I ususally slot it in just before the InitPersistFields function, what it does, is define a static (i.e only ever one of them is created for all class instances) table of value to string mappings. This is used so that the code which displays the values in the popup list of values you can choose has a string to represent each value.
Ok, so we have a number of values and variables to shove those values in, so there's only the final step of making those values available in the editor!
This code goes in the InitPersistFields function of your class.
What this code does, it that it tells Torque that the values blendSrc and blendDst are available to it, they are of "TypeEnum" which means they are an enumeration, it tells torque where they are by giving the offset and classname. Finally it then gives the enumeration table that it must read the values out of, in this case its the table we defined above (gBlendModes).
So thats it! if you rebuild the codebase with these changes, whatever class you put in will now have 2 fields which you can choose a blendSrc and a blendDst value for. Of course, they dont actually do anything until you hook them up in your code.
So in your render function, you would do something like:
Now when you inspect an instance of this class, you will find that you can select the source and destination blend factors from a popup list. Niiiiice!
These popup lists can be used for all sorts of things. Give them a go!
Ive included a gui control I did as a test for this, all it does is use a bitmap and applies a few transformations on it, (scale, rotate, zoom or whatever). But you can alter the blend functions to do some fun gui effects!
Thats all for now.
Let me know if you find any of this hard to understand!
Adding Console Enumerated types to Torque objects.
You know when you go to edit an object in the property editor in torque and you see those grey buttons next to an object (the ones like horizontal and vertical alignment).
Well, we're going to learn how to do that!
Why would we want to?
Well, suppose youve got a property of some class that you want to give the user a number of options to choose from, or you've got some kind of base class that you need to produce some property that is used by the derived classes?
In my example case, I'm going to use one of the cases I wanted to use myself. That is alpha blend types. I had a Gui control I wanted to have the option of setting the alpha blend values for.
So how do we setup the enumeration? Lets see!!
First step, is to actually define the enumeration table, this is just the list of available values. Lets look at some example code, this goes in your classes header:
/// ================================================ code
/// @name Gui Alpha Values
enum BlendModes
{
ZERO = 0,
ONE = 1,
SRC_COLOR = 0x0300,
ONE_MINUS_SRC_COLOR = 0x0301,
SRC_ALPHA = 0x0302,
ONE_MINUS_SRC_ALPHA = 0x0303,
DST_ALPHA = 0x0304,
ONE_MINUS_DST_ALPHA = 0x0305,
DST_COLOR = 0x0306,
ONE_MINUS_DST_COLOR = 0x0307,
SRC_ALPHA_SATURATE = 0x0308,
NumBlendModes = 10
};
BlendModes blendSrc;
BlendModes blendDst;
/// ================================================ codeSo what does this do? well, it defines an enumeration of values (if you dont know what an enumeration is, please have a look at your compilers docs, theyre useful!). In this case, it defines a number of different blend factors for source and destination blends (again, if you dont know what blend factors are, consult the OpenGL spec). You'll notice that the values for each "FACTOR" is the value that you can find in OpenGL's headers, thats so we can use the blendmode values directly in OpenGL calls (glBlendFunc to be exact).
Then we define two variables, blendSrc and blendDst. There's no real reason we only define two of these variables other than that's what the glBlendFunc function requires.
So these would be made public inside our classes header file, lets go look at the .cc file and see how that works!
First off, we need to initialise the values (remember blendSrc and blendDst are member variables) so we use some code like:
/// ================================================ code
// this would go in your constructor..
blendSrc = GuiBitmapEffectCtrl::SRC_ALPHA;
blendDst = GuiBitmapEffectCtrl::ONE;
/// ================================================ codeThats got our initial values setup to SRC_ALPHA and ONE. Note the use of the ClassName::Blah thats there because we defined the enumeration as a public part of the class, so to use one of the blend modes, we have to access its value by specifying the class as part of its name. Dont worry about that too much, its just a syntax thing for C++.
Ok, now lets get onto the meat of the code:
/// ================================================ code
static EnumTable::Enums blendTable[] =
{
{ GuiBitmapEffectCtrl::ZERO, "ZERO" },
{ GuiBitmapEffectCtrl::ONE, "ONE" },
{ GuiBitmapEffectCtrl::SRC_COLOR, "SRC_COLOR" },
{ GuiBitmapEffectCtrl::ONE_MINUS_SRC_COLOR, "ONE_MINUS_SRC_COLOR" },
{ GuiBitmapEffectCtrl::SRC_ALPHA, "SRC_ALPHA" },
{ GuiBitmapEffectCtrl::ONE_MINUS_SRC_ALPHA, "ONE_MINUS_SRC_ALPHA" },
{ GuiBitmapEffectCtrl::DST_ALPHA, "DST_ALPHA" },
{ GuiBitmapEffectCtrl::ONE_MINUS_DST_ALPHA, "ONE_MINUS_DST_ALPHA" },
{ GuiBitmapEffectCtrl::DST_COLOR, "DST_COLOR" },
{ GuiBitmapEffectCtrl::ONE_MINUS_DST_COLOR, "ONE_MINUS_DST_COLOR" },
{ GuiBitmapEffectCtrl::SRC_ALPHA_SATURATE, "SRC_ALPHA_SATURATE" }
};
static EnumTable gBlendModes(GuiBitmapEffectCtrl::NumBlendModes, &blendTable[0]);
/// ================================================ codeThis code goes in its own code block, I ususally slot it in just before the InitPersistFields function, what it does, is define a static (i.e only ever one of them is created for all class instances) table of value to string mappings. This is used so that the code which displays the values in the popup list of values you can choose has a string to represent each value.
Ok, so we have a number of values and variables to shove those values in, so there's only the final step of making those values available in the editor!
/// ================================================ code
addField("blendSrc", TypeEnum, Offset(blendSrc, GuiBitmapEffectCtrl), 1, &gBlendModes);
addField("blendDst", TypeEnum, Offset(blendDst, GuiBitmapEffectCtrl), 1, &gBlendModes);
/// ================================================ codeThis code goes in the InitPersistFields function of your class.
What this code does, it that it tells Torque that the values blendSrc and blendDst are available to it, they are of "TypeEnum" which means they are an enumeration, it tells torque where they are by giving the offset and classname. Finally it then gives the enumeration table that it must read the values out of, in this case its the table we defined above (gBlendModes).
So thats it! if you rebuild the codebase with these changes, whatever class you put in will now have 2 fields which you can choose a blendSrc and a blendDst value for. Of course, they dont actually do anything until you hook them up in your code.
So in your render function, you would do something like:
/// ================================================ code glEnable(GL_BLEND); glBlendFunc(blendSrc, blendDst); /// ================================================ codeInstead of the more usual hardcoded:
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
Now when you inspect an instance of this class, you will find that you can select the source and destination blend factors from a popup list. Niiiiice!
These popup lists can be used for all sorts of things. Give them a go!
Ive included a gui control I did as a test for this, all it does is use a bitmap and applies a few transformations on it, (scale, rotate, zoom or whatever). But you can alter the blend functions to do some fun gui effects!
Thats all for now.
Let me know if you find any of this hard to understand!
About the author
#2
01/30/2004 (9:01 am)
Hmmm, I think I might use this (meaning the enums with GL blending tokens) to add some blending control to my interior "detail texture" support (to be released real soon now)
#6
-- Markus
01/31/2004 (4:14 am)
@Phil: Send an email to your team17 and blueyonder address. Tell me if it reached you.-- Markus
Torque Owner Markus Nuebel
Cool idea.
Do you want me to change this for the RealmWars motion trail?
BTW: Got my emails, regarding lens flare and ladder stuff?
-- Markus