Game Development Community

dev|Pro Game Development Curriculum

Fading transparent bitmap control

by Jeff "Ddraig Goch" Parry · 02/20/2005 (10:41 pm) · 18 comments

Download Code File

OK, this is really a very simple control and all the gurus will probably say "duh"; but I figured I'd publish it anyway for all of the rest of us, ha.

I needed a control that did not fade in and out from black. I wanted the actual bitmap to fade in/out to/from transparent. I just horked the code from guiFadeinBitmapCtrl, changed it a bit and made one little change to the parent control, guiBitmapCtrl, and voila a transparent fading bitmap.

Here is a little movie comparing guiXFadeBitmapCtrl and guiFadeinBitmapCtrl. Movie

IMPORTANT NOTE: This control cannot be the first layer, in other words there must be something behind this control for it to work. Unlike the guiFadeinBitmapCtrl which has a bitmap and a fading black rectangle, this control just has the fading bitmap. When the guiFadeinBitmapCtrl is faded out you see the bitmap. When the guiXFadeBitmapCtrl fades out there is nothing.

Just in case the link to the code above doesn't work, here is the code.

Anyway here is the code and an example.

First we need to move the the bitmap modulation clear in guiBitmapCtrl so it doesn't reset our fading before we get a chance to draw it.

In engine\gui\guiBitmapCtrl.cc around line 113, comment out or remove this line:

dglClearBitmapModulation();

then around line 147 add it back in after:

if (mProfile->mBorder || !mTextureHandle)
   {
      RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
      dglDrawRect(rect, mProfile->mBorderColor);
   }

      [b]dglClearBitmapModulation();[/b]

Next create a new file called guiXFadeBitmapCtrl.cc with the following code:

//-----------------------------------------------------------------------------
// Torque Game Engine
// 
// GuiXFadeBitmapCtrl - Fades bitmap in or out from transparent.
// 						Hope you like this simple little control.
//
//						Jeff (Ddraig Goch) Parry
//-----------------------------------------------------------------------------

#include "console/console.h"
#include "console/consoleTypes.h"
#include "dgl/dgl.h"

#include "gui/guiBitmapCtrl.h"

class GuiXFadeBitmapCtrl : public GuiBitmapCtrl
{
   typedef GuiBitmapCtrl Parent;
public:
   U32 wakeTime;
   bool done;
   U32 fadeinTime;
   U32 waitTime;
   U32 fadeoutTime;

   GuiXFadeBitmapCtrl()
   {
      wakeTime    = 0;
      fadeinTime  = 1000;
      waitTime    = 2000;
      fadeoutTime = 1000;
      done        = false;
   }
   void onPreRender()
   {
      Parent::onPreRender();
      setUpdate();
   }
   void onMouseDown(const GuiEvent &)
   {
      Con::executef(this, 1, "click");
   }
   bool onKeyDown(const GuiEvent &)
   {
      Con::executef(this, 1, "click");
      return true;
   }
   DECLARE_CONOBJECT(GuiXFadeBitmapCtrl);
   bool onWake()
   {
      if(!Parent::onWake())
         return false;
      wakeTime = Platform::getRealMilliseconds();
      return true;
   }
   void onRender(Point2I offset, const RectI &updateRect)
   {
		  
	  U32 elapsed = Platform::getRealMilliseconds() - wakeTime;

      U32 alpha;
	  	  
      if (elapsed < fadeinTime)
      {
         // fade-in
         alpha = 255 - (255 * (F32(elapsed) / F32(fadeinTime)));
      }
      else if (elapsed < (fadeinTime+waitTime))
      {
         // wait
         alpha = 0;
      }
      else if (elapsed < (fadeinTime+waitTime+fadeoutTime))
      {
         // fade out
         elapsed -= (fadeinTime+waitTime);
         alpha = 255 * F32(elapsed) / F32(fadeoutTime);
      }
      else
      {
         // done state
         alpha = fadeoutTime ? 255 : 0;
         done = true;
      }
     ColorI color(255,255,255,255-alpha);
      
     dglSetBitmapModulation(color);
     Parent::onRender(offset, updateRect);
   }
   static void initPersistFields()
   {
      Parent::initPersistFields();
      addField("fadeinTime", TypeS32, Offset(fadeinTime, GuiXFadeBitmapCtrl));
      addField("waitTime", TypeS32, Offset(waitTime, GuiXFadeBitmapCtrl));
      addField("fadeoutTime", TypeS32, Offset(fadeoutTime, GuiXFadeBitmapCtrl));
      addField("done", TypeBool, Offset(done, GuiXFadeBitmapCtrl));
   }
};

IMPLEMENT_CONOBJECT(GuiXFadeBitmapCtrl);

add it to your project in engine\gui, recompile and there you have it.

It works just like guiFadeinBitmapCtrl; you can set fadeinTime, waitTime and fadeoutTime, etc.

Just use it in your scripts like this:

new GuiXFadeBitmapCtrl(fadingLogo) {
      profile = "GuiDefaultProfile";
      horizSizing = "right";
      vertSizing = "bottom";
      position = "145 156";
      extent = "129 82";
      minExtent = "8 2";
      visible = "1";
      bitmap = "./logo";
      wrap = "0";
      fadeinTime = "5000";
      waitTime = "2000";
      fadeoutTime = "5000";
      done = "0";
   };

About the author

Recent Blogs

• Animated cursor

#1
02/21/2005 (10:44 am)
Thank you - it works very nicely!
#2
10/25/2005 (6:35 pm)
Yeah, thanks for posting this.
#3
01/06/2006 (9:44 am)
This is exactly what I was looking for. Thanks!!
#4
03/06/2006 (11:52 pm)
Nice if you could update it to work with the 1.4 release. Thanks.
#5
05/07/2006 (5:15 pm)
Yes, it would be very helpful if this worked with TGE 1.4. As of now it doesn't fade at all, just acts like a normal bitmap.
#6
05/18/2006 (6:17 pm)
This works fine with 1.4 all you have to do is change #include "gui/guiBitmapCtrl.h" to #include "gui/controls/guiBitmapCtrl.h" at the top of guiXFadeBitmapCtrl.cc
#8
06/19/2006 (2:58 pm)
Don't mind me, I'm an absolute moron. Forgot to move the clearBitmapModulation call.
#9
08/28/2006 (11:43 am)
Pretty cool resource.

Unfortunately
dglClearBitmapModulation();
Is where it is for a reason. Moving it will cause you problems with bitmaps located behind GUI controls. I.e. they won't appear.
#10
11/03/2006 (11:57 am)
Tim is quite right. Moving this line does break a few things, like the guiBitmapButtonCtrl for example. However, there are several ways to fix this. I chose the following route. All changes are in bold.

In guiBitmapCtrl.h change the public block as follows:
public:
   //creation methods
   DECLARE_CONOBJECT(GuiBitmapCtrl);
   GuiBitmapCtrl();
   static void initPersistFields();
[b]   // Begin - Change for guiXFadeBitmapCtrl
   bool mBitmapFade;
   // End - Change for guiXFadeBitmapCtrl[/b]

In guiBitmapCtrl.cc make the following changes to the constructor:
GuiBitmapCtrl::GuiBitmapCtrl(void)
{
   mBitmapName = StringTable-]insert("");
	startPoint.set(0, 0);
	mWrap = false;
[b]	// Begin - Change for guiXFadeBitmapCtrl
	mBitmapFade = false;
	// End - Change for guiXFadeBitmapCtrl[/b]
}
and then in the OnRender function, instead of commenting out the call to dglClearBitmapModulation(); replace it with:
if (mTextureHandle)
   {
[b]		// Begin - Change for guiXFadeBitmapCtrl
		if (!mBitmapFade)
		{
			dglClearBitmapModulation();
		}
		// End - Change for guiXFadeBitmapCtrl[/b]
and at the bottom of the function make this change:
[b]   // Begin - Change for guiXFadeBitmapCtrl
   if (mBitmapFade)
   {
	   dglClearBitmapModulation();
   }
   // End - Change for guiXFadeBitmapCtrl[/b]

   renderChildControls(offset, updateRect);
}
then finally change the constructor in guiXFadeBitmapCtrl.cc as follows:
GuiXFadeBitmapCtrl()
   {
      wakeTime    = 0;
      fadeinTime  = 1000;
      waitTime    = 2000;
      fadeoutTime = 1000;
      done        = false;
[b]	  // Begin - Change for guiXFadeBitmapCtrl
	  mBitmapFade = true;
	  // End - Change for guiXFadeBitmapCtrl[/b]
   }

This enables both this control to work as well as any other controls that rely on this object. It's currently coexisting nicely with my bitmapped buttons in TGE 1.5 without any problems.
Hope this helps.
#11
05/10/2007 (8:43 am)
When you say, "This control cannot be the first layer, in other words there must be something behind this control for it to work." Does this mean an image has to be behind it? I'm trying to get my weapon hud to fade in and out everytime a player switches weapons. Does any know if this is possible? Any help would be greatly appreciated.
Thx.
#12
11/15/2007 (4:53 pm)
With GuiFadeInBimapCtrl, any children of the bitmap get faded in as well (which can be used to fade in text and whatnot)

With GuiXFadeBitmapCtrl, this is no longer the case, can anyone figure out a quick way to let the old behavior pass through while retaining the fade from/to transparent functionality?

Thanks
#13
02/26/2008 (7:37 pm)
Does it works with TGE 1.5.2 ? cause I'm trying to build the engine and got several errors, not just warnings. I made the update from Stephen too, and I still got trouble.
#14
02/26/2008 (7:39 pm)
This is what I get when building the Torque Demo
7>Generating Code...
7>Compiling resources...
7>Linking...
7>guiXFadeBitmapCtrl.obj : error LNK2001: unresolved external symbol "public: static class AbstractClassRep * __cdecl GuiBitmapCtrl::getStaticClassRep(void)" (?getStaticClassRep@GuiBitmapCtrl@@SAPAVAbstractClassRep@@XZ)
7>missionAreaEditor.obj : error LNK2019: unresolved external symbol "public: static class AbstractClassRep * __cdecl GuiBitmapCtrl::getStaticClassRep(void)" (?getStaticClassRep@GuiBitmapCtrl@@SAPAVAbstractClassRep@@XZ) referenced in function "public: static class AbstractClassRep * __cdecl MissionAreaEditor::getParentStaticClassRep(void)" (?getParentStaticClassRep@MissionAreaEditor@@SAPAVAbstractClassRep@@XZ)
7>guiCrossHairHud.obj : error LNK2001: unresolved external symbol "public: static class AbstractClassRep * __cdecl GuiBitmapCtrl::getStaticClassRep(void)" (?getStaticClassRep@GuiBitmapCtrl@@SAPAVAbstractClassRep@@XZ)
7>guiSpeedometer.obj : error LNK2001: unresolved external symbol "public: static class AbstractClassRep * __cdecl GuiBitmapCtrl::getStaticClassRep(void)" (?getStaticClassRep@GuiBitmapCtrl@@SAPAVAbstractClassRep@@XZ)
7>guiFadeinBitmapCtrl.obj : error LNK2001: unresolved external symbol "public: static class AbstractClassRep * __cdecl GuiBitmapCtrl::getStaticClassRep(void)" (?getStaticClassRep@GuiBitmapCtrl@@SAPAVAbstractClassRep@@XZ)
7>guiBitmapCtrl.obj : error LNK2001: unresolved external symbol "public: virtual class AbstractClassRep * __thiscall GuiBitmapCtrl::getClassRep(void)const " (?getClassRep@GuiBitmapCtrl@@UBEPAVAbstractClassRep@@XZ)
7>../example/torqueDemo.exe : fatal error LNK1120: 2 unresolved externals
7>Build log was saved at "file://d:\Program Files\Torque\TGE_1_5_2\engine\out.VC8.RELEASE\BuildLog.htm"
7>Torque Demo - 7 error(s), 0 warning(s)
========== Rebuild All: 6 succeeded, 1 failed, 0 skipped ==========
#15
02/27/2008 (6:07 am)
Martin, try a Rebuild and see if that clears up the linker problems
#16
09/30/2008 (11:48 pm)
yeah i got those errors too. some things have changed with guiBitmapCtrl.cc since this resource was posted. you're gonna have to manually make the edits to your guiBitmapCtrl.cc. simply replacing it with the file in Jeffs zip will not work.

I got a question: just how the heck does one tell this little control to activate? i've only seen it fade-in/out the moment the gui is pushed. i need it to fade in/out periodically while in game....anyone?
-mike
#17
10/31/2008 (12:37 am)
It also works in TGEA 1.7.1 with minor changes.
#18
05/25/2009 (7:20 pm)
HI SpaceIllusion,

you mention that it worked with TGEA 1.7.1 with minor changes. thats gr8. I am trying it on TGEA 1.8.1. But I am getting some problems like Here mentioned guiBitmapCtrl.cc and in our code there is no .cc files onle .cpp file are there. second if I assume guiBitmapCtrl.cpp file like guiBitmapCtrl.cc and searched for dglClearBitmapModulation() but couldn't find this function. So if any solution for TGE 1.8.1 you have please help me to solve it for me. It will be really great help.



Thanking you all.