os/graphics/graphicstest/uibench/s60/src/model.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicstest/uibench/s60/src/model.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,262 @@
     1.4 +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +
    1.20 +#include "model.h"
    1.21 +#include "geometrystructs.h"
    1.22 +#include "egldefs.h"
    1.23 +#include "eglerror.h"
    1.24 +
    1.25 +#include <e32math.h>
    1.26 +
    1.27 +
    1.28 +const TInt KMoonPositionCount = 100;
    1.29 +const TInt KSunPositionCount = 100;
    1.30 +
    1.31 +const TInt KSunOrbitRadius = 2000; //heliocentric
    1.32 +const TInt KMoonOrbitRadius = 100;
    1.33 +const TInt KModelDistanceFromCamera = 200;
    1.34 +
    1.35 +const TInt KMinResolution = 5;
    1.36 +const TInt KMaxResolution = 50;
    1.37 +const TInt KDefaultResolution = 50;
    1.38 +
    1.39 +const TInt KSunRadius=100;
    1.40 +const TInt KPlanetRadius=50;
    1.41 +const TInt KMoonRadius = 10;
    1.42 +
    1.43 +_LIT(KRed, "red");
    1.44 +_LIT(KGreen, "green");
    1.45 +_LIT(KBlue, "blue");
    1.46 +_LIT(KBlack, "black");
    1.47 +
    1.48 +
    1.49 +CModel* CModel::NewL(EGLDisplay aDisplay, EGLSurface aSurface)
    1.50 +    {
    1.51 +    TPtrC defaultColor(KBlack);
    1.52 +    return NewL(aDisplay, aSurface, defaultColor);
    1.53 +    }
    1.54 +
    1.55 +CModel* CModel::NewL(EGLDisplay aDisplay, EGLSurface aSurface, TPtrC aBackgroundColor)
    1.56 +    {
    1.57 +    CModel* self = new(ELeave) CModel(aDisplay, aSurface);
    1.58 +    CleanupStack::PushL(self);
    1.59 +    self->ConstructL(aBackgroundColor);
    1.60 +    CleanupStack::Pop(self);
    1.61 +    return self;
    1.62 +    }
    1.63 +
    1.64 +void CModel::PrecalculateOrbitL(TInt aOrbitingDistance, RArray<Vertex3F>& aVertices, TInt aPositionCount, TReal aAngle)
    1.65 +    {
    1.66 +    //fghCircleTable allocates for sin and cos tables, 
    1.67 +    //so we must not fail to append vertices to the array,
    1.68 +    //so we must reserve all the space we need.
    1.69 +    aVertices.ReserveL(aPositionCount);
    1.70 +    //precalculate the positions of the sun
    1.71 +    TReal32 *sint1,*cost1;
    1.72 +    User::LeaveIfError(fghCircleTable(&sint1,&cost1, aPositionCount));
    1.73 +    
    1.74 +    TReal radians = aAngle*(KPi/180);
    1.75 +    TReal32 cosA = cos(radians);
    1.76 +    TReal32 sinA = sin(radians);
    1.77 +    
    1.78 +    TReal32 x,y = 0;
    1.79 +    TReal32 cosCalc = aOrbitingDistance * cosA;
    1.80 +    TReal32 sinCalc = aOrbitingDistance * sinA;
    1.81 +    for(TInt i = 0; i < aPositionCount;  i++)
    1.82 +        {
    1.83 +        x = cost1[i] * cosCalc;
    1.84 +        y = cost1[i] * sinCalc;
    1.85 +
    1.86 +        Vertex3F v(x,y, sint1[i]*aOrbitingDistance);
    1.87 +        User::LeaveIfError(aVertices.Append(v));
    1.88 +        }
    1.89 +    delete[] sint1;
    1.90 +    delete[] cost1;
    1.91 +    }
    1.92 +
    1.93 +void CModel::ConstructL(TPtrC aBackgroundColor)
    1.94 +    {
    1.95 +    iResolution=KDefaultResolution;
    1.96 +
    1.97 +    CSolidSphere* newSun = CSolidSphere::NewLC(KSunRadius, iResolution, iResolution);
    1.98 +    CSolidSphere* newPlanet = CSolidSphere::NewLC(KPlanetRadius, iResolution, iResolution);
    1.99 +    CSolidSphere* newMoon = CSolidSphere::NewLC(KMoonRadius, iResolution, iResolution);
   1.100 +    SetShapes(newSun, newPlanet, newMoon);
   1.101 +    CleanupStack::Pop(3, newSun);
   1.102 +    
   1.103 +    PrecalculateOrbitL(KSunOrbitRadius, iSunPositions, KSunPositionCount, 135);
   1.104 +    PrecalculateOrbitL(KMoonOrbitRadius, iMoonPositions, KMoonPositionCount, 23.5);
   1.105 +    if(aBackgroundColor == KRed)
   1.106 +        {
   1.107 +        iBackgroundColor[ERed] = 0.5;
   1.108 +        }
   1.109 +    else if (aBackgroundColor == KGreen)
   1.110 +        {
   1.111 +        iBackgroundColor[EGreen] = 0.5;
   1.112 +        }
   1.113 +    else if (aBackgroundColor == KBlue)
   1.114 +        {
   1.115 +        iBackgroundColor[EBlue] = 0.5;
   1.116 +        }
   1.117 +    }
   1.118 +
   1.119 +CModel::CModel(EGLDisplay aDisplay, EGLSurface aSurface)
   1.120 +    :iDisplay(aDisplay), iSurface(aSurface)
   1.121 +    {
   1.122 +    }
   1.123 +
   1.124 +CModel::~CModel()
   1.125 +    {
   1.126 +    delete iSun;
   1.127 +    delete iPlanet;
   1.128 +    delete iMoon;
   1.129 +    iSunPositions.Close();
   1.130 +    iMoonPositions.Close();
   1.131 +    }
   1.132 +
   1.133 +void CModel::SetShapes(CSolidSphere* aSun, CSolidSphere* aPlanet, CSolidSphere* aMoon)
   1.134 +    {
   1.135 +    delete iSun;
   1.136 +    iSun = aSun;
   1.137 +    
   1.138 +    delete iPlanet;
   1.139 +    iPlanet = aPlanet;
   1.140 +    
   1.141 +    delete iMoon;
   1.142 +    iMoon = aMoon;
   1.143 +    }
   1.144 +
   1.145 +void CModel::DrawToBuffer(TInt aTime) const
   1.146 +    {
   1.147 +    InitialiseFrame();
   1.148 +    DrawModelData(aTime);
   1.149 +    }
   1.150 +
   1.151 +void CModel::InitialiseFrame() const
   1.152 +    {
   1.153 +    glEnable(GL_CULL_FACE);
   1.154 +    glEnable(GL_DEPTH_TEST); 
   1.155 +    glEnable(GL_COLOR_ARRAY);
   1.156 +    glEnable(GL_LIGHTING);
   1.157 +    glEnable(GL_LIGHT0);
   1.158 +    glEnableClientState(GL_VERTEX_ARRAY);
   1.159 +    glEnableClientState(GL_NORMAL_ARRAY);
   1.160 +    
   1.161 +    glClearColor(iBackgroundColor[ERed], iBackgroundColor[EGreen], iBackgroundColor[EBlue], iBackgroundColor[EAlpha]); 
   1.162 +    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
   1.163 +    
   1.164 +    glCullFace(GL_FRONT);   
   1.165 +    glShadeModel (GL_SMOOTH);
   1.166 +
   1.167 +    // Set the projection parameters
   1.168 +    glMatrixMode(GL_PROJECTION);
   1.169 +    glLoadIdentity();
   1.170 +    
   1.171 +    EGLint height;
   1.172 +    if(!eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &height))
   1.173 +        {
   1.174 +        ProcessEglError();
   1.175 +        }
   1.176 +    EGLint width;
   1.177 +        if(!eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &width))
   1.178 +            {
   1.179 +            ProcessEglError();
   1.180 +            }
   1.181 +        
   1.182 +    GLfloat widthf = width;
   1.183 +    GLfloat heightf = height;
   1.184 +    GLfloat aspectRatio = widthf/heightf;
   1.185 +    glFrustumf( -(aspectRatio*KFrustumHeight), (aspectRatio*KFrustumHeight), 
   1.186 +                -KFrustumHeight, KFrustumHeight, 
   1.187 +                KFrustumNear, KFrustumFar);
   1.188 +    }
   1.189 +
   1.190 +void CModel::DrawModelData(TInt aTime) const
   1.191 +    {
   1.192 +    //draw a light source where the sun is
   1.193 +    glMatrixMode(GL_MODELVIEW);
   1.194 +    glLoadIdentity();
   1.195 +    GLfloat sun_color[] = { 1.0, 1.0, 0.5333, 1 };
   1.196 +    Vertex3F vSun = iSunPositions[aTime%KSunPositionCount];
   1.197 +    vSun.iZ-=KModelDistanceFromCamera;
   1.198 +    GLfloat light0position[] = {vSun.iX, vSun.iY, vSun.iZ, 1.0 };
   1.199 +    glLightfv(GL_LIGHT0, GL_POSITION, light0position);
   1.200 +    glLightfv(GL_LIGHT0, GL_SPECULAR, sun_color);  
   1.201 +    
   1.202 +    //draw the sun
   1.203 +    glMatrixMode(GL_MODELVIEW);
   1.204 +    glLoadIdentity();
   1.205 +    //this is obviously wrong: I don't understand why the z-coord for the 
   1.206 +    //sun needs to be the negation of the z-coord for the light source position,
   1.207 +    //in order for the light to appear to come from the sun!
   1.208 +    glTranslatef(vSun.iX, vSun.iY, -vSun.iZ);
   1.209 +        
   1.210 +    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, sun_color);
   1.211 +        
   1.212 +    iSun->Draw();
   1.213 +    //draw the planet
   1.214 +    glMatrixMode(GL_MODELVIEW);
   1.215 +    glLoadIdentity();
   1.216 +    glTranslatef(0, 0, -KModelDistanceFromCamera);
   1.217 +    
   1.218 +    GLfloat mat_planet_color[] = { 0.459, 0.679, 0.8, 1 };
   1.219 +    GLfloat mat_planet_shininess[] = { 30.0 };
   1.220 +    GLfloat mat_no_emission[] = {0, 0, 0, 0};
   1.221 +
   1.222 +    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_planet_color);
   1.223 +    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_planet_color);
   1.224 +    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_planet_color);
   1.225 +    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_planet_shininess);
   1.226 +    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_no_emission);
   1.227 +    iPlanet->Draw();
   1.228 +    
   1.229 +    //draw the moon
   1.230 +    glMatrixMode(GL_MODELVIEW);
   1.231 +    glLoadIdentity();
   1.232 +    Vertex3F vMoon = iMoonPositions[aTime%KMoonPositionCount];
   1.233 +    vMoon.iZ-=KModelDistanceFromCamera;
   1.234 +    glTranslatef(vMoon.iX, vMoon.iY, vMoon.iZ);
   1.235 +    
   1.236 +    GLfloat mat_moon_specular[] = { 0.5, 0.5, 0.5, 1.0 };
   1.237 +    GLfloat mat_moon_shininess[] = { 500.0 };
   1.238 +    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_moon_specular);
   1.239 +    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_moon_specular);
   1.240 +    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_moon_specular);
   1.241 +    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_moon_shininess);  
   1.242 +    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_no_emission);
   1.243 +    
   1.244 +    iMoon->Draw();
   1.245 +    }
   1.246 +
   1.247 +void CModel::SetResolutionL(TInt aResolution)
   1.248 +    {
   1.249 +    aResolution *= 5;
   1.250 +    if(aResolution > KMaxResolution)
   1.251 +        {
   1.252 +        aResolution = KMaxResolution;
   1.253 +        }
   1.254 +    if(aResolution < KMinResolution)
   1.255 +        {
   1.256 +        aResolution = KMinResolution;
   1.257 +        }
   1.258 +    iResolution = aResolution;
   1.259 +    CSolidSphere* newSun = CSolidSphere::NewLC(KSunRadius, iResolution, iResolution);
   1.260 +    CSolidSphere* newPlanet = CSolidSphere::NewLC(KPlanetRadius, iResolution, iResolution);
   1.261 +    CSolidSphere* newMoon = CSolidSphere::NewLC(KMoonRadius, iResolution, iResolution);
   1.262 +    SetShapes(newSun, newPlanet, newMoon);  
   1.263 +    CleanupStack::Pop(3, newSun);
   1.264 +    }
   1.265 +