Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

A Simple Effect Tutorial

We are going to create a very simple effect that animates a textured rectangle by rotating it in different directions. This effect will not use any complicated things like event handlers, 3d mouse coordinates etc., but is nevertheless a good starting point in learning how to create your effect classes.

First, take a look at EffectTemplate.h and EffectTemplate.cpp and take your time to study them. Do the same with GLEffect base class. Read the corresponding documentation for detailed explanations on how things work if you want, but don't worry too much about details of implementation for now. We'll take it easy.

I've already made copies of EffectTemplate.h and EffectTemplate.cpp and renamed them to SimpleEffect.h and SimpleEffect.cpp, respectively. Then I changed the "YourClassName" class name to SimpleEffect everywhere in both files.

Attention: The implementation of this class is already complete and is included into the project, so you don't need to write anything - just read the tutorial and look into the source code from time to time.

For our effect we will need several member variables, which reside in the private section of the class:
EffectTimer is a Qtimer object, which will animate the effect.
rotationAngle and angleDelta are used by glRotated() to rotate the square.

There is also a private slot, animate, which will be our animation routine controlled by the effect timer.

The first thing we need to do is initialize the effect information structure with necessary parameters. Here's how this is done: SimpleEffect::SimpleEffect()

Look at the documentation of GLEffect::effectInformation for details on individual parameters. In short, this is what we do :

In effectName we set the name of this effect. In shortDescription we provide a short one-sentence description of what my effect is about. The needNewTextures parameter tells the framework that our effect really requires a new set of images to be loaded, i.e. it doesn't want to use the images that have been loaded by the previous effect.
RequiredImageLists provides the number of image sets we want to load, in this case we only want one set of images. fileDialogNames[0] will provide a descriptive name for our file loading dialog. The effect version is 1.0. The author is our fictional programmer named Fred.

Then we call SimpleEffect::createControlPanel() with 'false' as parameter, which will put our control panel into the right side of main window. Finally, we call hideControls(), which is necessary to properly hide the effect until it is selected.

That's it for the constructor, it's pretty simple in this case because we don't need anything else.

Now we continue on to the implementation of SimpleEffect::initialize() : Here we set initial perspective projection parameters (see OpenGL documentation, namely sections describing the use of gluPerspective() for explanations on what parameters specify the projection). Here the initial distance from the world origin to the viewpoint is 3 units, which is quiet acceptable in this simple case, the FOV angle is 60 degrees, near clipping plane is at 1 units and far clipping plane at 30 units. The rotationAngle is set to 0.0. We then also set the necessary texturing parameters and bind our texture object as a 2-D texture.

In SimpleEffect::createControls() we instantiate our effectTimer object and connect it to the animation routine SimpleEffect::animate(). The animation itself is very simple: it continuously rotates the square around (1,1,1) axis by incrementing the rotationAngle value and changes rotation to the opposite direction with each full 360 degree turn. If an image sequence has been loaded, this will also go to the next frame in the sequence with each step.

The SimpleEffect::play(), SimpleEffect::stop(), SimpleEffect::reset(), and SimpleEffect::pause() control the animation. Look into their implementations, they are really very simple. play() simply starts the timer with a 50 ms interval, pause() stops the timer but leaves everything else as is, stop() stops the timer and also goes back to the very first frame in the animation sequence (if there was one), and reset() has the same effect as stop(), only it additionally resets the rotation angle back to 0.0.

Those are the basic sections that constitute our simple effect. Other effect classes follow a similar pattern. You will need to read the program documentation for detailed information about various functions.

The effect is then instantiated within GLFramework constructor. Here's where and how it is done:

effectPool= new GLEffect* [20]; // max 20 effects for now

effectPool[0] = new SampleEffect(this);
CHECK_PTR(effectPool[0]);

effectPool[1] = new SampleEffect2(this);
CHECK_PTR(effectPool[1]);

effectPool[2] = new SimpleEffect(this);
CHECK_PTR(effectPool[2]);

add effects to the selector box
effectSelector->insertItem("Sample 1 - Parametric Polygons");
effectSelector->insertItem("Sample 2");
effectSelector->insertItem("Simple Effect");

The bold lines indicate where our effect has been added. You can add your other effect classes in the same manner when you've written them.

That's it - the effect is done ! Compile the program and select "Simple Effect" in the effect selector box to see it. Don't forget to load some images (a sample image cat.png could be used as a simple texture.).

Have fun!


Generated at Fri Apr 19 16:53:07 2002 for GLFramework by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001