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