graphicstest/uibench/s60/src/model.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #include "model.h"
       
    18 #include "geometrystructs.h"
       
    19 #include "egldefs.h"
       
    20 #include "eglerror.h"
       
    21 
       
    22 #include <e32math.h>
       
    23 
       
    24 
       
    25 const TInt KMoonPositionCount = 100;
       
    26 const TInt KSunPositionCount = 100;
       
    27 
       
    28 const TInt KSunOrbitRadius = 2000; //heliocentric
       
    29 const TInt KMoonOrbitRadius = 100;
       
    30 const TInt KModelDistanceFromCamera = 200;
       
    31 
       
    32 const TInt KMinResolution = 5;
       
    33 const TInt KMaxResolution = 50;
       
    34 const TInt KDefaultResolution = 50;
       
    35 
       
    36 const TInt KSunRadius=100;
       
    37 const TInt KPlanetRadius=50;
       
    38 const TInt KMoonRadius = 10;
       
    39 
       
    40 _LIT(KRed, "red");
       
    41 _LIT(KGreen, "green");
       
    42 _LIT(KBlue, "blue");
       
    43 _LIT(KBlack, "black");
       
    44 
       
    45 
       
    46 CModel* CModel::NewL(EGLDisplay aDisplay, EGLSurface aSurface)
       
    47     {
       
    48     TPtrC defaultColor(KBlack);
       
    49     return NewL(aDisplay, aSurface, defaultColor);
       
    50     }
       
    51 
       
    52 CModel* CModel::NewL(EGLDisplay aDisplay, EGLSurface aSurface, TPtrC aBackgroundColor)
       
    53     {
       
    54     CModel* self = new(ELeave) CModel(aDisplay, aSurface);
       
    55     CleanupStack::PushL(self);
       
    56     self->ConstructL(aBackgroundColor);
       
    57     CleanupStack::Pop(self);
       
    58     return self;
       
    59     }
       
    60 
       
    61 void CModel::PrecalculateOrbitL(TInt aOrbitingDistance, RArray<Vertex3F>& aVertices, TInt aPositionCount, TReal aAngle)
       
    62     {
       
    63     //fghCircleTable allocates for sin and cos tables, 
       
    64     //so we must not fail to append vertices to the array,
       
    65     //so we must reserve all the space we need.
       
    66     aVertices.ReserveL(aPositionCount);
       
    67     //precalculate the positions of the sun
       
    68     TReal32 *sint1,*cost1;
       
    69     User::LeaveIfError(fghCircleTable(&sint1,&cost1, aPositionCount));
       
    70     
       
    71     TReal radians = aAngle*(KPi/180);
       
    72     TReal32 cosA = cos(radians);
       
    73     TReal32 sinA = sin(radians);
       
    74     
       
    75     TReal32 x,y = 0;
       
    76     TReal32 cosCalc = aOrbitingDistance * cosA;
       
    77     TReal32 sinCalc = aOrbitingDistance * sinA;
       
    78     for(TInt i = 0; i < aPositionCount;  i++)
       
    79         {
       
    80         x = cost1[i] * cosCalc;
       
    81         y = cost1[i] * sinCalc;
       
    82 
       
    83         Vertex3F v(x,y, sint1[i]*aOrbitingDistance);
       
    84         User::LeaveIfError(aVertices.Append(v));
       
    85         }
       
    86     delete[] sint1;
       
    87     delete[] cost1;
       
    88     }
       
    89 
       
    90 void CModel::ConstructL(TPtrC aBackgroundColor)
       
    91     {
       
    92     iResolution=KDefaultResolution;
       
    93 
       
    94     CSolidSphere* newSun = CSolidSphere::NewLC(KSunRadius, iResolution, iResolution);
       
    95     CSolidSphere* newPlanet = CSolidSphere::NewLC(KPlanetRadius, iResolution, iResolution);
       
    96     CSolidSphere* newMoon = CSolidSphere::NewLC(KMoonRadius, iResolution, iResolution);
       
    97     SetShapes(newSun, newPlanet, newMoon);
       
    98     CleanupStack::Pop(3, newSun);
       
    99     
       
   100     PrecalculateOrbitL(KSunOrbitRadius, iSunPositions, KSunPositionCount, 135);
       
   101     PrecalculateOrbitL(KMoonOrbitRadius, iMoonPositions, KMoonPositionCount, 23.5);
       
   102     if(aBackgroundColor == KRed)
       
   103         {
       
   104         iBackgroundColor[ERed] = 0.5;
       
   105         }
       
   106     else if (aBackgroundColor == KGreen)
       
   107         {
       
   108         iBackgroundColor[EGreen] = 0.5;
       
   109         }
       
   110     else if (aBackgroundColor == KBlue)
       
   111         {
       
   112         iBackgroundColor[EBlue] = 0.5;
       
   113         }
       
   114     }
       
   115 
       
   116 CModel::CModel(EGLDisplay aDisplay, EGLSurface aSurface)
       
   117     :iDisplay(aDisplay), iSurface(aSurface)
       
   118     {
       
   119     }
       
   120 
       
   121 CModel::~CModel()
       
   122     {
       
   123     delete iSun;
       
   124     delete iPlanet;
       
   125     delete iMoon;
       
   126     iSunPositions.Close();
       
   127     iMoonPositions.Close();
       
   128     }
       
   129 
       
   130 void CModel::SetShapes(CSolidSphere* aSun, CSolidSphere* aPlanet, CSolidSphere* aMoon)
       
   131     {
       
   132     delete iSun;
       
   133     iSun = aSun;
       
   134     
       
   135     delete iPlanet;
       
   136     iPlanet = aPlanet;
       
   137     
       
   138     delete iMoon;
       
   139     iMoon = aMoon;
       
   140     }
       
   141 
       
   142 void CModel::DrawToBuffer(TInt aTime) const
       
   143     {
       
   144     InitialiseFrame();
       
   145     DrawModelData(aTime);
       
   146     }
       
   147 
       
   148 void CModel::InitialiseFrame() const
       
   149     {
       
   150     glEnable(GL_CULL_FACE);
       
   151     glEnable(GL_DEPTH_TEST); 
       
   152     glEnable(GL_COLOR_ARRAY);
       
   153     glEnable(GL_LIGHTING);
       
   154     glEnable(GL_LIGHT0);
       
   155     glEnableClientState(GL_VERTEX_ARRAY);
       
   156     glEnableClientState(GL_NORMAL_ARRAY);
       
   157     
       
   158     glClearColor(iBackgroundColor[ERed], iBackgroundColor[EGreen], iBackgroundColor[EBlue], iBackgroundColor[EAlpha]); 
       
   159     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
       
   160     
       
   161     glCullFace(GL_FRONT);   
       
   162     glShadeModel (GL_SMOOTH);
       
   163 
       
   164     // Set the projection parameters
       
   165     glMatrixMode(GL_PROJECTION);
       
   166     glLoadIdentity();
       
   167     
       
   168     EGLint height;
       
   169     if(!eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &height))
       
   170         {
       
   171         ProcessEglError();
       
   172         }
       
   173     EGLint width;
       
   174         if(!eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &width))
       
   175             {
       
   176             ProcessEglError();
       
   177             }
       
   178         
       
   179     GLfloat widthf = width;
       
   180     GLfloat heightf = height;
       
   181     GLfloat aspectRatio = widthf/heightf;
       
   182     glFrustumf( -(aspectRatio*KFrustumHeight), (aspectRatio*KFrustumHeight), 
       
   183                 -KFrustumHeight, KFrustumHeight, 
       
   184                 KFrustumNear, KFrustumFar);
       
   185     }
       
   186 
       
   187 void CModel::DrawModelData(TInt aTime) const
       
   188     {
       
   189     //draw a light source where the sun is
       
   190     glMatrixMode(GL_MODELVIEW);
       
   191     glLoadIdentity();
       
   192     GLfloat sun_color[] = { 1.0, 1.0, 0.5333, 1 };
       
   193     Vertex3F vSun = iSunPositions[aTime%KSunPositionCount];
       
   194     vSun.iZ-=KModelDistanceFromCamera;
       
   195     GLfloat light0position[] = {vSun.iX, vSun.iY, vSun.iZ, 1.0 };
       
   196     glLightfv(GL_LIGHT0, GL_POSITION, light0position);
       
   197     glLightfv(GL_LIGHT0, GL_SPECULAR, sun_color);  
       
   198     
       
   199     //draw the sun
       
   200     glMatrixMode(GL_MODELVIEW);
       
   201     glLoadIdentity();
       
   202     //this is obviously wrong: I don't understand why the z-coord for the 
       
   203     //sun needs to be the negation of the z-coord for the light source position,
       
   204     //in order for the light to appear to come from the sun!
       
   205     glTranslatef(vSun.iX, vSun.iY, -vSun.iZ);
       
   206         
       
   207     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, sun_color);
       
   208         
       
   209     iSun->Draw();
       
   210     //draw the planet
       
   211     glMatrixMode(GL_MODELVIEW);
       
   212     glLoadIdentity();
       
   213     glTranslatef(0, 0, -KModelDistanceFromCamera);
       
   214     
       
   215     GLfloat mat_planet_color[] = { 0.459, 0.679, 0.8, 1 };
       
   216     GLfloat mat_planet_shininess[] = { 30.0 };
       
   217     GLfloat mat_no_emission[] = {0, 0, 0, 0};
       
   218 
       
   219     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_planet_color);
       
   220     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_planet_color);
       
   221     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_planet_color);
       
   222     glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_planet_shininess);
       
   223     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_no_emission);
       
   224     iPlanet->Draw();
       
   225     
       
   226     //draw the moon
       
   227     glMatrixMode(GL_MODELVIEW);
       
   228     glLoadIdentity();
       
   229     Vertex3F vMoon = iMoonPositions[aTime%KMoonPositionCount];
       
   230     vMoon.iZ-=KModelDistanceFromCamera;
       
   231     glTranslatef(vMoon.iX, vMoon.iY, vMoon.iZ);
       
   232     
       
   233     GLfloat mat_moon_specular[] = { 0.5, 0.5, 0.5, 1.0 };
       
   234     GLfloat mat_moon_shininess[] = { 500.0 };
       
   235     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_moon_specular);
       
   236     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_moon_specular);
       
   237     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_moon_specular);
       
   238     glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_moon_shininess);  
       
   239     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_no_emission);
       
   240     
       
   241     iMoon->Draw();
       
   242     }
       
   243 
       
   244 void CModel::SetResolutionL(TInt aResolution)
       
   245     {
       
   246     aResolution *= 5;
       
   247     if(aResolution > KMaxResolution)
       
   248         {
       
   249         aResolution = KMaxResolution;
       
   250         }
       
   251     if(aResolution < KMinResolution)
       
   252         {
       
   253         aResolution = KMinResolution;
       
   254         }
       
   255     iResolution = aResolution;
       
   256     CSolidSphere* newSun = CSolidSphere::NewLC(KSunRadius, iResolution, iResolution);
       
   257     CSolidSphere* newPlanet = CSolidSphere::NewLC(KPlanetRadius, iResolution, iResolution);
       
   258     CSolidSphere* newMoon = CSolidSphere::NewLC(KMoonRadius, iResolution, iResolution);
       
   259     SetShapes(newSun, newPlanet, newMoon);  
       
   260     CleanupStack::Pop(3, newSun);
       
   261     }
       
   262