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 +