GuiBitmapCtrl Implementation Problems
by David Means · in Torque Game Engine · 02/26/2007 (11:57 am) · 4 replies
I am having some problems with a fade-in GUI I'm putting together.
First, here is the code for it:
One issue, is that whatever the last child-object is you have in the GUI, will dictate the limits and size of the OpenGL rectangle that I'm using for fading (thus making it smaller than the whole screen). Therefore, that leads to my other problem: I pop a fadeGui on top of my main gui I want to fade in, and use the onFadeIn() eventhandler I made to call Canvas.popDialog(fadeGui). This, however, causes Torque to crash outright.
Any thoughts?
First, here is the code for it:
//-----------------------------------------------------------------------------
// Torque Game Engine
//
// Copyright (c) 2001 GarageGames.Com
//-----------------------------------------------------------------------------
#include "console/console.h"
#include "console/consoleTypes.h"
#include "dgl/dgl.h"
#include "game/item.h"
#include "gui/core/guiControl.h"
#include "gui/controls/guiBitmapCtrl.h"
class GuiFadeinBitmapCtrl : public GuiBitmapCtrl
{
typedef GuiBitmapCtrl Parent;
private:
bool mFadeIn;
bool mFadeOut;
U32 wakeTime;
U32 alpha;
U32 elapsed;
public:
U32 fadeinTime;
U32 fadeoutTime;
GuiFadeinBitmapCtrl()
{
wakeTime = 0;
fadeinTime = 1000;
fadeoutTime = 1000;
mFadeIn = false;
mFadeOut = false;
alpha = 0;
elapsed = 0;
}
void onPreRender()
{
Parent::onPreRender();
setUpdate();
}
DECLARE_CONOBJECT(GuiFadeinBitmapCtrl);
bool onWake()
{
if(!Parent::onWake())
return false;
return true;
}
void onRender(Point2I offset, const RectI &updateRect)
{
Parent::onRender(offset, updateRect);
elapsed = Platform::getRealMilliseconds() - wakeTime;
//elapsed time increases up to fadein time
if (elapsed < fadeinTime && mFadeIn == true && mFadeOut != true)
{
//fade-in
alpha = 255 - (255 * (F32(elapsed) / F32(fadeinTime)));
}
//elapsed time increases up to fadeout time
else if (elapsed < fadeoutTime && mFadeOut == true && mFadeIn != true)
{
//fade out
elapsed -= (fadeinTime);
alpha = 255 * F32(elapsed) / F32(fadeoutTime);
}
else
{
//If we were just fading in...
if(mFadeIn == true)
//Event handler called after fade-in
onFadeIn();
//If we were just fading out...
if(mFadeOut == true)
//Event handler called after fade-out
onFadeOut();
//Reset everything
alpha = 0;
mFadeOut = false;
mFadeIn = false;
}
ColorI color(0,0,0,alpha);
//dglDrawRectFill(point, extent, color);
dglDrawRectFill(mBounds.point, mBounds.extent, color);
}
//Sets the mFadeIn boolean for the next render loop
void fadeIn()
{
//Do not attempt both at the same time
if(mFadeOut != true)
{
wakeTime = Platform::getRealMilliseconds();
mFadeIn = true;
}
}
//Sets the mFadeOut boolean for the next render loop
void fadeOut()
{
//Do not attempt both at the same time
if(mFadeIn != true)
{
wakeTime = Platform::getRealMilliseconds();
mFadeOut = true;
}
}
//If we were just fading in...
void onFadeIn()
{
Con::executef(this,1,"onFadeIn");
}
//If we were just fading out...
void onFadeOut()
{
Con::executef(this,1,"onFadeOut");
}
static void initPersistFields()
{
Parent::initPersistFields();
addField("fadeinTime", TypeS32, Offset(fadeinTime, GuiFadeinBitmapCtrl));
addField("fadeoutTime", TypeS32, Offset(fadeoutTime, GuiFadeinBitmapCtrl));
}
};
ConsoleMethod(GuiFadeinBitmapCtrl, fadeIn, void, 2, 2, "Fade GUI in")
{
object->fadeIn();
}
ConsoleMethod(GuiFadeinBitmapCtrl, fadeOut, void, 2, 2, "Fade GUI out")
{
object->fadeOut();
}
IMPLEMENT_CONOBJECT(GuiFadeinBitmapCtrl);One issue, is that whatever the last child-object is you have in the GUI, will dictate the limits and size of the OpenGL rectangle that I'm using for fading (thus making it smaller than the whole screen). Therefore, that leads to my other problem: I pop a fadeGui on top of my main gui I want to fade in, and use the onFadeIn() eventhandler I made to call Canvas.popDialog(fadeGui). This, however, causes Torque to crash outright.
Any thoughts?
About the author
#2
This is a modified version of theirs. Theirs had no event handlers for onFadeIn or onFadeOut, plus I am adding some functionality. And yes, the same problem with the size inheritance issue was in the original one.
Here's the GUI implementation:
02/26/2007 (3:12 pm)
Thanks for replying,This is a modified version of theirs. Theirs had no event handlers for onFadeIn or onFadeOut, plus I am adding some functionality. And yes, the same problem with the size inheritance issue was in the original one.
Here's the GUI implementation:
//--- OBJECT WRITE BEGIN ---
new GuiFadeinBitmapCtrl(fadeGui) {
Profile = "GuiDefaultProfile";
HorizSizing = "relative";
VertSizing = "relative";
position = "0 0";
Extent = "640 480";
MinExtent = "8 2";
Visible = "1";
wrap = "0";
fadeinTime = "1000";
fadeoutTime = "1000";
};
//--- OBJECT WRITE END ---
function fadeGui::onWake(%this)
{
//This crashes Torque after it's finished fading in (see onFadeIn, below)
%this.fadeIn();
}
function fadeGui::onFadeIn()
{
//When this is called, it crashes. However, this needs to be called once it's faded in
//so that I can have access to click buttons on the screen
Canvas.popDialog(fadeGui);
}
function fadeGui::onFadeOut()
{
echo("Faded Out");
}
#3
There are tutorials on fading in that you might want to compare to your approach with:
SplashScreens
DynamicSplashScreen
In your C++ code above, is there a reason why you don't declare local variable alpha in function void onRender(Point2I, const RectI) ?
As to your initial question about the size of the fading rectangle, do you _want_ that rectangle to be smaller than the full screen? Your big plan is not made clear.
That said, I believe that there have been posts on the Forums to the effect that a callback when the screen is fully faded would be desirable, and your C++ efforts seem to be along these lines. So, goodo on you!
02/27/2007 (1:40 pm)
@David wrote:function fadeGui::onFadeIn() { Canvas.popDialog(fadeGui); }This doesn't look good to me somehow. You are calling popDialog() against yourself. Maybe use fadeGui.schedule(), which will execute after the engine returns from the class code? Just guessing, really.There are tutorials on fading in that you might want to compare to your approach with:
SplashScreens
DynamicSplashScreen
In your C++ code above, is there a reason why you don't declare local variable alpha in function void onRender(Point2I, const RectI) ?
As to your initial question about the size of the fading rectangle, do you _want_ that rectangle to be smaller than the full screen? Your big plan is not made clear.
That said, I believe that there have been posts on the Forums to the effect that a callback when the screen is fully faded would be desirable, and your C++ efforts seem to be along these lines. So, goodo on you!
#4
Yeah, the code TGE uses default for fading GUIs didn't seem right to me. It was pretty rigid, and would automatically fade out over a set time -- so I made methods you could call to force it to fade in or out.
D'oh! I think that scheduling the event is what would be best. I realize I am more than likely just cutting the execution short with having it pop itself off the GUI stack and causing an exception. But I must ask, if the GUI isn't being deleted, it is merely being hidden... and I can call a GUI to pop itself off with other event handlers (such as onWake -- I use that all the time with buggy screens), how come I can't use it with this handler?
e.g. this works (I use it a lot for buggy screens):
Oh, and 'alpha' is declared in the private section at the beginning of the class.
No, I do not wish the fade-in effect to be smaller than the screen, but that's what the effect is if you have child GUI objects in the fading GUI.
Unfortunately, there is something screwy with the onRender method, and whatever the last defined child GUI object is, dictates the size of the fading screen (the fade will only happen over this button). That is the reason why I push a fading gui on top my gui with buttons etc., then remove the fading gui after it fades in.
Thank you for your help!
02/27/2007 (6:30 pm)
Thank you for your reply,Yeah, the code TGE uses default for fading GUIs didn't seem right to me. It was pretty rigid, and would automatically fade out over a set time -- so I made methods you could call to force it to fade in or out.
D'oh! I think that scheduling the event is what would be best. I realize I am more than likely just cutting the execution short with having it pop itself off the GUI stack and causing an exception. But I must ask, if the GUI isn't being deleted, it is merely being hidden... and I can call a GUI to pop itself off with other event handlers (such as onWake -- I use that all the time with buggy screens), how come I can't use it with this handler?
e.g. this works (I use it a lot for buggy screens):
function myGui::onWake(%this)
{
Canvas.popDialog(myGui);
}Oh, and 'alpha' is declared in the private section at the beginning of the class.
No, I do not wish the fade-in effect to be smaller than the screen, but that's what the effect is if you have child GUI objects in the fading GUI.
//--- OBJECT WRITE BEGIN ---
new GuiFadeinBitmapCtrl(fadeGui) {
Profile = "GuiDefaultProfile";
HorizSizing = "relative";
VertSizing = "relative";
position = "0 0";
Extent = "640 480";
MinExtent = "8 2";
Visible = "1";
wrap = "0";
fadeinTime = "1000";
fadeoutTime = "1000";
new GuiBitmapButtonCtrl(myButton)
{
Profile = "GuiButtonProfile";
HorizSizing = "relative";
VertSizing = "relative";
position = "488 363";
Extent = "128 32";
MinExtent = "8 2";
Visible = "1";
Command = "aFunction();";
text = "Button";
groupNum = "-1";
buttonType = "PushButton";
bitmap = "~/client/ui/buttons/AcceptButton";
};
};
//--- OBJECT WRITE END ---
function fadeGUI::onWake(%this)
{
%this.fadeIn();
}Unfortunately, there is something screwy with the onRender method, and whatever the last defined child GUI object is, dictates the size of the fading screen (the fade will only happen over this button). That is the reason why I push a fading gui on top my gui with buttons etc., then remove the fading gui after it fades in.
Thank you for your help!
Employee Michael Perry
ZombieShortbus
*EDIT* Or are you asking how to use it in the scripts? How to implement their's?