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