
/**

\page tutorial 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 
<b>"YourClassName"</b> class name to SimpleEffect everywhere in both files.

<b>Attention:</b> 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:  \n
<b>EffectTimer</b> is a <b>Qtimer</b> object, which will animate the effect.\n
<b>rotationAngle</b> and <b>angleDelta</b> are used by <b>glRotated()</b> to rotate 
the square.  

There is also a private <b>slot</b>, <b>animate</b>, 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 <b>effectName</b> we set the name of this effect. In <b>shortDescription</b> we 
provide a short one-sentence description of what my effect is about. The 
<b>needNewTextures</b> 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.\n
<b>RequiredImageLists</b> provides the number of image sets we want to load, in this 
case we only want one set of images. <b> fileDialogNames[0] </b> 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 <b>gluPerspective()</b> 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 
<b>rotationAngle</b> 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. <b>play()</b> simply starts the timer with a 50 ms interval, 
<b>pause()</b> stops the timer but leaves everything else as is, <b>stop()</b> stops the 
timer and also goes back to the very first frame in the animation sequence (if there was 
one), and <b>reset()</b> has the same effect as <b>stop()</b>, 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);\n
CHECK_PTR(effectPool[0]);
		
effectPool[1] = new SampleEffect2(this);\n
CHECK_PTR(effectPool[1]);

<b>effectPool[2] = new SimpleEffect(this); </b>\n
<b>CHECK_PTR(effectPool[2]);</b>
	
// add effects to the selector box \n
effectSelector->insertItem("Sample 1 - Parametric Polygons");\n
effectSelector->insertItem("Sample 2");\n
<b>effectSelector->insertItem("Simple Effect");</b>\n

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 <b>cat.png</b> 
could be used as a simple texture.). 

<H2>Have fun!<H2>

**/




