S60 3rd Edition SDK for Symbian OS
Example Applications Guide

Hierarchy.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : Hierarchy.cpp
00004 *  Part of     : OpenGLEx / Hierarchy
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 <e32std.h>
00018 #include "Hierarchy.h"
00019 
00020 // EXTERNAL DATA STRUCTURES
00021 
00022 // EXTERNAL FUNCTION PROTOTYPES  
00023 
00024 // CONSTANTS
00025 
00026 // MACROS
00027 
00028 // LOCAL CONSTANTS AND MACROS
00029 
00030 #define cameraDistance 150.0
00031 
00032 /**
00033  * Vertice coordinates for the cube.
00034  * This is used to draw every part of the robot hand.
00035  */
00036 static const GLbyte vertices[8 * 3] =
00037     {
00038      -1,  1,  1,
00039       1,  1,  1,
00040       1, -1,  1,
00041      -1, -1,  1,
00042 
00043      -1,  1, -1,
00044       1,  1, -1,
00045       1, -1, -1,
00046      -1, -1, -1
00047     };
00048 
00049 /**
00050  * Indices for drawing the triangles.
00051  */
00052 static const GLubyte triangles[12 * 3] =
00053     {
00054     /* front */
00055      1,0,3,
00056      1,3,2,
00057 
00058      /* right */
00059      2,6,5,
00060      2,5,1,
00061 
00062      /* back */
00063      7,4,5,
00064      7,5,6,
00065 
00066      /* left */
00067      0,4,7,
00068      0,7,3,
00069 
00070      /* top */
00071      5,4,0,
00072      5,0,1,
00073 
00074      /* bottom */
00075      3,7,6,
00076      3,6,2
00077     };
00078 
00079 
00080 /** Colors for the first arm part of the robot's hand. */
00081 static const GLubyte colorArm1[8 * 4] =
00082     {
00083     /* Dark gray */
00084     150, 150, 150,255,
00085     150, 150, 150,255,
00086     150, 150, 150,255,
00087     150, 150, 150,255,
00088 
00089     150, 150, 150,255,
00090     150, 150, 150,255,
00091     150, 150, 150,255,
00092     150, 150, 150,255
00093     };
00094 
00095 /** Colors for the second arm part of the robot's hand. */
00096 static const GLubyte colorArm2[8 * 4] =
00097     {
00098     /* Light gray */
00099     200, 200, 200,255,
00100     200, 200, 200,255,
00101     200, 200, 200,255,
00102     200, 200, 200,255,
00103     
00104     200, 200, 200,255,
00105     200, 200, 200,255,
00106     200, 200, 200,255,
00107     200, 200, 200,255
00108     };
00109 
00110 /** Colors for the first finger on the robot's hand. */
00111 static const GLubyte colorFinger1[8 * 4] = 
00112     {
00113     /* Red */
00114     255,   0,   0,255,
00115     255,   0,   0,255,
00116     255,   0,   0,255,
00117     255,   0,   0,255,
00118     
00119     255,   0,   0,255,
00120     255,   0,   0,255,
00121     255,   0,   0,255,
00122     255,   0,   0,255
00123     };
00124 
00125 /** Colors for the second finger on the robot's hand. */
00126 static const GLubyte colorFinger2[8 * 4] = 
00127     {
00128     /* White */
00129     255, 255, 255,255,
00130     255, 255, 255,255,
00131     255, 255, 255,255,
00132     255, 255, 255,255,
00133     
00134     255, 255, 255,255,
00135     255, 255, 255,255,
00136     255, 255, 255,255,
00137     255, 255, 255,255
00138     };
00139 
00140 
00141 /**
00142  * Used to create a helper, which simply draws the coordinate system.
00143  * This is very useful if your transformations are not correct.
00144  * Kind of graphical debugging.
00145  */
00146 static const GLubyte axisInd[3 * 2] = 
00147     {
00148     0,1,
00149     0,2,
00150     0,3
00151     };
00152 
00153 // ============================ MEMBER FUNCTIONS ===============================
00154 
00155 // -----------------------------------------------------------------------------
00156 // CHierarchy::CHierarchy
00157 // C++ default constructor can NOT contain any code, that
00158 // might leave.
00159 // -----------------------------------------------------------------------------
00160 //
00161 CHierarchy::CHierarchy( TUint aWidth, TUint aHeight )
00162 :iScreenWidth(aWidth), iScreenHeight(aHeight)
00163     {
00164     }
00165 
00166 
00167 // -----------------------------------------------------------------------------
00168 // CHierarchy::ConstructL
00169 // Symbian 2nd phase constructor can leave.
00170 // -----------------------------------------------------------------------------
00171 //
00172 void CHierarchy::ConstructL( void )
00173     {
00174     }
00175 
00176 
00177 // -----------------------------------------------------------------------------
00178 // CHierarchy::NewL
00179 // Two-phased constructor.
00180 // -----------------------------------------------------------------------------
00181 //
00182 CHierarchy* CHierarchy::NewL( TUint aWidth, TUint aHeight )
00183     {
00184     /* Symbian 2-phase constructor. Calls both the default 
00185        C++ constructor and Symbian ConstructL methods */
00186     CHierarchy* self = new (ELeave) CHierarchy( aWidth, aHeight );
00187     CleanupStack::PushL( self );
00188     self->ConstructL();
00189     CleanupStack::Pop();
00190 
00191     return self;
00192     }
00193 
00194 
00195 // Destructor. 
00196 CHierarchy::~CHierarchy()
00197     {
00198     }
00199 
00200 
00201 // -----------------------------------------------------------------------------
00202 // CHierarchy::AppInit
00203 // Initialize OpenGL ES, set the vertex and color arrays and pointers, 
00204 // and select the shading mode.
00205 // -----------------------------------------------------------------------------
00206 //
00207 void CHierarchy::AppInit( void )
00208     {
00209     /* Set the screen background color. */
00210     glClearColor( 0.f, 0.f, 0.f, 1.f );
00211 
00212     /* Enable depth test and back face culling. */
00213     glEnable( GL_DEPTH_TEST );
00214     glEnable( GL_CULL_FACE  );
00215 
00216     /* Initialize viewport and projection. */
00217     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00218     glMatrixMode( GL_PROJECTION );
00219 
00220     // Calculate the view frustrum
00221     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00222     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00223                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00224                 FRUSTUM_NEAR, FRUSTUM_FAR );
00225 
00226     glMatrixMode( GL_MODELVIEW );
00227 
00228     /* Enable vertex and color arrays. */
00229     glEnableClientState( GL_VERTEX_ARRAY );
00230     glEnableClientState( GL_COLOR_ARRAY );
00231 
00232     /* Set the initial shading mode */
00233     glShadeModel( GL_FLAT ); 
00234 
00235     /* Do not use perspective correction */
00236     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
00237 
00238     /* Rotate mode switch */
00239     iRotateMode      = ROTATE_ELBOW;
00240     iElbowRotAngle   = 0.0;
00241     iFingersRotAngle = 0.0;
00242     iRotateUpEnabled        = EFalse;
00243     iRotateDownEnabled      = EFalse;
00244     }
00245 
00246 
00247 // -----------------------------------------------------------------------------
00248 // CHierarchy::AppExit
00249 // Release any allocations made in AppInit.
00250 // -----------------------------------------------------------------------------
00251 //
00252 void CHierarchy::AppExit( void )
00253     {
00254     }
00255 
00256 
00257 // -----------------------------------------------------------------------------
00258 // CHierarchy::DrawCoordSystem
00259 // -----------------------------------------------------------------------------
00260 //
00261 void CHierarchy::DrawCoordSystem( void )
00262     {
00263     glDrawElements( GL_LINES, 3 * 2, GL_UNSIGNED_BYTE, axisInd );
00264     }
00265 
00266 // -----------------------------------------------------------------------------
00267 // CHierarchy::DrawBox
00268 // Draw a box. Used to draw every part of the robot hand.
00269 // -----------------------------------------------------------------------------
00270 //
00271 void CHierarchy::DrawBox( void )
00272     {
00273     glDrawElements( GL_TRIANGLES, 12 * 3, GL_UNSIGNED_BYTE, triangles );
00274     }
00275 
00276 
00277 // -----------------------------------------------------------------------------
00278 // CHierarchy::AppCycle
00279 // Draws and animates the objects
00280 // -----------------------------------------------------------------------------
00281 //
00282 void CHierarchy::AppCycle( TInt /*aFrame*/ )
00283     {
00284     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00285 
00286     glLoadIdentity();
00287 
00288     /* Update rotate angles*/
00289     if ( iRotateUpEnabled )
00290         {
00291         if ( iRotateMode == ROTATE_ELBOW )
00292             {
00293             iElbowRotAngle += 1.0;
00294             if ( iElbowRotAngle > 90.0 ) 
00295                 {
00296                 iElbowRotAngle = 90.0;
00297                 }
00298             }
00299         else if ( iRotateMode == ROTATE_FINGERS ) 
00300             {
00301             iFingersRotAngle += 1.0;
00302             if ( iFingersRotAngle > 80.0 )
00303                 {
00304                 iFingersRotAngle = 80.0;
00305                 }
00306             }
00307         }
00308     
00309     if ( iRotateDownEnabled )
00310         {
00311         if ( iRotateMode == ROTATE_ELBOW )
00312             {
00313             iElbowRotAngle -= 1.0;
00314             if ( iElbowRotAngle < 0.0 )
00315                 {
00316                 iElbowRotAngle = 0.0;
00317                 }
00318             }
00319         else if ( iRotateMode == ROTATE_FINGERS )
00320             {
00321             iFingersRotAngle -= 1.0;
00322             if ( iFingersRotAngle < 0.0 )
00323                 {
00324                 iFingersRotAngle = 0.0;
00325                 }
00326             }
00327         }
00328     
00329     // Move Camera 
00330     glTranslatef( -40.0 , -10.0 , -cameraDistance );
00331     glRotatef(   10., 1., 0., 0. );
00332     glRotatef( -100., 0., 1., 0. );
00333     glRotatef(   60., 0., 0., 1. );
00334 
00335     // Draw Arm
00336     glVertexPointer( 3, GL_BYTE, 0, vertices );
00337     glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArm1 );
00338     glTranslatef( 0.0, 0.0, -30.0 );
00339     glPushMatrix();
00340     glScalef( 6.0, 6.0, 15.0 );
00341     glTranslatef( 0.0, 0.0, 1.0 );
00342     DrawBox();
00343     glPopMatrix();
00344 
00345     // Draw Hand 
00346     glVertexPointer( 3, GL_BYTE, 0, vertices );
00347     glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArm2 );
00348     glTranslatef( 6.0, 0.0, 0.0 );   // move coordisystem back to middle
00349     glRotatef( -iElbowRotAngle, 0.0, 1.0, 0.0 ); // rotate object
00350     glTranslatef( -6.0, 0.0, 0.0 );  // move coordsystem to top of the box
00351     glTranslatef( 0.0, 0.0, -30.0 ); // Move origin to the other end of cube
00352     glPushMatrix();
00353     glScalef( 6.0, 6.0, 15. );       // Scale the vertices
00354     glTranslatef( 0.0, 0.0, 1.0 );   // Translate origin to the side of the cube
00355     DrawBox();
00356     glPopMatrix();
00357 
00358     // Draw upper finger 
00359     glPushMatrix(); // Store the current matrix because we have to draw
00360                        // another finger to the same joint, i.e., arm 2. joint
00361 
00362     // Red part 
00363     glVertexPointer( 3, GL_BYTE, 0, vertices );
00364     glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorFinger1 );
00365     glTranslatef( 4.5, 0.0, 0.0 );   // move origin near the top of the arm 2. joint
00366     glTranslatef( 1.5, 0.0, 0.0 );   // move origin to the edge of the finger
00367     glRotatef( float(-10.0 - iFingersRotAngle), 0.0, 1.0, 0.0 ); // rotate 1st joint
00368     glTranslatef( -1.5, 0.0, 0.0 );  // move origin to the middle of finger
00369     glTranslatef( 0.0, 0.0, -10.0 ); // move origin to the other end if box
00370     glPushMatrix();
00371     glScalef( 1.5, 1.5, 5. );
00372     glTranslatef( 0.0, 0.0, 1.0 );
00373     DrawBox();
00374     glPopMatrix();
00375 
00376     // White part 
00377     glVertexPointer( 3, GL_BYTE, 0, vertices );
00378     glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorFinger2 );
00379     glTranslatef( -1.5, 0.0, 0.0 );
00380     glRotatef( float(80.0 - iFingersRotAngle), 0.0, 1.0, 0.0 );
00381     glTranslatef( 1.5, 0.0, 0.0 );
00382     glTranslatef( 0.0, 0.0, -6.0 );
00383     glPushMatrix();
00384     glScalef( 1.5, 1.5, 3. );
00385     glTranslatef( 0.0, 0.0, 1.0 );
00386     DrawBox();
00387     glPopMatrix();
00388 
00389     glPopMatrix(); // Pop back to the 'old' matrix in order to draw the second finger
00390 
00391     // Draw lower finger 
00392     glPushMatrix();
00393 
00394     // Red part 
00395     glVertexPointer( 3, GL_BYTE, 0, vertices );
00396     glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorFinger1 );
00397     glTranslatef( -4.5, 0.0, 0.0 );  // move origin near the bottom of the arm 2. joint
00398     glTranslatef( -1.5, 0.0, 0.0 );  // move origin to the edge of the finger
00399     glRotatef( float(10.0 + iFingersRotAngle), 0.0, 1.0, 0.0 ); // rotate 1st joint
00400     glTranslatef( 1.5, 0.0, 0.0 );   // move origin to the middle of finger
00401     glTranslatef( 0.0, 0.0, -10.0 ); // move origin to the other end if box
00402     glPushMatrix();
00403     glScalef( 1.5, 1.5, 5. );
00404     glTranslatef( 0.0, 0.0, 1.0 );
00405     DrawBox();
00406     glPopMatrix();
00407 
00408     // White part 
00409     glVertexPointer( 3, GL_BYTE, 0, vertices );
00410     glColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorFinger2 );
00411     glTranslatef( 1.5, 0.0, 0.0 );
00412     glRotatef( float(-80.0 + iFingersRotAngle), 0.0, 1.0, 0.0 );
00413     glTranslatef( -1.5, 0.0, 0.0 );
00414     glTranslatef( 0.0, 0.0, -6.0 );
00415     glPushMatrix();
00416     glScalef( 1.5, 1.5, 3. );
00417     glTranslatef( 0.0, 0.0, 1.0 );
00418     DrawBox();
00419     glPopMatrix();
00420 
00421     glPopMatrix();
00422 
00423 
00424     }
00425 
00426 
00427 //----------------------------------------------------------
00428 // The following methods are called by the CHierarchyAppUi 
00429 // class when handling the incoming key events.
00430 //----------------------------------------------------------
00431 
00432 // -----------------------------------------------------------------------------
00433 // CHierarchy::SwitchRotateMode
00434 // Switch the rotation mode between rotating the arm or fingers
00435 // -----------------------------------------------------------------------------
00436 //
00437 void CHierarchy::SwitchRotateMode( void )
00438     {
00439     if ( iRotateMode == ROTATE_ELBOW )
00440         {
00441         iRotateMode = ROTATE_FINGERS;
00442         }
00443     else
00444         {
00445         iRotateMode = ROTATE_ELBOW;
00446         }
00447     }
00448 
00449 // -----------------------------------------------------------------------------
00450 // CHierarchy::RotateObjectUp
00451 // Rotates object up
00452 // -----------------------------------------------------------------------------
00453 //
00454 void CHierarchy::RotateObjectUp( TBool aStart )
00455     {
00456     if( aStart )
00457         {
00458         iRotateUpEnabled = ETrue;
00459         iRotateDownEnabled = EFalse;
00460         } else
00461         {
00462         iRotateUpEnabled = EFalse;
00463         }
00464     }
00465 
00466 // -----------------------------------------------------------------------------
00467 // CHierarchy::RotateObjectDown
00468 // Rotates object down
00469 // -----------------------------------------------------------------------------
00470 //
00471 void CHierarchy::RotateObjectDown( TBool aStart )
00472     {
00473     if( aStart )
00474         {
00475         iRotateDownEnabled = ETrue;
00476         iRotateUpEnabled = EFalse;
00477         } else
00478         {
00479         iRotateDownEnabled = EFalse;
00480         }
00481     }
00482 
00483 // -----------------------------------------------------------------------------
00484 // CHierarchy::SetScreenSize
00485 // Reacts to the dynamic screen size change during execution of this program.
00486 // -----------------------------------------------------------------------------
00487 //
00488 void CHierarchy::SetScreenSize( TUint aWidth, TUint aHeight )
00489     {
00490     iScreenWidth  = aWidth;
00491     iScreenHeight = aHeight;
00492     
00493     // Reinitialize viewport and projection.
00494     glViewport( 0, 0, iScreenWidth, iScreenHeight );
00495 
00496     // Recalculate the view frustrum
00497     glMatrixMode( GL_PROJECTION );
00498     glLoadIdentity();
00499     GLfloat aspectRatio = (GLfloat)(iScreenWidth) / (GLfloat)(iScreenHeight);
00500     glFrustumf( FRUSTUM_LEFT * aspectRatio, FRUSTUM_RIGHT * aspectRatio,
00501                 FRUSTUM_BOTTOM, FRUSTUM_TOP,
00502                 FRUSTUM_NEAR, FRUSTUM_FAR );
00503     glMatrixMode( GL_MODELVIEW );
00504     }
00505 
00506 // End of File
00507 

© Nokia 2006

Back to top