S60 3rd Edition SDK for Symbian OS
Example Applications Guide

Billboard.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : Billboard.cpp
00004 *  Part of     : OpenGLEx / Billboard
00005 *  Interface   : 
00006 *  Description : 
00007 *  Version     : 
00008 *
00009 *  Copyright (c) 2004-2006 Nokia Corporation.
00010 *  This material, including documentation and any related 
00011 *  computer programs, is protected by copyright controlled by 
00012 *  Nokia Corporation.
00013 * ==============================================================================
00014 */
00015 
00016 // INCLUDE FILES
00017 #include "billboard.h"
00018 #include <aknnotewrappers.h> 
00019 #include <e32math.h>
00020 
00021 // EXTERNAL DATA STRUCTURES
00022 
00023 // EXTERNAL FUNCTION PROTOTYPES  
00024 
00025 // CONSTANTS
00026 const TInt KNumberOfTreeInRow = 10; //Number of trees in a row.
00027 const TInt KNumberOfTreeInCol = 10; //Number of trees in a col.
00028 const GLint KTreeStep = 10;         //Min. Distance between two trees.
00029 
00030 /* Define vertice coordinates for the ground plane */
00031 static const GLbyte planeVertices[4 * 3] =
00032         {
00033     +1,0,-1,
00034     +1,0,+1,
00035     -1,0,+1,
00036     -1,0,-1
00037         };
00038 
00039 /* Define texture coordinates for ground plane */
00040 static const GLshort planeTextureCoords[4 * 2] =
00041         {
00042         0,    0,
00043         0, 1000,
00044      1000, 1000,
00045      1000,    0
00046         };
00047  
00048 
00049 /* Define indices for drawing the triangles of the ground plane */
00050 static const GLubyte planeTriangles[2 * 3] =
00051         {
00052     0,2,1,
00053     0,3,2
00054         };
00055 
00056 
00057 /* Define vertice coordinates for drawing the trees */
00058 static const GLbyte treeVertices[4 * 3] =
00059         {
00060     +1,  0, 0,
00061     +1, +1, 0,
00062     -1, +1, 0,
00063     -1,  0, 0
00064         };
00065 
00066 /* Define texture coordinates for drawing the trees */
00067 static const GLbyte treeTextureCoords[4 * 2] =
00068         {
00069       0, 100,
00070       0,   0,
00071     100,   0,
00072     100, 100
00073         };
00074 
00075 /* Define indices for drawing the trees */
00076 static const GLubyte treeTriangles[2 * 3] =
00077         {
00078     0,1,2,
00079     0,2,3
00080         };
00081 
00082 /* Define indices for drawing the clouds */
00083 static const GLubyte cloudTriangles [] =
00084         {
00085     0,1,2,
00086     0,2,3
00087         };
00088 
00089 // MACROS
00090 
00091 // LOCAL CONSTANTS AND MACROS
00092 
00093 // MODULE DATA STRUCTURES
00094 
00095 // LOCAL FUNCTION PROTOTYPES
00096 
00097 // FORWARD DECLARATIONS
00098 
00099 // ============================ MEMBER FUNCTIONS ===============================
00100 
00101 // -----------------------------------------------------------------------------
00102 // CBillboard::NewL
00103 // Symbian 2-phase constructor. Can leave.
00104 // -----------------------------------------------------------------------------
00105 //
00106 CBillboard* CBillboard::NewL( TUint aWidth, TUint aHeight )
00107         {
00108     /* Symbian 2-phase constructor. Calls both the default 
00109        C++ constructor and Symbian ConstructL methods */
00110     CBillboard* self = new (ELeave) CBillboard( aWidth, aHeight );
00111     CleanupStack::PushL( self );
00112     self->ConstructL();
00113     CleanupStack::Pop();
00114 
00115     return self;
00116         }
00117 
00118 //  Destructor. 
00119 CBillboard::~CBillboard()
00120         {
00121         }
00122 
00123 // -----------------------------------------------------------------------------
00124 // CBillboard::AppInit
00125 // Initializes the application.
00126 // -----------------------------------------------------------------------------
00127 //
00128 void CBillboard::AppInitL( void )
00129         {
00130     /* Set the screen background color. */
00131     glClearColor( 0.f, 0.f, 0.f, 1.f );
00132 
00133     /* Enable back face culling. */
00134     glEnable( GL_CULL_FACE  );
00135     glEnable( GL_TEXTURE_2D );
00136     glEnable( GL_DEPTH_TEST );
00137 
00138     /*Disable lighting */
00139     glDisable( GL_LIGHTING );
00140 
00141     //Enable alpha test for color keying.
00142     glEnable( GL_ALPHA_TEST );
00143     glAlphaFuncx( GL_GREATER, FLOAT_2_FIXED(0.0f));
00144 
00145     /* Initialize viewport and projection. */
00146     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00147     glMatrixMode( GL_PROJECTION );
00148 
00149     // Calculate the view frustrum
00150     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00151     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00152                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00153                 FRUSTUM_NEAR, FRUSTUM_FAR );
00154 
00155     // Calculate cloud vertices based on the aspect ratio
00156     iCloudVertices[ 0 ] = FRUSTUM_RIGHT * aspectRatio;
00157     iCloudVertices[ 1 ] = 0.f;
00158     iCloudVertices[ 2 ] = -FRUSTUM_NEAR;
00159 
00160     iCloudVertices[ 3 ] = FRUSTUM_RIGHT * aspectRatio;
00161     iCloudVertices[ 4 ] = FRUSTUM_TOP;
00162     iCloudVertices[ 5 ] = -FRUSTUM_NEAR;
00163 
00164     iCloudVertices[ 6 ] = FRUSTUM_LEFT * aspectRatio;
00165     iCloudVertices[ 7 ] = FRUSTUM_TOP;
00166     iCloudVertices[ 8 ] = -FRUSTUM_NEAR;
00167 
00168     iCloudVertices[ 9 ] = FRUSTUM_LEFT * aspectRatio;
00169     iCloudVertices[ 10 ] = 0.f;
00170     iCloudVertices[ 11 ] = -FRUSTUM_NEAR;
00171 
00172 
00173     glMatrixMode( GL_TEXTURE );
00174     glLoadIdentity();
00175     glScalex(FIXED_DIV(FIXED_ONE, INT_2_FIXED(100)), FIXED_DIV(FIXED_ONE, INT_2_FIXED(100)), FIXED_ONE );
00176 
00177 
00178     glMatrixMode( GL_MODELVIEW );
00179 
00180     /* Enable vertex arrays. */
00181     glEnableClientState( GL_VERTEX_ARRAY );
00182     /* Enable texture arrays. */
00183     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
00184 
00185     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00186     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00187 
00188     iCloudTextureCoords[0] =   0; iCloudTextureCoords[1] = 100; 
00189     iCloudTextureCoords[2] =   0; iCloudTextureCoords[3] =   0; 
00190     iCloudTextureCoords[4] = 100; iCloudTextureCoords[5] =   0; 
00191     iCloudTextureCoords[6] = 100; iCloudTextureCoords[7] = 100; 
00192 
00193     iDistance = INT_2_FIXED(40);
00194     iDirection = +1;
00195 
00196     iLookUpTable = CLookUpTable::NewL( CLookUpTable::ESinx | CLookUpTable::ECosx );
00197 
00198         // Construct a texture manager that uses the application's private
00199         // directory as the location for all textures.
00200     iTextureManager = CTextureManager::NewL ( iScreenWidth, iScreenWidth,
00201                                               FRUSTUM_TOP, FRUSTUM_BOTTOM, FRUSTUM_RIGHT, FRUSTUM_LEFT, FRUSTUM_NEAR,                               
00202                                               this );
00203     
00204     // Defining a color key interval for the tree texture.
00205     TUint8 MinColor[] = {  50, 0,  50};
00206     TUint8 MaxColor[] = { 200, 0, 200};
00207     
00208     // Pushing the textures into the loading queue.
00209     _LIT(KTreeTexture, "tree.gif");
00210     _LIT(KGrassTexture, "grass.jpg");
00211     _LIT(KCloudTexture, "cloud.jpg");
00212     iTextureManager->RequestToLoad( KTreeTexture , &iTreeTexture, MinColor, MaxColor );
00213     iTextureManager->RequestToLoad( KGrassTexture, &iGrassTexture );
00214     iTextureManager->RequestToLoad( KCloudTexture, &iCloudTexture );
00215 
00216     //Start to load the textures.
00217     iTextureManager->DoLoadL();
00218         }
00219 
00220 // -----------------------------------------------------------------------------
00221 // CBillboard::AppExit
00222 // Release any allocations made in AppInit.
00223 // -----------------------------------------------------------------------------
00224 //
00225 void CBillboard::AppExit( void )
00226         {
00227     delete iTextureManager;
00228     delete iLookUpTable;
00229         }
00230 
00231 // -----------------------------------------------------------------------------
00232 // CBillboard::DrawPlane
00233 // Draw the ground plane.
00234 // -----------------------------------------------------------------------------
00235 //
00236 void CBillboard::DrawPlane( TInt /*aFrame*/ )
00237         {
00238     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE );
00239 
00240     glBindTexture(  GL_TEXTURE_2D, iGrassTexture.iID );
00241 
00242     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00243     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00244     
00245     glLoadIdentity();
00246     T3DModelx::MakeWorldViewMatrix(iCamera, TVectorx(INT_2_FIXED(0), INT_2_FIXED(0), INT_2_FIXED(0)));
00247     glScalex( INT_2_FIXED(100), INT_2_FIXED(0), INT_2_FIXED(100) );
00248 
00249     glVertexPointer( 3, GL_BYTE, 0, planeVertices );
00250     glTexCoordPointer( 2, GL_SHORT, 0, planeTextureCoords );
00251     glDrawElements( GL_TRIANGLES, 2 * 3, GL_UNSIGNED_BYTE, planeTriangles );
00252 
00253     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00254     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00255 
00256     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
00257         }
00258 
00259 // -----------------------------------------------------------------------------
00260 // CBillboard::DrawCloud
00261 // Draw clouds.
00262 // -----------------------------------------------------------------------------
00263 //
00264 void CBillboard::DrawCloud( TInt /*aFrame*/ )
00265         {
00266     //Moving the clouds.
00267     iTextureOffset = (GLshort)(iTextureOffset + 10 * iDirection * FIXED_2_FLOAT(iElapsedTime));
00268     iCloudTextureCoords[0] = iCloudTextureCoords[2] = iTextureOffset;
00269     iCloudTextureCoords[4] = iCloudTextureCoords[6] = (GLshort)(iTextureOffset+40);
00270 
00271     glLoadIdentity();
00272 
00273     glBindTexture( GL_TEXTURE_2D, iCloudTexture.iID );
00274 
00275         glVertexPointer( 3, GL_FLOAT, 0, iCloudVertices );
00276     glTexCoordPointer( 2, GL_SHORT, 0, iCloudTextureCoords );
00277     glDrawElements( GL_TRIANGLES, 2 * 3, GL_UNSIGNED_BYTE, cloudTriangles );
00278         }
00279 
00280 // -----------------------------------------------------------------------------
00281 // CBillboard::DrawTree
00282 // Draw a tree.
00283 // -----------------------------------------------------------------------------
00284 //
00285 void CBillboard::DrawTree( TInt /*aFrame*/, TInt aI, TInt aJ)
00286         {
00287     GLint x = KTreeStep * (aJ - (KNumberOfTreeInCol >> 1));
00288     GLint z = KTreeStep * (aI - (KNumberOfTreeInRow >> 1));
00289 
00290     glLoadIdentity();
00291     
00292     // Turns the tree so that it always faces the camera. (Billboarding technique)
00293     T3DModelx::MakeBillboardWorldViewMatrix(iCamera, TVectorx(INT_2_FIXED(x), INT_2_FIXED(0), INT_2_FIXED(z)));
00294     glScalex( INT_2_FIXED(1), INT_2_FIXED(3), INT_2_FIXED(1) );
00295 
00296     glBindTexture(  GL_TEXTURE_2D, iTreeTexture.iID );
00297     
00298     glVertexPointer(   3, GL_BYTE, 0, treeVertices );
00299     glTexCoordPointer( 2, GL_BYTE, 0, treeTextureCoords );
00300     glDrawElements(    GL_TRIANGLES, 2 * 3, GL_UNSIGNED_BYTE, treeTriangles );
00301         }
00302 
00303 
00304 // -----------------------------------------------------------------------------
00305 // CBillboard::AppCycle
00306 // Draws and animates the objects.
00307 // @param aFrame Current frame number.
00308 // -----------------------------------------------------------------------------
00309 //
00310 void CBillboard::AppCycle( TInt aFrame )
00311         {
00312         glClear( GL_DEPTH_BUFFER_BIT );
00313 
00314     iT0 = iT1;
00315     do 
00316                 {
00317         iT1 = GetTimeTick();
00318         //Compute the ellapsed time (in sec.) between the current and the previous frame.
00319         iElapsedTime = FLOAT_2_FIXED( I64LOW( iT1.MicroSecondsFrom( iT0 ).Int64() ) * ( 1 / 1000000.0f ) );
00320                 } while ( iElapsedTime == 0 );   
00321 
00322         //Compute the frame rate
00323     iFPSCount = FIXED_DIV(FIXED_ONE, iElapsedTime);
00324 
00325     /* Move the camera. */
00326     TurnCamera(iDirection);
00327 
00328     GLfixed sin = iLookUpTable->Sinx(iAzimuth),
00329             cos = iLookUpTable->Cosx(iAzimuth);
00330 
00331     GLfixed x = FIXED_MUL(iDistance, cos);
00332     GLfixed z = FIXED_MUL(iDistance, sin);
00333 
00334     iCamera.LookAt(TVectorx(x, INT_2_FIXED(3), z),
00335                    TVectorx(INT_2_FIXED(0), INT_2_FIXED(0),  INT_2_FIXED(0)),
00336                    TVectorx(INT_2_FIXED(0), INT_2_FIXED(1),  INT_2_FIXED(0)));
00337 
00338     /* Draws the clouds, the gound plane and the trees */
00339     glDisable( GL_DEPTH_TEST );
00340     DrawCloud( aFrame );
00341     DrawPlane( aFrame );
00342     glEnable( GL_DEPTH_TEST );
00343 
00344     for ( TInt i = 0;i < KNumberOfTreeInRow; i++ )
00345         {
00346         for ( TInt j = 0;j < KNumberOfTreeInCol; j++ )
00347                         {
00348                         DrawTree( aFrame, i, j);
00349                         }
00350         }
00351         }
00352 
00353 // -----------------------------------------------------------------------------
00354 // CBillboard::CBillBoard
00355 // Default C++ and Symbian ConstructL are placed in protected
00356 // area to force the use of NewL when creating an instance.
00357 // -----------------------------------------------------------------------------
00358 //
00359 CBillboard::CBillboard( TUint aWidth, TUint aHeight )
00360         : CFiniteStateMachine()
00361         {
00362     iScreenWidth  = aWidth;
00363     iScreenHeight = aHeight;
00364         }
00365 
00366 // -----------------------------------------------------------------------------
00367 // CBillboard::ConstructL
00368 // Symbian 2nd phase constructor can leave.
00369 // -----------------------------------------------------------------------------
00370 //
00371 void CBillboard::ConstructL( void )
00372         {
00373         }
00374 
00375 // ---------------------------------------------------------
00376 // CBillboard::OnEnterState( TInt aState )
00377 // Called by TFiniteStateMachine when the f.s.m enters a new state
00378 // ---------------------------------------------------------
00379 
00380 void CBillboard::OnEnterStateL( TInt aState )
00381         {
00382     switch ( aState )
00383                 {
00384                 case ERunning:
00385                         iT1 = GetTimeTick();
00386                         break;
00387 
00388                 default:
00389                   break;
00390                 }
00391         }
00392 
00393 // -------------------------------------------------------------------------------------------------------
00394 // CBillboard::OnStartLoadingTextures()
00395 // Called for a MTextureLoadingListener by the texture manager when texture loading operation starts 
00396 // -------------------------------------------------------------------------------------------------------
00397 
00398 void CBillboard::OnStartLoadingTexturesL()
00399         {
00400     SetStateL( ELoadingTextures );
00401         }
00402 
00403 // ------------------------------------------------------------------------------------------------------------
00404 // CBillboard::OnEndLoadingTextures()
00405 // Called for a MTextureLoadingListener by the texture manager when texture loading operation is completed
00406 // ------------------------------------------------------------------------------------------------------------
00407 void CBillboard::OnEndLoadingTexturesL()
00408         {
00409         if ( GetState() == ELoadingTextures )
00410                 {
00411                 SetStateL( ERunning );
00412                 }
00413         }
00414 
00415 // ------------------------------------------------------------------------------------------------------------
00416 // CBillboard::GetTimeTick()
00417 // Returns the current time.
00418 // ------------------------------------------------------------------------------------------------------------
00419 TTime CBillboard::GetTimeTick()
00420         {
00421         TTime time;
00422         time.UniversalTime();
00423         
00424         return time;
00425         }
00426 
00427 // ------------------------------------------------------------------------------------------------------------
00428 // CBillboard::GetElapsedTime()
00429 // Returns the ellapsed time (in sec.) between the current and the previous frame.
00430 // ------------------------------------------------------------------------------------------------------------
00431 GLfixed CBillboard::GetElapsedTime() 
00432         {
00433         return iElapsedTime; 
00434         }
00435 
00436 // ------------------------------------------------------------------------------------------------------------
00437 // CBillboard::GetFPSCount()
00438 // Returns the current frame rate in f.p.s
00439 // ------------------------------------------------------------------------------------------------------------
00440 GLfixed CBillboard::GetFPSCount() 
00441         { 
00442         return iFPSCount; 
00443         }
00444 
00445 // -----------------------------------------------------------------------------
00446 // CBillboard::SetScreenSize
00447 // Reacts to the dynamic screen size change during execution of this program.
00448 // -----------------------------------------------------------------------------
00449 //
00450 void CBillboard::SetScreenSize( TUint aWidth, TUint aHeight )
00451     {
00452     iScreenWidth  = aWidth;
00453     iScreenHeight = aHeight;
00454     
00455     // Notify the texture manager of screen size change
00456     iTextureManager->SetScreenSize( aWidth, aHeight );
00457 
00458     // Reinitialize viewport and projection.
00459     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00460 
00461     // Recalculate the view frustrum
00462     glMatrixMode( GL_PROJECTION );
00463     glLoadIdentity();
00464     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00465     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00466                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00467                 FRUSTUM_NEAR, FRUSTUM_FAR );
00468     glMatrixMode( GL_MODELVIEW );
00469 
00470     // Recalculate cloud vertices based on the aspect ratio
00471     iCloudVertices[ 0 ] = FRUSTUM_RIGHT * aspectRatio;
00472     iCloudVertices[ 1 ] = 0.f;
00473     iCloudVertices[ 2 ] = -FRUSTUM_NEAR;
00474 
00475     iCloudVertices[ 3 ] = FRUSTUM_RIGHT * aspectRatio;
00476     iCloudVertices[ 4 ] = FRUSTUM_TOP;
00477     iCloudVertices[ 5 ] = -FRUSTUM_NEAR;
00478 
00479     iCloudVertices[ 6 ] = FRUSTUM_LEFT * aspectRatio;
00480     iCloudVertices[ 7 ] = FRUSTUM_TOP;
00481     iCloudVertices[ 8 ] = -FRUSTUM_NEAR;
00482 
00483     iCloudVertices[ 9 ] = FRUSTUM_LEFT * aspectRatio;
00484     iCloudVertices[ 10 ] = 0.f;
00485     iCloudVertices[ 11 ] = -FRUSTUM_NEAR;
00486     }
00487 
00488 // ------------------------------------------------------------------------------------------------------------
00489 // CBillboard::MoveCamera()
00490 // Move the camera from/to the origin.
00491 // ------------------------------------------------------------------------------------------------------------
00492 void CBillboard::MoveCamera(GLint aDirection, GLfixed aTime)
00493         {
00494         if ( aTime == 0 )
00495                 {
00496                 aTime = iElapsedTime;
00497                 }
00498         iDistance += FIXED_MUL(INT_2_FIXED(aDirection * 3), aTime);
00499         if ( iDistance < INT_2_FIXED(-100) )
00500                 {
00501                 iDistance = INT_2_FIXED(-100);
00502                 }
00503         if ( iDistance > INT_2_FIXED(+100) )
00504                 {
00505                 iDistance = INT_2_FIXED(+100);
00506                 }
00507     }
00508 
00509 // ------------------------------------------------------------------------------------------------------------
00510 // CBillboard::TurnCamera()
00511 // Turn the camera in azimuth.
00512 // ------------------------------------------------------------------------------------------------------------
00513 void CBillboard::TurnCamera(GLint aDirection, GLfixed aTime)
00514         {
00515         if ( aTime == 0 )
00516                 {
00517                 aTime = iElapsedTime;
00518                 }
00519     iAzimuth += FIXED_MUL(INT_2_FIXED(aDirection * 10), aTime);
00520      //Keeping the azimuth within [0, 359]
00521     if ( iAzimuth < 0 )
00522         {
00523         iAzimuth = INT_2_FIXED(+359);
00524         }
00525     else if ( iAzimuth > INT_2_FIXED(+359) )
00526         {
00527         iAzimuth = 0; 
00528         }
00529     else 
00530         {
00531         }
00532         }

© Nokia 2006

Back to top