S60 3rd Edition SDK for Symbian OS
Example Applications Guide

CMultiTex Class Reference

#include <MultiTex.h>

List of all members.

Public Types

enum  { ELoadingTextures, ERunning }

Public Member Functions

virtual ~CMultiTex ()
void AppInitL (TAny *aInstance)
void AppExit (void)
void AppCyclePbuffer (TInt aFrame)
void AppCycleWindow (TInt aFrame)
void OnEnterStateL (TInt aState)
void OnStartLoadingTexturesL ()
void OnEndLoadingTexturesL ()
void CalculateLightsL (void)
void DrawLights (TInt iFrame)
void SetScreenSize (TUint aWidth, TUint aHeight)

Static Public Member Functions

static CMultiTex * NewL (TUint aWidth, TUint aHeight)

Protected Member Functions

 CMultiTex (TUint aWidth, TUint aHeight)
void ConstructL (void)

Private Attributes

CTextureManager * iTextureManager
TUint iScreenWidth
TUint iScreenHeight
GLfloat iAspectRatio
TTexture iWorldTexture
TUint8 * iLightTex
GLuint iLightTexObjects [2]
GLint iCameraDistance


Detailed Description

Class that does the actual OpenGL ES rendering. Subclass of CFiniteStateMachine because the application needs to handle loading textures and running states.

Definition at line 40 of file MultiTex.h.


Member Enumeration Documentation

anonymous enum
 

Application states: ELoadingTextures - indicates that the app. is loading textures. ERunning - indicates that the app. is running.

Definition at line 143 of file MultiTex.h.

00144                 {
00145                 ELoadingTextures, 
00146                 ERunning
00147                 };


Constructor & Destructor Documentation

CMultiTex::~CMultiTex (   )  [virtual]
 

Destructor. Does nothing.

Definition at line 143 of file MultiTex.cpp.

00144 {
00145 }

CMultiTex::CMultiTex (  TUint  aWidth,
TUint  aHeight
)  [protected]
 

Standard constructor that must never Leave. Stores the given screen width and height.

Parameters:
aWidth Width of the screen.
aHeight Height of the screen.

Definition at line 120 of file MultiTex.cpp.

References iAspectRatio, iCameraDistance, iScreenHeight, and iScreenWidth.

00120                                                   : 
00121     CFiniteStateMachine(),
00122     iScreenWidth( aWidth ),
00123     iScreenHeight( aHeight )
00124 {
00125     if ( iScreenHeight != 0 )
00126     {
00127         iAspectRatio = (GLfloat)iScreenWidth / (GLfloat)iScreenHeight;
00128     }
00129     else
00130     {
00131         iAspectRatio = 1.0;
00132     }
00133     iCameraDistance = 200;
00134 }


Member Function Documentation

CMultiTex * CMultiTex::NewL (  TUint  aWidth,
TUint  aHeight
)  [static]
 

Factory method for creating a new CMultiTex object.

Definition at line 101 of file MultiTex.cpp.

References CMultiTex().

00102 {
00103     /* Symbian 2-phase constructor. Calls both the default 
00104        C++ constructor and Symbian ConstructL methods */
00105     CMultiTex* self = new (ELeave) CMultiTex( aWidth, aHeight );
00106     CleanupStack::PushL( self );
00107     self->ConstructL();
00108     CleanupStack::Pop();
00109     
00110     return self;
00111 }

void CMultiTex::AppInitL (  TAny *  aInstance  ) 
 

Initializes OpenGL ES, sets the vertex and color arrays and pointers. Also selects the shading mode and creates the CTextureManager instance and starts loading of required textures.

Definition at line 227 of file MultiTex.cpp.

References CalculateLightsL(), iAspectRatio, CMultiTexContainer::iEglContext, CMultiTexContainer::iEglDisplay, CMultiTexContainer::iEglPbufferContext, CMultiTexContainer::iEglPbufferSurface, CMultiTexContainer::iEglSurface, iLightTex, iLightTexObjects, iScreenHeight, iScreenWidth, iTextureManager, and iWorldTexture.

00228 {
00229     
00230     CMultiTexContainer* instance = (CMultiTexContainer*) aInstance;
00231 
00232     /*=========================================================================*/
00233     /*===================== Initialize Pbuffer context ========================*/
00234     /*=========================================================================*/
00235 
00236     /* Bind the pbuffer context to the current rendering thread and surface.*/
00237     eglMakeCurrent( instance->iEglDisplay, instance->iEglPbufferSurface, 
00238                     instance->iEglPbufferSurface, instance->iEglPbufferContext );
00239     
00240     /* Create light texture map */
00241     CalculateLightsL();
00242     const GLvoid *texPtr = iLightTex;
00243     
00244     // Set the screen background color (black). 
00245     glClearColor( 0.f, 0.f, 0.f, 1.f );
00246     
00247     // Initialize viewport and projection. 
00248     glViewport( 0, 0, 128, 128 );
00249     glMatrixMode( GL_PROJECTION );
00250     glFrustumf( -1.f, 1.f, -1.f, 1.f, 3.f, 1000.f );
00251 
00252     /* Initialize appropriate texture matrix. First we have to translate the
00253        input texture coordinate values to be within a range of [0,255]. Hence
00254        we translate the x- and y-coordinate values by 128. Recall that the 
00255        values in nokTexCoords are between [-128,127], now they are in a range 
00256        of [0,255]. After that we scale the values by 1/255 to make the values 
00257        to be in range [0,1]. */
00258     glMatrixMode( GL_TEXTURE );
00259     glLoadIdentity();
00260     glScalef(     1.0f/255.0f, 1.0f/255.0f, 1.0f );
00261     glTranslatef( 128.0f,      128.0f,      0.0f );
00262     
00263     // Remember to change the matrix mode to modelview. 
00264     glMatrixMode( GL_MODELVIEW );
00265     
00266     // Enable back face culling, texturing and blending. 
00267     glEnable( GL_CULL_FACE  );
00268     glEnable( GL_TEXTURE_2D );
00269     glEnable( GL_BLEND );
00270     glBlendFunc( GL_SRC_ALPHA, GL_ONE );
00271     
00272     // Enable vertex arrays. 
00273     glEnableClientState( GL_VERTEX_ARRAY );
00274     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
00275     
00276     // Set array pointers. 
00277     glVertexPointer( 3, GL_BYTE, 0, LightVertices );
00278     glTexCoordPointer( 2, GL_BYTE, 0, LightTexCoords );
00279     
00280     // Set the initial shading mode 
00281     glShadeModel( GL_FLAT ); 
00282     
00283     /* Create texture names */
00284     glGenTextures( 2, iLightTexObjects );
00285     
00286     // Bind and set the light texture.
00287     glBindTexture( GL_TEXTURE_2D, iLightTexObjects[0] );
00288     glTexImage2D(  GL_TEXTURE_2D, 0, GL_RGBA, 64, 32, 
00289                    0, GL_RGBA, GL_UNSIGNED_BYTE, texPtr );
00290     glTexEnvx( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
00291     
00292     /* We can now free the memory reserved for light texture,
00293        since it's loaded inside OpenGL ES */
00294     delete[] iLightTex;
00295     iLightTex = NULL;
00296 
00297     /* Bind and set the environment map texture. We pass NULL as pixels,
00298        since we use glCopyTexImage2D later to initialize the texture memory. */
00299     glBindTexture( GL_TEXTURE_2D, iLightTexObjects[1] );
00300     glTexImage2D(  GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 
00301                    0, GL_RGB, GL_UNSIGNED_BYTE, NULL );
00302     glTexEnvx( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
00303     
00304     // Do not use perspective correction 
00305     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
00306   
00307 
00308     /*=========================================================================*/
00309     /*====================== Initialize Window context ========================*/
00310     /*=========================================================================*/
00311 
00312 
00313     // Bind the Window context to the current rendering thread and surface.
00314     eglMakeCurrent( instance->iEglDisplay, instance->iEglSurface, 
00315                     instance->iEglSurface, instance->iEglContext );
00316     
00317     // Set the screen background color. 
00318     glClearColor( 0.f, 0.f, 0.4f, 1.f );
00319     
00320     /* Enable depth testing and back face culling. */
00321     glEnable( GL_DEPTH_TEST );
00322     glEnable( GL_CULL_FACE  );
00323     glEnable( GL_TEXTURE_2D );
00324 
00325     // Initialize viewport and projection. 
00326     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00327     glMatrixMode( GL_PROJECTION );
00328 
00329     // Calculate the view frustrum
00330     glFrustumf( FRUSTUM_LEFT * iAspectRatio, FRUSTUM_RIGHT * iAspectRatio,
00331                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00332                 FRUSTUM_NEAR, FRUSTUM_FAR );
00333 
00334 
00335     // Initialize appropriate texture matrix
00336     glMatrixMode( GL_TEXTURE );
00337     glLoadIdentity();
00338     glScalef(     1.0f/32767.0f, 1.0f/32767.0f, 1.0f );
00339     
00340     // Remember to change the matrix mode to modelview. 
00341     glMatrixMode( GL_MODELVIEW );
00342     
00343     // Set shading mode
00344     glShadeModel( GL_FLAT ); 
00345     
00346     // Do not use perspective correction 
00347     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
00348 
00349 
00350         // Construct a texture manager that uses the application's private
00351         // directory as the location for all textures.
00352     iTextureManager = CTextureManager::NewL ( iScreenWidth, iScreenWidth,
00353                                               iAspectRatio*1.f, iAspectRatio*-1.f, 1.f, -1.f, 3.f,                               
00354                                               this );
00355 
00356     // Pushing the textures into the loading queue.
00357     _LIT(KWorldTexture, "world.jpg");
00358     iTextureManager->RequestToLoad(KWorldTexture, &iWorldTexture );
00359 
00360     //Start to load the textures.
00361     iTextureManager->DoLoadL();
00362     
00363 }

void CMultiTex::AppExit (  void   ) 
 

Called upon application exit. Destroys the CTextureManager instance that was created in AppInitL() method.

Definition at line 447 of file MultiTex.cpp.

References iTextureManager.

00448 {
00449     delete iTextureManager;
00450 }

void CMultiTex::AppCyclePbuffer (  TInt  aFrame  ) 
 

Renders one frame with Pbuffer context to Ppbuffer surface.

Parameters:
aFrame Number of the frame to be rendered.

Definition at line 482 of file MultiTex.cpp.

References DrawLights(), iCameraDistance, and iLightTexObjects.

00483 {
00484     glClear( GL_COLOR_BUFFER_BIT );
00485     
00486     // Bind the light texture as current 
00487     glBindTexture( GL_TEXTURE_2D, iLightTexObjects[0] );
00488     
00489     /* Animate and draw lights */
00490     glLoadIdentity();
00491     glTranslatex( 0 , 0 , -iCameraDistance << 16 );
00492     glScalex( 2 << 16, 2 << 16, 2 << 16 );
00493     DrawLights( iFrame );
00494     
00495     // Bind the environment map texture as current 
00496     glBindTexture( GL_TEXTURE_2D, iLightTexObjects[1] );
00497  
00498     // Copy the content of the pbuffer to the currently bound texture 
00499     glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 128, 128, 0 );
00500 }

void CMultiTex::AppCycleWindow (  TInt  aFrame  ) 
 

Renders one frame with Window context to Window surface.

Parameters:
aFrame Number of the frame to be rendered.

Definition at line 509 of file MultiTex.cpp.

References iCameraDistance.

00510 {
00511     // Set the TEXTURE1 unit as active (env map texture) 
00512     glActiveTexture( GL_TEXTURE1 );
00513     glClientActiveTexture( GL_TEXTURE1 );
00514     
00515     // Set the correct texture matrix 
00516     glMatrixMode( GL_TEXTURE );
00517     glLoadIdentity();
00518     glTranslatef( 0.5f, 0.5f, 0.5f );
00519     glRotatex( 180 << 16, 0, 0, 1 << 16 );
00520     glRotatex( iFrame << 16, 0, 1 << 16, 0 );
00521     glScalef( 1.0f/65534.0f, 1.0f/65534.0f, 1.0f/65534.0f );
00522     
00523     glMatrixMode( GL_MODELVIEW );
00524     
00525     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00526     
00527     glLoadIdentity();
00528     glTranslatex( 0 , 0 , -iCameraDistance << 16 );
00529     glRotatex( 180 << 16, 0, 0, 1 << 16 );
00530     glRotatex( iFrame << 16, 0, 1 << 16, 0 );
00531     
00532     // Scale the world model to fit the screen. 
00533     glScalex( 1 << 9, 1 << 9, 1 << 9 );
00534     glDrawElements( GL_TRIANGLES, objFaces * 3, 
00535                     GL_UNSIGNED_SHORT, objIndices );
00536 }

void CMultiTex::OnEnterStateL (  TInt  aState  ) 
 

Called when the finite state machine enters a new state. Does nothing in this implementation.

Parameters:
aState State that is about to be entered.

Definition at line 435 of file MultiTex.cpp.

00436         {
00437             // Nothing to do here...
00438         }

void CMultiTex::OnStartLoadingTexturesL (   ) 
 

Called when texture manager starts loading the textures. Sets the current state to "loading textures".

Definition at line 370 of file MultiTex.cpp.

00371         {
00372     SetStateL( ELoadingTextures );
00373         }

void CMultiTex::OnEndLoadingTexturesL (   ) 
 

Called when texture manager has completed texture loading. Changes the current state to "running".

Definition at line 379 of file MultiTex.cpp.

References iLightTexObjects, and iWorldTexture.

00380         {
00381     /* TEXTURE0 is used for Marble texture */
00382     glActiveTexture( GL_TEXTURE0 );
00383     glClientActiveTexture( GL_TEXTURE0 );
00384     
00385     // Enable texturing
00386     glEnable( GL_TEXTURE_2D );
00387     
00388     // Enable vertex and texture coordinates arrays. 
00389     glEnableClientState( GL_VERTEX_ARRAY );
00390     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
00391     
00392     // Set array pointers. 
00393     glVertexPointer( 3, GL_SHORT, 0, objVertex );
00394     glTexCoordPointer( 2, GL_SHORT, 0, objTexCoords );
00395     
00396     /* Bind the marble.jpg texture to iWorldTexture, set the texture 
00397        to the texPtr defined above, and set the texture environment. */
00398     glBindTexture( GL_TEXTURE_2D, iWorldTexture.iID );
00399     glTexEnvx( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
00400     
00401     /* Texture to TEXTURE1 is taken from Pbuffer 
00402        context, i.e, iLightTexObjects[1] */
00403     glActiveTexture( GL_TEXTURE1 );
00404     glClientActiveTexture( GL_TEXTURE1 );
00405     
00406     // Enable texturing
00407     glEnable( GL_TEXTURE_2D );
00408     
00409     // Enable vertex and texture coordinates arrays. 
00410     glEnableClientState( GL_VERTEX_ARRAY );
00411     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
00412     
00413     // Set array pointers. 
00414     glVertexPointer( 3, GL_SHORT, 0, objVertex );
00415     glTexCoordPointer( 3, GL_SHORT, 0, envNormals );
00416     
00417     /* Bind the environment map texture created with Pbuffer context.
00418        Actual creation and updating is done in AppCycle. */
00419     glBindTexture( GL_TEXTURE_2D, iLightTexObjects[1] );
00420 
00421     // Set the texture env mode for environment map texture 
00422     glTexEnvx( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
00423 
00424         if ( GetState() == ELoadingTextures )
00425                 {
00426                 SetStateL( ERunning );
00427                 }
00428         }

void CMultiTex::CalculateLightsL (  void   ) 
 

Calculate light texture for environment map lights.

Definition at line 166 of file MultiTex.cpp.

References iLightTex.

00167 {
00168     // Reserve memory for light texture
00169     iLightTex = new (ELeave) TUint8[64*32*4];
00170     if ( !iLightTex )
00171     {
00172         User::LeaveNoMemory();
00173     }
00174 
00175     TInt d         = 0;   // distance from the center of the spot
00176     GLfloat alpha = 0.f;  // alpha value
00177 
00178     for ( TInt i = 0; i < 32; i++ )
00179     {
00180         for ( TInt j = 0; j < 32; j++ )
00181         {
00182             // distance from the center of spotlight 
00183             d = (i-16)*(i-16) + (j-16)*(j-16);
00184             
00185             // simple linear attenuation used for alpha 
00186             alpha = 255.f*(1.f-(1.f/250.f)*(GLfloat)(d));
00187             
00188             // alpha < 0 corresponds to spotlight cut-off value 
00189             if ( alpha < 0.f )
00190             {
00191                 iLightTex[64*4*i+4*j]   = 255;      //r
00192                 iLightTex[64*4*i+4*j+1] = 0;        //g
00193                 iLightTex[64*4*i+4*j+2] = 0;        //b
00194                 iLightTex[64*4*i+4*j+3] = 0;        //a
00195 
00196                 iLightTex[64*4*i+4*j+32*4]   = 0;   //r
00197                 iLightTex[64*4*i+4*j+1+32*4] = 255; //g
00198                 iLightTex[64*4*i+4*j+2+32*4] = 0;   //b
00199                 iLightTex[64*4*i+4*j+3+32*4] = 0;   //a
00200             }
00201             // inside the cut-off, set alpha as calculated above/
00202             else
00203             {
00204                 iLightTex[64*4*i+4*j]   = 255;                   //r
00205                 iLightTex[64*4*i+4*j+1] = 0;                     //g
00206                 iLightTex[64*4*i+4*j+2] = 0;                     //b
00207                 iLightTex[64*4*i+4*j+3] = (GLubyte)(alpha);      //a
00208 
00209                 iLightTex[64*4*i+4*j+32*4]   = 0;                //r
00210                 iLightTex[64*4*i+4*j+1+32*4] = 255;              //g
00211                 iLightTex[64*4*i+4*j+2+32*4] = 0;                //b
00212                 iLightTex[64*4*i+4*j+3+32*4] = (GLubyte)(alpha); //a
00213             }
00214         }
00215     }
00216 }

void CMultiTex::DrawLights (  TInt  iFrame  ) 
 

Draws lights with given dimensions.

Parameters:
iFrame The current frame number

Definition at line 459 of file MultiTex.cpp.

00460 {
00461     // Draw red light 
00462     glPushMatrix();
00463     glTranslatex(( 2 << 16) + (GLint) (sin(iFrame * 0.10f) * 5 * 65536) , (2 << 16) + (GLint) (cos(iFrame * 0.13f) * 5 * 65536) , 0 );
00464     glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
00465     glPopMatrix();
00466     
00467     // Draw green light 
00468     glPushMatrix();
00469     glTranslatex( (-2 << 16) + (GLint) (sin(iFrame * 0.10f) * 5 * 65536) , (-2 << 16) + (GLint) (cos(iFrame * 0.10f) * 8 * 65536) , 0 );
00470     glDrawArrays( GL_TRIANGLE_STRIP, 4, 4 );
00471     glPopMatrix();
00472     
00473 }

void CMultiTex::SetScreenSize (  TUint  aWidth,
TUint  aHeight
) 
 

Notifies that the screen size has dynamically changed during execution of this program. Resets the viewport to this new size and sets this size to the CTextureManager.

Parameters:
aWidth New width of the screen.
aHeight New height of the screen.

Definition at line 543 of file MultiTex.cpp.

References iAspectRatio, iScreenHeight, iScreenWidth, and iTextureManager.

00544     {
00545     iScreenWidth  = aWidth;
00546     iScreenHeight = aHeight;
00547     
00548     // Notify the texture manager of screen size change
00549     iTextureManager->SetScreenSize( aWidth, aHeight );
00550 
00551     // Reinitialize viewport and projection.
00552     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00553 
00554     // Recalculate the view frustrum
00555     if ( iScreenHeight != 0 )
00556         {
00557         iAspectRatio = (GLfloat)iScreenWidth / (GLfloat)iScreenHeight;
00558         }
00559     else
00560         {
00561         iAspectRatio = 1.0;
00562         }
00563         
00564     glMatrixMode( GL_PROJECTION );
00565     glLoadIdentity();
00566     glFrustumf( FRUSTUM_LEFT * iAspectRatio, FRUSTUM_RIGHT * iAspectRatio,
00567                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00568                 FRUSTUM_NEAR, FRUSTUM_FAR );
00569     glMatrixMode( GL_PROJECTION );
00570 
00571     }

void CMultiTex::ConstructL (  void   )  [protected]
 

Second phase contructor. Does nothing.

Definition at line 154 of file MultiTex.cpp.

00155 {
00156 }


Member Data Documentation

CTextureManager* CMultiTex::iTextureManager [private]
 

Texture manager that is used to load the used textures.

Definition at line 153 of file MultiTex.h.

TUint CMultiTex::iScreenWidth [private]
 

Width of the screen

Definition at line 155 of file MultiTex.h.

TUint CMultiTex::iScreenHeight [private]
 

Height of the screen

Definition at line 157 of file MultiTex.h.

GLfloat CMultiTex::iAspectRatio [private]
 

Aspect ratio of the screen (iScreenHeight / iScreenWidth).

Definition at line 159 of file MultiTex.h.

TTexture CMultiTex::iWorldTexture [private]
 

World texture.

Definition at line 162 of file MultiTex.h.

TUint8* CMultiTex::iLightTex [private]
 

Pointer to the light texture data.

Definition at line 164 of file MultiTex.h.

GLuint CMultiTex::iLightTexObjects[2] [private]
 

List for light and env map texture objects.

Definition at line 166 of file MultiTex.h.

GLint CMultiTex::iCameraDistance [private]
 

Camera distance.

Definition at line 168 of file MultiTex.h.


© Nokia 2006

Back to top