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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
18 #include "geometrystructs.h"
25 const TInt KMoonPositionCount = 100;
26 const TInt KSunPositionCount = 100;
28 const TInt KSunOrbitRadius = 2000; //heliocentric
29 const TInt KMoonOrbitRadius = 100;
30 const TInt KModelDistanceFromCamera = 200;
32 const TInt KMinResolution = 5;
33 const TInt KMaxResolution = 50;
34 const TInt KDefaultResolution = 50;
36 const TInt KSunRadius=100;
37 const TInt KPlanetRadius=50;
38 const TInt KMoonRadius = 10;
41 _LIT(KGreen, "green");
43 _LIT(KBlack, "black");
46 CModel* CModel::NewL(EGLDisplay aDisplay, EGLSurface aSurface)
48 TPtrC defaultColor(KBlack);
49 return NewL(aDisplay, aSurface, defaultColor);
52 CModel* CModel::NewL(EGLDisplay aDisplay, EGLSurface aSurface, TPtrC aBackgroundColor)
54 CModel* self = new(ELeave) CModel(aDisplay, aSurface);
55 CleanupStack::PushL(self);
56 self->ConstructL(aBackgroundColor);
57 CleanupStack::Pop(self);
61 void CModel::PrecalculateOrbitL(TInt aOrbitingDistance, RArray<Vertex3F>& aVertices, TInt aPositionCount, TReal aAngle)
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));
71 TReal radians = aAngle*(KPi/180);
72 TReal32 cosA = cos(radians);
73 TReal32 sinA = sin(radians);
76 TReal32 cosCalc = aOrbitingDistance * cosA;
77 TReal32 sinCalc = aOrbitingDistance * sinA;
78 for(TInt i = 0; i < aPositionCount; i++)
80 x = cost1[i] * cosCalc;
81 y = cost1[i] * sinCalc;
83 Vertex3F v(x,y, sint1[i]*aOrbitingDistance);
84 User::LeaveIfError(aVertices.Append(v));
90 void CModel::ConstructL(TPtrC aBackgroundColor)
92 iResolution=KDefaultResolution;
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);
100 PrecalculateOrbitL(KSunOrbitRadius, iSunPositions, KSunPositionCount, 135);
101 PrecalculateOrbitL(KMoonOrbitRadius, iMoonPositions, KMoonPositionCount, 23.5);
102 if(aBackgroundColor == KRed)
104 iBackgroundColor[ERed] = 0.5;
106 else if (aBackgroundColor == KGreen)
108 iBackgroundColor[EGreen] = 0.5;
110 else if (aBackgroundColor == KBlue)
112 iBackgroundColor[EBlue] = 0.5;
116 CModel::CModel(EGLDisplay aDisplay, EGLSurface aSurface)
117 :iDisplay(aDisplay), iSurface(aSurface)
126 iSunPositions.Close();
127 iMoonPositions.Close();
130 void CModel::SetShapes(CSolidSphere* aSun, CSolidSphere* aPlanet, CSolidSphere* aMoon)
142 void CModel::DrawToBuffer(TInt aTime) const
145 DrawModelData(aTime);
148 void CModel::InitialiseFrame() const
150 glEnable(GL_CULL_FACE);
151 glEnable(GL_DEPTH_TEST);
152 glEnable(GL_COLOR_ARRAY);
153 glEnable(GL_LIGHTING);
155 glEnableClientState(GL_VERTEX_ARRAY);
156 glEnableClientState(GL_NORMAL_ARRAY);
158 glClearColor(iBackgroundColor[ERed], iBackgroundColor[EGreen], iBackgroundColor[EBlue], iBackgroundColor[EAlpha]);
159 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
161 glCullFace(GL_FRONT);
162 glShadeModel (GL_SMOOTH);
164 // Set the projection parameters
165 glMatrixMode(GL_PROJECTION);
169 if(!eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &height))
174 if(!eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &width))
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);
187 void CModel::DrawModelData(TInt aTime) const
189 //draw a light source where the sun is
190 glMatrixMode(GL_MODELVIEW);
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);
200 glMatrixMode(GL_MODELVIEW);
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);
207 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, sun_color);
211 glMatrixMode(GL_MODELVIEW);
213 glTranslatef(0, 0, -KModelDistanceFromCamera);
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};
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);
227 glMatrixMode(GL_MODELVIEW);
229 Vertex3F vMoon = iMoonPositions[aTime%KMoonPositionCount];
230 vMoon.iZ-=KModelDistanceFromCamera;
231 glTranslatef(vMoon.iX, vMoon.iY, vMoon.iZ);
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);
244 void CModel::SetResolutionL(TInt aResolution)
247 if(aResolution > KMaxResolution)
249 aResolution = KMaxResolution;
251 if(aResolution < KMinResolution)
253 aResolution = KMinResolution;
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);