|
S60 3rd Edition SDK for Symbian OS Example Applications Guide |
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 |