| DemoGL::Using::Creating an effectclass |
The developer doesn't have to implement all methods of CEffect. The methods that should be implemented however are Init() and one of the two render methods: RenderFrame or RenderFrameEx() (see DEMOGL_SetVariable for the variable DGL_VF_USERENDERFRAMEEX) Init(), because DemoGL calls the Init method of every registered effectobject (the instance of an effectclass, registered with DemoGL) during startup, and one of the render methods because otherwise the effectobject is never executed during application execution.
Below we create a simple effect class that will fade in a splashscreen in orthogonal projection. First the header file is created, since a good habit in C++ programming is to place the class definitions in headerfiles and the class implementation in a .cpp file. The class created below is called CSplash.
The header file, csplash.h, contains the following code:
// CSplash.h header file, belongs to CSplash.cpp
///////////////////////////////////////////////////////////
#ifndef _CSPLASH_H
#define _CSPLASH_H
// Include the DemoGL CEffect class header file
#include "DemoGL_Effect.h"
// Class definition
class CSplash:public CEffect
{
// public method declarations. Only 4 methods are
// implemented
public:
CSplash();
virtual ~CSplash();
int Init(int iWidth, int iHeight);
void RenderFrame(long lElapsedTime);
void Prepare(void);
void End(void);
// private methods
private:
void DrawLogo(long lNow);
// Private members
private:
int m_iWidth;
int m_iHeight;
GLuint m_iTexture;
long m_lTimeStart;
};
#endif
The class CSplash now has to be implemented. The code below is the implementation of the CSplash class and stored in the csplash.cpp file. It uses a texture, logo.jpg, which is loaded using DemoGL's texture load routines and is located in the subdir 'demotex'.
// CSplash class implementation
////////////////////////////////////////////////
#include <0windows.h>
#include <GL/gl.h>
#include "DemoGL_DLL.h"
#include "CSplash.h"
//Purpose: Constructor
CSplash::CSplash()
{
}
// Purpose: destructor
CSplash::~CSplash()
{
}
// Purpose: implementation of init()
int
CSplash::Init(int iWidth, int iHeight)
{
m_iWidth=iWidth;
m_iHeight=iHeight;
m_lTimeStart = -1;
// load the logotexture
m_iTexture = DEMOGL_TextureLoad("demotex\\logo.jpg", DGL_FTYPE_JPGFILE, 0,
GL_REPEAT, GL_REPEAT, GL_LINEAR, GL_LINEAR, false, false, 0,
GL_RGB5_A1, DGL_TEXTUREDIMENSION_2D);
if(m_iTexture > 0)
{
// all fine
return SYS_OK;
}
else
{
// some error occured. signal we failed.
return SYS_NOK;
}
}
// Purpose: implementation of the prepare()
void
CSplash::Prepare()
{
// upload the texture
DEMOGL_TextureUpload(m_iTexture);
}
// Purpose: implementation of the end()
void
CSplash::End()
{
// unupload the logotexture
DEMOGL_TextxureUnUpload(m_iTexture);
}
// Purpose: draws the actual splashscreen.
void
CSplash::DrawLogo(long lNow)
{
float fPassedSeconds;
fPassedSeconds = ((float)(lNow - m_lTimeStart))/1000.f;
// we will fade up in 10 seconds. So we will go from 0 to 1.0 in 10 seconds.
// start drawing a quad.
glColor4f(1.0f,1.0f,1.0f, fPassedSeconds/10.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex3f(0.2f,0.125f,-0.45f);
glTexCoord2f(1.0f,0.0f);glVertex3f(0.8f,0.125f,-0.45f);
glTexCoord2f(1.0f,1.0f);glVertex3f(0.8f,0.875f,-0.45f);
glTexCoord2f(0.0f,1.0f);glVertex3f(0.2f,0.875f,-0.45f);
glEnd();
// draw white background
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glVertex3f(0.0f,0.0f,-0.5f);
glVertex3f(1.0f,0.0f,-0.5f);
glVertex3f(1.0f,1.0f,-0.5f);
glVertex3f(0.0f,1.0f,-0.5f);
glEnd();
}
// Purpose: implementation of the RenderFrame()
void
CSplash::RenderFrame(long lElapsedTime)
{
if(m_lTimeStart <0)
{
// first time
m_lTimeStart=lElapsedTime;
}
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT);
// enable blending so an almost transparent set of polies will
// be almost invisible so we can fade up nicely
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
// insert a scissortest to get black bars as a 'movie on TV' effect.
glScissor(0, (m_iHeight (int)((m_iWidth * 9)/20)) / 2,
m_iWidth, (int)((m_iWidth * 9)/20));
glEnable(GL_SCISSOR_TEST);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_TEXTURE_2D);
// bind to the logo texture
glBindTexture(GL_TEXTURE_2D, m_iTexture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// set up orthogonal view.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f,1.0f,0,1.0f,-1.0f,1.0f);
// set matrixmode in Modelview.
glMatrixMode(GL_MODELVIEW);
// load the identity matrix into the modelview matrix.
glLoadIdentity();
// position the camera.
glTranslatef(0.0f,0.0f,-0.1f);
// draw the logo
DrawLogo(lElapsedTime);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
Now that this class is created, an instance can be created from it and registered with DemoGL. Then the object (instance) of this class can be scheduled using a script. All that's done in this class is implement the actual effect. Which is exactly what we wanted: program effects.
Last changed on 02-jun-2001
©1999-2001 Solutions Design