os/graphics/graphicstest/uibench/s60/src/model.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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