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