(C++) Scene Node Fade Animator (Transparency)
Posted: Fri Dec 29, 2006 4:41 pm
I couldn't find good answer on how to effeciently fade a scene node, so I came up with one using the existing scene node animator examples. Many suggested using lock()/unlock() on the node's texture to edit the pixels and change the alpha value, which works, but I was warned that it is costly in terms of resources. So basically what I did is select the texture I want to be able to fade, load multiple versions of it into memory using createImageFromData(), save them in a vector, pass it as a reference to the animator, and now the animator can iterate through the textures over a designated period of time causing a "fade" effect.
Here's the CFadeAnimator class:
CFadeAnimator.h
and CFadeAnimator.cpp:
Here is also some example code on how to generate the vector of ITexture ponters necessary to fade your texture. This should be done during the initialization of your program:
And there you go. I'm well aware that there are probably much better ways to do pretty much everything involved here, but I'm still learning Irrlicht so this is what I came up with. This works well in my current project, but thats as far as I can warrant its quality for now. I intend to add "begin" and "end" fade values to the constructor to do partial fades in the near future. If there's any interest, I'll post it up here.
Hope this helps!
Here's the CFadeAnimator class:
CFadeAnimator.h
Code: Select all
#ifndef _CFadeAnimator_h__
#define _CFadeAnimator_h__
#define CFA_FADEIN 1
#define CFA_FADEOUT 2
#include "ISceneNode.h"
#include <vector>
namespace irr {
namespace scene {
class CFadeAnimator : public ISceneNodeAnimator {
public:
//! constructor
CFadeAnimator(int mode, u32 timeForWay, u32 now, std::vector<video::ITexture*> *textures);
//! destructor
virtual ~CFadeAnimator();
//! animates a scene node
virtual void animateNode(ISceneNode* node, u32 timeMs);
private:
int FadeMode;
f32 TimeFactor;
u32 StartTime;
u32 TimeForWay;
int Start, End;
std::vector<video::ITexture*> *Textures;
};
}}
#endif
Code: Select all
#include "CFadeAnimator.h"
namespace irr {
namespace scene {
CFadeAnimator::CFadeAnimator(int mode, u32 timeForWay, u32 now,
std::vector<video::ITexture*> *textures) : StartTime(now), TimeForWay(timeForWay),
Textures(textures), FadeMode(mode) {
#ifdef _DEBUG
setDebugName("CFadeAnimator");
#endif
int max = 0;
if (!textures) {
Start = 0;
End = 0;
TimeFactor = 0;
return;
} else {
if (textures->size() <= 0) {
Start = 0;
End = 0;
TimeFactor = 0;
return;
}
}
max = textures->size() - 1;
if (FadeMode == CFA_FADEIN) {
Start = 0;
End = max;
} else if (FadeMode == CFA_FADEOUT) {
Start = max;
End = 0;
} else {
Start = 0;
End = 0;
TimeFactor = 0;
return;
}
TimeFactor = (f32)max / TimeForWay;
}
CFadeAnimator::~CFadeAnimator() {
}
void CFadeAnimator::animateNode(ISceneNode* node, u32 timeMs) {
if (!node) {
return;
}
u32 t = timeMs - StartTime;
int index = Start;
if (t >= TimeForWay) {
index = End;
} else {
if (FadeMode == CFA_FADEIN) {
index = (int)((f32)fmod(t, TimeForWay) * TimeFactor);
} else if (FadeMode == CFA_FADEOUT) {
index = Start - (int)((f32)fmod(t, TimeForWay) * TimeFactor);
}
}
node->setMaterialTexture(0, Textures->at(index));
}
}}
Code: Select all
// Necessary Includes //
#include <vector>
#include <sstream> // cause I'm lazy
// The vector to hold your fade textures //
std::vector<irr::video::ITexture*> FadeTextures;
// Get your texture and some necessary attributes
irr::video::ITexture *source = Driver->getTexture("/path/to/texture");
core::dimension2d<s32> dim = source->getSize();
video::ECOLOR_FORMAT format = source->getColorFormat();
s32 pitch = source->getPitch();
for (int i = 0; i <= 255; i=i+5) {
// Change alpha channel based on "i" //
unsigned char *pixels = (unsigned char*)source->lock();
for (int x = 0; x < dim.Width; x++) {
for (int y = 0; y < dim.Height; y++) {
s32 offset = (y*pitch)+(x*4);
(pixels+offset)[3] = i;
}
}
source->unlock();
// Create a new image and load it as a texture //
irr::video::IImage* image = Driver->createImageFromData(format, dim, pixels, false);
std::stringstream tname;
tname << "texturename-" << i;
irr::video::ITexture *texture = Driver->addTexture(tname.str().c_str(), image);
FadeTextures.push_back(texture);
}
Hope this helps!