T3D 1.2 - Image Modulation
by Robert Fritzen · 09/27/2012 (9:23 pm) · 1 comments
So, a while back I asked about in-game image coloration. I was pointed in the direction of using the GFXDrawUtil class' setImageModulation function to accomplish this and some sample code was provided. Unfortunately the sample code that I was provided is no longer there, and since I'm almost certain someone will be looking for a function like this at some point, I've decided to put up what I have recently re-coded and have functioning in my own copy of T3D 1.2
open GuiBitmapCtrl.h: (note, when I use .'s it indicated lines of code, just skip down to the relevant parts, I indicate those lines/sections with comments)
This will add our new information to the class, now let's get it in the engine, open guiBitmapCtrl.cpp and make the following additions/changes:
change the constructor definition like so:
Add this line after the other fields in initPersistFields:
And change your definition of onRender to this:
Lastly we add some functions to the console to get and set the image modulation:
And there you go! In game image modulation. I hope you like it, and if you have any changes to submit, or catch any of my silly programmatic errors, please fix them... fixes here benefit everyone else!
Enjoy!
open GuiBitmapCtrl.h: (note, when I use .'s it indicated lines of code, just skip down to the relevant parts, I indicate those lines/sections with comments)
/// Renders a bitmap.
class GuiBitmapCtrl : public GuiControl
{
.
.
.
protected:
.
/// Loaded texture.
GFXTexHandle mTextureObject;
//Phantom139: Added Here
ColorI mImageModulation;
.
.
public:
.
.
void setBitmapHandle(GFXTexHandle handle, bool resize = false);
//Phantom139: Added
void setImageColor(ColorI c);
void deleteImageColor();
ColorI getImageColor();
//Phantom139: end
.
.
};This will add our new information to the class, now let's get it in the engine, open guiBitmapCtrl.cpp and make the following additions/changes:
change the constructor definition like so:
GuiBitmapCtrl::GuiBitmapCtrl(void)
: mBitmapName(),
mStartPoint( 0, 0 ),
mWrap( false ),
mImageModulation(0, 0, 0, 0)
{
}Add this line after the other fields in initPersistFields:
addField( "imageColor", TypeColorI, Offset( mImageModulation, GuiBitmapCtrl),
"Color modulation to apply to the bitmap.");And change your definition of onRender to this:
void GuiBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
{
if (mTextureObject)
{
GFX->getDrawUtil()->clearBitmapModulation();
//Phantom139: Added Code
if(mImageModulation.red == 0 && mImageModulation.green == 0 && mImageModulation.blue == 0 && mImageModulation.alpha == 0)
{
//no modulation set.
}
else
{
GFX->getDrawUtil()->setBitmapModulation(mImageModulation);
}
//Phantom139: End
if(mWrap)
{
// We manually draw each repeat because non power of two textures will
// not tile correctly when rendered with GFX->drawBitmapTile(). The non POT
// bitmap will be padded by the hardware, and we'll see lots of slack
// in the texture. So... lets do what we must: draw each repeat by itself:
GFXTextureObject* texture = mTextureObject;
RectI srcRegion;
RectI dstRegion;
float xdone = ((float)getExtent().x/(float)texture->mBitmapSize.x)+1;
float ydone = ((float)getExtent().y/(float)texture->mBitmapSize.y)+1;
int xshift = mStartPoint.x%texture->mBitmapSize.x;
int yshift = mStartPoint.y%texture->mBitmapSize.y;
for(int y = 0; y < ydone; ++y)
for(int x = 0; x < xdone; ++x)
{
srcRegion.set(0,0,texture->mBitmapSize.x,texture->mBitmapSize.y);
dstRegion.set( ((texture->mBitmapSize.x*x)+offset.x)-xshift,
((texture->mBitmapSize.y*y)+offset.y)-yshift,
texture->mBitmapSize.x,
texture->mBitmapSize.y);
GFX->getDrawUtil()->drawBitmapStretchSR(texture,dstRegion, srcRegion, GFXBitmapFlip_None, GFXTextureFilterLinear);
}
}
else
{
RectI rect(offset, getExtent());
GFX->getDrawUtil()->drawBitmapStretch(mTextureObject, rect, GFXBitmapFlip_None, GFXTextureFilterLinear, false);
}
//Phantom139: Clear Bitmap Modulation...
GFX->getDrawUtil()->clearBitmapModulation();
}
if (mProfile->mBorder || !mTextureObject)
{
RectI rect(offset.x, offset.y, getExtent().x, getExtent().y);
GFX->getDrawUtil()->drawRect(rect, mProfile->mBorderColor);
}
renderChildControls(offset, updateRect);
}Lastly we add some functions to the console to get and set the image modulation:
//Phantom139: Added Some New Stuffs!
void GuiBitmapCtrl::setImageColor(ColorI c) {
mImageModulation.set(c, c.alpha);
setUpdate();
}
void GuiBitmapCtrl::deleteImageColor() {
mImageModulation.set(255, 255, 255, 255);
setUpdate();
}
ColorI GuiBitmapCtrl::getImageColor() {
return mImageModulation;
}
DefineEngineMethod(GuiBitmapCtrl, deleteImageColor, void, (),, "(void) Removes image modulation") {
object->deleteImageColor();
}
DefineEngineMethod(GuiBitmapCtrl, setImageColor, void, (int r, int g, int b, int a),,
"Set the image modulation color for this control, see ImageModulation var.") {
ColorI newCol(r, g, b, a);
object->setImageColor(newCol);
}
DefineEngineMethod(GuiBitmapCtrl, getImageColor, const char *, (),, "(void)") {
ColorI modulation = object->getImageColor();
char output[8]; //8 bits (U8 Type)
std::string final;
//
_itoa(modulation.red, output, 10);
final = output;
strcpy(output, "");
_itoa(modulation.green, output, 10);
final.append(" ");
final.append(output);
strcpy(output, "");
_itoa(modulation.blue, output, 10);
final.append(" ");
final.append(output);
strcpy(output, "");
_itoa(modulation.alpha, output, 10);
final.append(" ");
final.append(output);
strcpy(output, "");
char *str = Con::getReturnBuffer(final.size() +1);
dStrcpy(str, final.c_str());
return str;
}And there you go! In game image modulation. I hope you like it, and if you have any changes to submit, or catch any of my silly programmatic errors, please fix them... fixes here benefit everyone else!
Enjoy!
About the author
Illinois Grad. Retired T3D Developer / Pack Dev.

Torque Owner John E. Nelson
Suspicious Activity