S60 3rd Edition SDK for Symbian OS
Example Applications Guide

SimpleLight.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : SimpleLight.cpp
00004 *  Part of     : OpenGLEx / SimpleLight
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 // INCLUDES
00017 #include <e32std.h>
00018 #include <e32math.h>
00019 
00020 #include "SimpleLight.h"
00021 
00022 #include "duck.h"        // Geometry, normals, and indices for the duck model
00023 #include "head.h"        // Geometry, normals, and indices for the head model
00024 
00025 // MACROS
00026 #define MATERIAL_MAX 1
00027 #define LIGHT_MAX    1
00028 
00029 #define cameraDistance 270
00030 
00031 
00032 #define MATERIALCOLOR(r, g, b, a)     \
00033        (GLfloat)(r * MATERIAL_MAX),   \
00034        (GLfloat)(g * MATERIAL_MAX),   \
00035        (GLfloat)(b * MATERIAL_MAX),   \
00036        (GLfloat)(a * MATERIAL_MAX)    
00037 
00038 #define LIGHTCOLOR(r, g, b, a)        \
00039        (GLfloat)(r * LIGHT_MAX),      \
00040        (GLfloat)(g * LIGHT_MAX),      \
00041        (GLfloat)(b * LIGHT_MAX),      \
00042        (GLfloat)(a * LIGHT_MAX)    
00043 
00044 // CONSTANTS
00045 /** Materials for the duck object. */
00046 static const GLfloat objDiffuseDuck[4]  = { MATERIALCOLOR(0.8, 0.8, 0.2, 1.0) };
00047 static const GLfloat objAmbientDuck[4]  = { MATERIALCOLOR(0.8, 0.8, 0.2, 1.0) };
00048 static const GLfloat objSpecularDuck[4] = { MATERIALCOLOR(1.0, 1.0, 1.0, 1.0) };
00049 static const GLfloat objEmissionDuck[4] = { MATERIALCOLOR(0.0, 0.0, 0.0, 1.0) };
00050 
00051 /* Materials for the head object. */
00052 static const GLfloat objDiffuseHead[4]  = { MATERIALCOLOR(0.8, 0.4, 0.0, 1.0) };
00053 static const GLfloat objAmbientHead[4]  = { MATERIALCOLOR(0.8, 0.4, 0.0, 1.0) };
00054 static const GLfloat objSpecularHead[4] = { MATERIALCOLOR(1.0, 1.0, 1.0, 1.0) };
00055 
00056 /* Global ambient light. */
00057 static const GLfloat globalAmbient[4]   = { LIGHTCOLOR(0.0, 0.0, 0.0, 1.0) };
00058 
00059 /* Lamp parameters. */
00060 static const GLfloat lightDiffuseLamp[4]   = { LIGHTCOLOR(0.7, 0.7, 0.7, 1.0) };
00061 static const GLfloat lightAmbientLamp[4]   = { LIGHTCOLOR(0.3, 0.3, 0.3, 1.0) };
00062 static const GLfloat lightPositionLamp[4]  = { 0, 10, 10, 0 };
00063 
00064 /* Spotlight parameters. */
00065 static const GLfloat lightDiffuseSpot[4]   = { LIGHTCOLOR(0.0, 0.0, 0.0, 1.0) };
00066 static const GLfloat lightAmbientSpot[4]   = { LIGHTCOLOR(0.0, 0.0, 0.0, 1.0) };
00067 static const GLfloat lightSpecularSpot[4]  = { LIGHTCOLOR(0.0, 0.0, 3.0, 1.0) };
00068 static const GLfloat lightPositionSpot[4]  = {  0, -10, -1, 0 };
00069 static const GLfloat lightDirectionSpot[4] = {  0,  10,  1, 1 };
00070 
00071 
00072 // ============================= LOCAL FUNCTIONS ===============================
00073 
00074 // -----------------------------------------------------------------------------
00075 // sin
00076 // Help function to make the duck 'quak'.
00077 // -----------------------------------------------------------------------------
00078 //
00079 GLfloat CSimpleLight::sin(GLfloat aRad)
00080     {
00081     TReal trg, src = (TReal)aRad;
00082     if ( Math::Sin(trg, src) == KErrNone )
00083         {
00084         return (GLfloat)trg;
00085         }
00086     return 0;
00087 
00088     }
00089 
00090 
00091 // ============================ MEMBER FUNCTIONS ===============================
00092 
00093 // -----------------------------------------------------------------------------
00094 // CSimpleLight::CSimpleLight
00095 // C++ default constructor can NOT contain any code, that
00096 // might leave.
00097 // -----------------------------------------------------------------------------
00098 //
00099 CSimpleLight::CSimpleLight( TUint aWidth, TUint aHeight )
00100 :iScreenWidth(aWidth), iScreenHeight(aHeight)
00101     {
00102     }
00103 
00104 // -----------------------------------------------------------------------------
00105 // CSimpleLight::ConstructL
00106 // Symbian 2nd phase constructor can leave.
00107 // -----------------------------------------------------------------------------
00108 //
00109 void CSimpleLight::ConstructL( void )
00110     {
00111     }
00112 
00113 
00114 // -----------------------------------------------------------------------------
00115 // CSimpleLight::NewL
00116 // Two-phased constructor.
00117 // -----------------------------------------------------------------------------
00118 //
00119 CSimpleLight* CSimpleLight::NewL( TUint aWidth, TUint aHeight )
00120     {
00121     /* Symbian 2-phase constructor. Calls both the default 
00122        C++ constructor and Symbian ConstructL methods */
00123     CSimpleLight* self = new (ELeave) CSimpleLight( aWidth, aHeight );
00124     CleanupStack::PushL( self );
00125     self->ConstructL();
00126     CleanupStack::Pop();
00127 
00128     return self;
00129     }
00130 
00131 
00132 // Destructor. 
00133 CSimpleLight::~CSimpleLight()
00134     {
00135     }
00136 
00137 
00138 
00139 // -----------------------------------------------------------------------------
00140 // CSimpleLight::AppInit
00141 // Initialize OpenGL ES, set the vertex and color arrays and pointers, 
00142 // and select the shading mode.
00143 // -----------------------------------------------------------------------------
00144 //
00145 void CSimpleLight::AppInit( void )
00146     {
00147       // Set the screen background color. 
00148     glClearColor( 0.f, 0.f, 0.f, 1.f );
00149 
00150     // Enable depth testing, back face culling, and lighting. 
00151     glEnable( GL_DEPTH_TEST );
00152     glEnable( GL_CULL_FACE  );
00153     glEnable( GL_LIGHTING   );
00154     /* Make OpenGL ES automatically normalize all normals after tranformations. 
00155        This is important when making irregular xforms like scaling, or if we
00156        have specified nonunit-length normals. */
00157     glEnable( GL_NORMALIZE  ); 
00158 
00159     // Initialize viewport and projection. 
00160     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00161     glMatrixMode( GL_PROJECTION );
00162 
00163     // Calculate the view frustrum
00164     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00165     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00166                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00167                 FRUSTUM_NEAR, FRUSTUM_FAR );
00168 
00169     glMatrixMode( GL_MODELVIEW );
00170 
00171     // Enable vertex and normal arrays. 
00172     glEnableClientState( GL_VERTEX_ARRAY );
00173     glEnableClientState( GL_NORMAL_ARRAY );
00174     
00175     // Set array pointers. Initially for the duck object. 
00176     glVertexPointer( 3, GL_SHORT, 0, objVertexdataDuck );
00177     glNormalPointer( GL_BYTE, 0, objNormaldataDuck     );
00178 
00179     // Set up global ambient light. 
00180     glLightModelfv( GL_LIGHT_MODEL_AMBIENT, globalAmbient );
00181 
00182     // Set up lamp. 
00183     glEnable( GL_LIGHT0 );
00184     glLightfv(  GL_LIGHT0, GL_DIFFUSE,  lightDiffuseLamp  );
00185     glLightfv(  GL_LIGHT0, GL_AMBIENT,  lightAmbientLamp  );
00186     glLightfv(  GL_LIGHT0, GL_SPECULAR, lightDiffuseLamp  );
00187     glLightfv(  GL_LIGHT0, GL_POSITION, lightPositionLamp );
00188 
00189     // Set up spot.  Initially spot is disabled. 
00190     glLightfv(  GL_LIGHT1, GL_DIFFUSE,  lightDiffuseSpot  );
00191     glLightfv(  GL_LIGHT1, GL_AMBIENT,  lightAmbientSpot  );
00192     glLightfv(  GL_LIGHT1, GL_SPECULAR, lightSpecularSpot );
00193     glLightfv(  GL_LIGHT1, GL_POSITION, lightPositionSpot );
00194 
00195     glLightf(   GL_LIGHT1, GL_CONSTANT_ATTENUATION,  1.5  );
00196     glLightf(   GL_LIGHT1, GL_LINEAR_ATTENUATION,    0.5  );
00197     glLightf(   GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.5  );
00198 
00199     glLightf(   GL_LIGHT1, GL_SPOT_CUTOFF,   17.0                );
00200     glLightf(   GL_LIGHT1, GL_SPOT_EXPONENT,  2.0                );
00201     glLightfv(  GL_LIGHT1, GL_SPOT_DIRECTION, lightDirectionSpot );
00202 
00203     // Set duck material 
00204     glMaterialfv(   GL_FRONT_AND_BACK, GL_DIFFUSE,  objDiffuseDuck      );
00205     glMaterialfv(   GL_FRONT_AND_BACK, GL_AMBIENT,  objAmbientDuck      );
00206     glMaterialfv(   GL_FRONT_AND_BACK, GL_SPECULAR, objSpecularDuck     );
00207     glMaterialfv(   GL_FRONT_AND_BACK, GL_EMISSION, objEmissionDuck     );
00208     glMaterialx( GL_FRONT_AND_BACK, GL_SHININESS,   10 << 16         );
00209 
00210     // Set shading mode
00211     glShadeModel( GL_SMOOTH ); 
00212 
00213     // Do not use perspective correction 
00214     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
00215 
00216     // Initialize menu state variables, Symbian menu stuff. 
00217     iLightingEnabled = ETrue;          // Lighting is enabled
00218     iLampEnabled     = ETrue;          // Lamp is enabled
00219     iSpotEnabled     = EFalse;         // Spot is disabled
00220     iObjectModel     = EDuckModel;     // Default model is duck
00221     }
00222 
00223 
00224 // -----------------------------------------------------------------------------
00225 // CSimpleLight::AppExit
00226 // Release any allocations made in AppInit.
00227 // -----------------------------------------------------------------------------
00228 //
00229 void CSimpleLight::AppExit( void )
00230     {
00231     }
00232 
00233 
00234 // -----------------------------------------------------------------------------
00235 // CSimpleLight::AppCycle
00236 // Draws and animates the objects
00237 // -----------------------------------------------------------------------------
00238 //
00239 void CSimpleLight::AppCycle( TInt iFrame )
00240     {
00241     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00242 
00243     glLoadIdentity();
00244 
00245     switch( iObjectModel )
00246         {
00247         case EDuckModel:
00248             {
00249             glTranslatex( 0 , -20 << 16 , -cameraDistance << 16 );
00250 
00251             glRotatex((-90 << 16) + (GLint) (sin(iFrame * 0.17f) * 15 * 65536), 
00252                       1 << 16, 0, 0);
00253             glRotatex((GLint) (sin(iFrame * 0.13f) * 10 * 65536), 0, 1 << 16, 0);
00254             glRotatex(iFrame << 16, 0, 0, 1 << 16);
00255             
00256             // Use some magic numbers to scale the duck model to fit the screen.
00257             glScalex( 3 << 6, 3 << 6, 3 << 6 );
00258             glDrawElements( GL_TRIANGLES, objFaces * 3, 
00259                             GL_UNSIGNED_BYTE, objFacedataDuck );
00260             }
00261             break;
00262         case EHeadModel:
00263             {
00264             glTranslatex( 0, 0, -cameraDistance << 16 );
00265             
00266             glRotatex(-90 << 16, 1 << 16, 0, 0);
00267             glRotatex( iFrame << 16, 5 << 16, 1 << 12, 0);
00268             glRotatex( iFrame << 16, 0, 0, 1 << 16);
00269             
00270             // Use some magic numbers to scale the head model to fit the screen. 
00271             glScalex( 1 << 10, 1 << 10, 1 << 10 );
00272             glDrawElements( GL_TRIANGLES, objFacesHead * 3, 
00273                             GL_UNSIGNED_SHORT, objFacedataHead );
00274             }
00275             break;
00276         default:
00277             // Do nothing.
00278             break;
00279         }
00280     }
00281 
00282 
00283 //----------------------------------------------------------
00284 // The following methods are called by the CSimpleLightAppUi 
00285 // class when handling the incoming menu events.
00286 //----------------------------------------------------------
00287 
00288 
00289 // -----------------------------------------------------------------------------
00290 // CSimpleLight::ToggleLighting
00291 // Enable/Disable lighting from the application menu.
00292 // -----------------------------------------------------------------------------
00293 //
00294 void CSimpleLight::ToggleLighting( void )
00295     {
00296     if ( iLightingEnabled)
00297         {
00298         iLightingEnabled = EFalse;
00299         glDisable( GL_LIGHTING );
00300         }
00301     else
00302         {
00303         iLightingEnabled = ETrue;
00304         glEnable( GL_LIGHTING );
00305         }
00306     }
00307 
00308 
00309 // -----------------------------------------------------------------------------
00310 // CSimpleLight::ToggleLamp
00311 // Enable/Disable lamp from the application menu.
00312 // -----------------------------------------------------------------------------
00313 //
00314 void CSimpleLight::ToggleLamp( void )
00315     {
00316     if ( iLampEnabled )
00317         {
00318         iLampEnabled = EFalse;
00319         glDisable( GL_LIGHT0 );
00320         }
00321     else
00322         {
00323         iLampEnabled = ETrue;
00324         glEnable( GL_LIGHT0 );
00325         }
00326     }
00327 
00328 
00329 // -----------------------------------------------------------------------------
00330 // CSimpleLight::ToggleSpot
00331 // Enable/Disable spot from the application menu.
00332 // -----------------------------------------------------------------------------
00333 //
00334 void CSimpleLight::ToggleSpot( void )
00335     {
00336     if ( iSpotEnabled )
00337         {
00338         iSpotEnabled = EFalse;
00339         glDisable( GL_LIGHT1 );
00340         }
00341     else
00342         {
00343         iSpotEnabled = ETrue;
00344         glEnable( GL_LIGHT1 );
00345         }
00346     }
00347 
00348 
00349 // -----------------------------------------------------------------------------
00350 // CSimpleLight::DuckModel
00351 // Change the current model to duck object.
00352 // -----------------------------------------------------------------------------
00353 //
00354 void CSimpleLight::DuckModel( void )
00355     {
00356     iObjectModel = EDuckModel;
00357 
00358     // Set array pointers for duck model. 
00359     glVertexPointer( 3, GL_SHORT, 0, objVertexdataDuck );
00360     glNormalPointer( GL_BYTE, 0, objNormaldataDuck );
00361     
00362     // Set duck material 
00363     glMaterialfv(   GL_FRONT_AND_BACK, GL_AMBIENT,  objAmbientDuck  );
00364     glMaterialfv(   GL_FRONT_AND_BACK, GL_DIFFUSE,  objDiffuseDuck  );
00365     glMaterialfv(   GL_FRONT_AND_BACK, GL_SPECULAR, objSpecularDuck );
00366     glMaterialx( GL_FRONT_AND_BACK, GL_SHININESS,   10 << 16     );
00367     }
00368 
00369 
00370 // -----------------------------------------------------------------------------
00371 // CSimpleLight::HeadModel
00372 // Change the current model to head object.
00373 // -----------------------------------------------------------------------------
00374 //
00375 void CSimpleLight::HeadModel( void )
00376     {
00377     iObjectModel = EHeadModel;
00378 
00379     // Set array pointers for head model. 
00380     glVertexPointer( 3, GL_SHORT, 0, objVertexdataHead );
00381     glNormalPointer( GL_BYTE, 0, objNormaldataHead );
00382 
00383     // Set head front material 
00384     glMaterialfv(   GL_FRONT_AND_BACK, GL_AMBIENT,  objAmbientHead  );
00385     glMaterialfv(   GL_FRONT_AND_BACK, GL_DIFFUSE,  objDiffuseHead  );
00386     glMaterialfv(   GL_FRONT_AND_BACK, GL_SPECULAR, objSpecularHead );
00387     glMaterialx( GL_FRONT_AND_BACK, GL_SHININESS,   12 << 16     );
00388 
00389     }
00390 
00391 
00392 // -----------------------------------------------------------------------------
00393 // CSimpleLight::SetScreenSize
00394 // Reacts to the dynamic screen size change during execution of this program.
00395 // -----------------------------------------------------------------------------
00396 //
00397 void CSimpleLight::SetScreenSize( TUint aWidth, TUint aHeight )
00398     {
00399     iScreenWidth  = aWidth;
00400     iScreenHeight = aHeight;
00401 
00402     // Reinitialize viewport and projection. 
00403     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00404 
00405     // Recalculate the view frustrum
00406     glMatrixMode( GL_PROJECTION );
00407     glLoadIdentity();
00408     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00409     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00410                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00411                 FRUSTUM_NEAR, FRUSTUM_FAR );
00412     glMatrixMode( GL_MODELVIEW );
00413     }
00414 
00415 //  End of File

© Nokia 2006

Back to top