S60 3rd Edition SDK for Symbian OS
Example Applications Guide

LensFlare.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : LensFlare.cpp
00004 *  Part of     : OpenGLEx / LensFlare
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 "lensflare.h"
00018 #include <aknnotewrappers.h> 
00019 #include <e32math.h>
00020 
00021 #include "model.h" 
00022 
00023 // EXTERNAL DATA STRUCTURES
00024 
00025 // EXTERNAL FUNCTION PROTOTYPES  
00026 
00027 // CONSTANTS
00028 
00029 // MACROS
00030 #define scl 1.0
00031 
00032 // LOCAL CONSTANTS AND MACROS
00033 
00034 /* Lens flare configuration */
00035 static const TFlareConfig LensFlareConfigs[] =
00036         {
00037     { 0, (GLfloat)(+1.2 / 01.0), (GLfloat)(0.15 / scl) },
00038     { 0, (GLfloat)(+1.0 / 01.0), (GLfloat)(1.00 / scl) },
00039     { 2, (GLfloat)(+1.0 / 01.5), (GLfloat)(0.50 / scl) },
00040     { 1, (GLfloat)(+1.0 / 01.6), (GLfloat)(0.25 / scl) },
00041     { 2, (GLfloat)(+1.0 / 02.0), (GLfloat)(0.50 / scl) },
00042     { 0, (GLfloat)(+1.0 / 02.3), (GLfloat)(0.25 / scl) },
00043     { 1, (GLfloat)(+1.0 / 17.0), (GLfloat)(0.35 / scl) },
00044     { 2, (GLfloat)(+1.0 / 09.0), (GLfloat)(0.20 / scl) },
00045     { 2, (GLfloat)(-1.0 / 02.0), (GLfloat)(0.50 / scl) },
00046     { 1, (GLfloat)(-1.0 / 04.0), (GLfloat)(0.25 / scl) },
00047     { 1, (GLfloat)(-1.0 / 05.0), (GLfloat)(0.45 / scl) }
00048         };
00049 
00050 /* Length of LensFlareConfigs */
00051 static const TUint8 LensFlareConfigCount = sizeof(LensFlareConfigs)/sizeof(LensFlareConfigs[0]);
00052 
00053 /* Define vertice coordinates for the ground plane */
00054 static const GLbyte planeVertices[4 * 3] =
00055         {
00056     +1,0,-1,
00057     +1,0,+1,
00058     -1,0,+1,
00059     -1,0,-1
00060         };
00061 
00062 /* Define indices for drawing the triangles of the ground plane */
00063 static const GLubyte planeTriangles[2 * 3] =
00064         {
00065     0,2,1,
00066     0,3,2
00067         };
00068 
00069 // MODULE DATA STRUCTURES
00070 
00071 // LOCAL FUNCTION PROTOTYPES
00072 
00073 // FORWARD DECLARATIONS
00074 
00075 // ============================ MEMBER FUNCTIONS ===============================
00076 
00077 // -----------------------------------------------------------------------------
00078 
00079 // -----------------------------------------------------------------------------
00080 // CLensflare::NewL
00081 // Two-phased constructor. Can leave.
00082 // -----------------------------------------------------------------------------
00083 //
00084 CLensflare* CLensflare::NewL( TUint aWidth, TUint aHeight )
00085         {
00086     /* Symbian 2-phase constructor. Calls both the default 
00087        C++ constructor and Symbian ConstructL methods */
00088     CLensflare* self = new (ELeave) CLensflare( aWidth, aHeight );
00089     CleanupStack::PushL( self );
00090     self->ConstructL();
00091     CleanupStack::Pop();
00092 
00093     return self;
00094         }
00095 
00096 /**
00097  * Destructor. 
00098  */
00099 CLensflare::~CLensflare()
00100         {
00101         }
00102 
00103 // -----------------------------------------------------------------------------
00104 // CLensflare::CLensflare
00105 // C++ default constructor can NOT contain any code, that
00106 // might leave.
00107 // -----------------------------------------------------------------------------
00108 //
00109 CLensflare::CLensflare( TUint aWidth, TUint aHeight )
00110         : CFiniteStateMachine()
00111         {
00112     iScreenWidth  = aWidth;
00113     iScreenHeight = aHeight;
00114 
00115         }
00116 
00117 // -----------------------------------------------------------------------------
00118 // CLensflare::ConstructL
00119 // Symbian 2nd phase constructor can leave.
00120 // -----------------------------------------------------------------------------
00121 //
00122 void CLensflare::ConstructL( void )
00123         {
00124         }
00125 
00126 // -----------------------------------------------------------------------------
00127 // CLensflare::AppInit
00128 // Initializes the application.
00129 // -----------------------------------------------------------------------------
00130 //
00131 void CLensflare::AppInitL( void )
00132         {
00133     /* Set the screen background color. */
00134     glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
00135 
00136     /* Enable back face culling. */
00137     glEnable( GL_CULL_FACE  );
00138     glEnable( GL_TEXTURE_2D );
00139     glEnable( GL_DEPTH_TEST );
00140 
00141     /*Disable lighting */
00142     glDisable( GL_LIGHTING );
00143 
00144     /* In this example, speed is  more important than quality */
00145     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
00146 
00147     /* Initialize viewport and projection. */
00148     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00149     glMatrixMode( GL_PROJECTION );
00150 
00151     // Calculate the view frustrum
00152     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00153     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00154                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00155                 FRUSTUM_NEAR, FRUSTUM_FAR );
00156 
00157     glMatrixMode( GL_MODELVIEW );
00158 
00159     /* Enable vertex arrays. */
00160     glEnableClientState( GL_VERTEX_ARRAY );
00161     /* Enable texture arrays. */
00162     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
00163 
00164     glTexEnvx( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
00165 
00166     iDistance = 250;
00167     iElevation = 8;
00168     iAzimuth = 90;
00169     iDirection = +1;
00170 
00171     iLookUpTable = CLookUpTable::NewL( CLookUpTable::ESin | CLookUpTable::ECos );
00172 
00173         // Construct a texture manager that uses the application's private
00174         // directory as the source location for all textures.
00175     iTextureManager = CTextureManager::NewL( iScreenWidth, iScreenWidth,
00176                                              FRUSTUM_TOP, FRUSTUM_BOTTOM, FRUSTUM_RIGHT, FRUSTUM_LEFT, FRUSTUM_NEAR,                                
00177                                              this );
00178 
00179     TBufC<MAX_TEXTURE_NAME> LensFlareTextureNames[4];
00180 
00181     //Set of textures that will be used by the lens flare effect.
00182     _LIT(KLens1, "lens1.jpg");
00183     _LIT(KLens2, "lens2.jpg");
00184     _LIT(KLens3, "lens3.jpg");
00185     LensFlareTextureNames[0] = KLens1;
00186     LensFlareTextureNames[1] = KLens2;
00187     LensFlareTextureNames[2] = KLens3;
00188 
00189     iLensFlareEffect = CLensFlareEffect::NewL(  LensFlareTextureNames, 3,
00190                                                 LensFlareConfigs, LensFlareConfigCount, 
00191                                                 iTextureManager,
00192                                                 iScreenWidth, iScreenHeight);
00193     
00194     //Start to load the textures.
00195     iTextureManager->DoLoadL();
00196         }
00197 
00198 // -----------------------------------------------------------------------------
00199 // CLensflare::AppExit
00200 // Release any allocations made in AppInit.
00201 // -----------------------------------------------------------------------------
00202 //
00203 void CLensflare::AppExit( void )
00204         {
00205     delete iTextureManager;
00206     delete iLensFlareEffect;
00207     delete iLookUpTable;
00208         }
00209 
00210 
00211 // -----------------------------------------------------------------------------
00212 // CLensflare::DrawText
00213 // Draw the 'NokiaGL' text.
00214 // -----------------------------------------------------------------------------
00215 //
00216 void CLensflare::DrawText(TBool aReflection)
00217         {
00218     glDisable( GL_DEPTH_TEST );
00219 
00220     glLoadIdentity();
00221 
00222     T3DModel::MakeWorldViewMatrix( iCamera, TVector(0.0f, 0.0f, 0.0f));
00223 
00224     if ( aReflection )
00225         {
00226         glScalef( 1.0f , -1.0f, 1.0f);// reflect across Y=0 plane. 
00227         }
00228     /* Scale the model to fit the screen. */
00229     glScalef( 0.01f, 0.01f, 0.01f );
00230 
00231     glDisable( GL_TEXTURE_2D );
00232     glColor4f( 0, 0, 1.f, 1.0f ); // Blue (nokia's logo color)
00233     glVertexPointer( 3, GL_SHORT, 0, TextVertices );
00234     glDrawElements( GL_TRIANGLES, TextIndicesCount, GL_UNSIGNED_SHORT, TextIndices );
00235     glEnable( GL_TEXTURE_2D );
00236 
00237     glEnable( GL_DEPTH_TEST );
00238         }
00239 
00240 // -----------------------------------------------------------------------------
00241 // CLensflare::DrawPlane
00242 // Draw the ground plane.
00243 // -----------------------------------------------------------------------------
00244 //
00245 void CLensflare::DrawPlane()
00246         {
00247     glLoadIdentity();
00248     T3DModel::MakeWorldViewMatrix(iCamera, TVector(0.0f, 0.0f, 0.0f));
00249     glScalef( 250, 0, 250 );
00250 
00251     //Enable alpha blending in order to blend the reflected text with the groud plane.
00252     glEnable(GL_BLEND);
00253     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00254     glColor4f( 0.7f, 0.0f, 0.0f, 0.70f ); // 70% of groud plane color - 30% of text color.
00255 
00256     glDisable( GL_TEXTURE_2D );
00257     glVertexPointer( 3, GL_BYTE, 0, planeVertices );
00258     glDrawElements( GL_TRIANGLES, 2 * 3, GL_UNSIGNED_BYTE, planeTriangles );
00259     glEnable( GL_TEXTURE_2D );
00260 
00261     glDisable(GL_BLEND);
00262         }
00263 
00264 // -----------------------------------------------------------------------------
00265 // CLensflare::AppCycle
00266 // Draws and animates the objects.
00267 // -----------------------------------------------------------------------------
00268 //
00269 void CLensflare::AppCycle( TInt /*aFrame*/ )
00270         {
00271 
00272     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00273 
00274     iT0 = iT1;
00275     do 
00276                 {
00277         iT1 = GetTimeTick();
00278         //Compute the ellapsed time (in sec.) between the current and the previous frame.
00279         iElapsedTime = I64LOW( iT1.MicroSecondsFrom( iT0 ).Int64() * ( 1 / 1000000.0f ) );
00280                 } while ( iElapsedTime == 0 );                   
00281     
00282         iFPSCount = 1 / (iElapsedTime);        //Compute the frame rate.
00283 
00284     /* Move the camera. */
00285     TurnCameraAzimuth(iDirection);
00286 
00287     GLfloat sinA, cosA, sinE, cosE;
00288 
00289     sinE = iLookUpTable->Sin((GLushort)iElevation);
00290     cosE = iLookUpTable->Cos((GLushort)iElevation);
00291     sinA = iLookUpTable->Sin((GLushort)iAzimuth);
00292     cosA = iLookUpTable->Cos((GLushort)iAzimuth);
00293 
00294     GLfloat x = iDistance * cosE * cosA;
00295     GLfloat y = iDistance * sinE;
00296     GLfloat z = iDistance * cosE * sinA;
00297 
00298     iCamera.LookAt(TVector(x, y, z ), TVector(0.0f, 0.0f, 0.0f ), TVector(0.0f, 1.0f, 0.0f));
00299 
00300     /*Draws the gound plane and the 'NokiaGL' text in the normal and the reflected form.*/
00301     DrawText(ETrue);
00302     DrawPlane();
00303     DrawText(EFalse);
00304 
00305     /* Animate and draw the lens flare. */
00306     iLensAngle += (20 * iDirection * iElapsedTime);
00307     if ( iLensAngle < 0 )
00308         {
00309         iLensAngle = 359;
00310         }
00311     else if ( iLensAngle > 359 ) 
00312         {
00313         iLensAngle = 0;
00314         }
00315     else
00316         {
00317         }
00318     
00319     GLfloat sin = iLookUpTable->Sin((GLushort)iLensAngle);
00320     GLfloat cos = iLookUpTable->Cos((GLushort)iLensAngle);
00321 
00322     iLensRadius = 65 * (sin > 0 ? sin : -sin);
00323     TReal xx = iLensRadius * cos + iScreenWidth / 2;
00324     TReal yy = iLensRadius * sin + iScreenHeight / 2;
00325 
00326     iLensFlareEffect->DrawAt((TInt)xx, (TInt)yy);
00327         }
00328 
00329 
00330 // ---------------------------------------------------------
00331 // CLensflare::GetTimeTick
00332 // Returns the current time.
00333 // ---------------------------------------------------------
00334 TTime CLensflare::GetTimeTick()
00335         {
00336         TTime time;
00337         time.UniversalTime();
00338    
00339         return time;
00340         }
00341         
00342 // ---------------------------------------------------------
00343 // CLensflare::GetElapsedTime
00344 // Returns the time (in sec.) between current and previous frame.
00345 // ---------------------------------------------------------
00346 GLfloat CLensflare::GetElapsedTime()
00347         { 
00348         return iElapsedTime;
00349         }
00350 
00351 // ---------------------------------------------------------
00352 // CLensflare::GetFPSCount
00353 // Returns the current frame rate.
00354 // ---------------------------------------------------------
00355 GLfloat CLensflare::GetFPSCount() 
00356         {
00357         return iFPSCount;
00358         }
00359 
00360 // ---------------------------------------------------------
00361 // CLensflare::MoveCamera
00362 // Move the camera from/to the origin.
00363 // ---------------------------------------------------------
00364 void CLensflare::MoveCamera(GLint aDirection, GLfloat aTime)
00365         {
00366         if ( aTime == 0 )
00367                 {
00368                 aTime = iElapsedTime;
00369                 }
00370         iDistance += (aDirection * 20 * aTime);
00371         }
00372 
00373 // ---------------------------------------------------------
00374 // CLensflare::TurnCameraAzimuth
00375 // Turn the camera in azimuth.
00376 // ---------------------------------------------------------
00377 void CLensflare::TurnCameraAzimuth(GLint aDirection, GLfloat aTime)
00378         {
00379         if ( aTime == 0 )
00380                 {
00381                 aTime = iElapsedTime;
00382                 }
00383         iAzimuth += (aDirection * 20 * aTime);
00384         if ( iAzimuth < 0 )
00385                 {
00386                 iAzimuth = 359;
00387                 }
00388         else if ( iAzimuth > 359 )
00389                 {
00390                 iAzimuth = 0;
00391                 }
00392         else
00393                 {
00394                 }
00395         }
00396 
00397 // ---------------------------------------------------------
00398 // CLensflare::TurnCameraElevation
00399 // Turn the camera in elevation.
00400 // ---------------------------------------------------------
00401 void CLensflare::TurnCameraElevation(GLint aDirection, GLfloat aTime)
00402         {
00403         if ( aTime == 0 )
00404                 {
00405                 aTime = iElapsedTime;
00406                 }
00407         iElevation += ( aDirection * 20 * aTime);
00408         if ( iElevation < 5 )
00409                 {
00410                 iElevation = 5;
00411                 }
00412         else if ( iElevation > 175 )
00413                 {
00414                 iElevation = 175;
00415                 }
00416         else
00417                 {
00418                 }
00419         }
00420 
00421 
00422 // -------------------------------------------------------------------------------------------------------
00423 // CLensflare::OnStartLoadingTextures()
00424 // Called for a MTextureLoadingListener by the texture manager when texture loading operation starts 
00425 // -------------------------------------------------------------------------------------------------------
00426 void CLensflare::OnStartLoadingTexturesL()
00427         {
00428     SetStateL( ELoadingTextures );
00429         }
00430 
00431 // ------------------------------------------------------------------------------------------------------------
00432 // CLensflare::OnEndLoadingTextures()
00433 // Called for a MTextureLoadingListener by the texture manager when texture loading operation is completed
00434 // ------------------------------------------------------------------------------------------------------------
00435 
00436 void CLensflare::OnEndLoadingTexturesL()
00437         {
00438         if ( GetState() == ELoadingTextures )
00439                 {
00440                 SetStateL( ERunning );
00441                 }
00442         }
00443 
00444 // ---------------------------------------------------------
00445 // CLensflare::OnEnterState( TInt aState )
00446 // Called by CFiniteStateMachine when the f.s.m enters a new state.
00447 // ---------------------------------------------------------
00448 
00449 void CLensflare::OnEnterStateL( TInt aState )
00450         {
00451     switch ( aState )
00452                 {
00453                 case ERunning:
00454                         iT1 = GetTimeTick();
00455                         break;
00456                 default:
00457               break;
00458                 }
00459         }
00460 
00461 // -----------------------------------------------------------------------------
00462 // CLensflare::SetScreenSize
00463 // Reacts to the dynamic screen size change during execution of this program.
00464 // -----------------------------------------------------------------------------
00465 //
00466 void CLensflare::SetScreenSize( TUint aWidth, TUint aHeight )
00467     {
00468     iScreenWidth  = aWidth;
00469     iScreenHeight = aHeight;
00470     
00471     // Notify the texture manager of screen size change
00472     iTextureManager->SetScreenSize( aWidth, aHeight );
00473 
00474     // Reinitialize viewport and projection.
00475     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00476 
00477     // Recalculate the view frustrum
00478     glMatrixMode( GL_PROJECTION );
00479     glLoadIdentity();
00480     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00481     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00482                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00483                 FRUSTUM_NEAR, FRUSTUM_FAR );
00484     glMatrixMode( GL_MODELVIEW );
00485     }

© Nokia 2006

Back to top