1*38e8c45fSAndroid Build Coastguard Worker /* San Angeles Observation OpenGL ES version example
2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2004-2005 Jetro Lauha
3*38e8c45fSAndroid Build Coastguard Worker * All rights reserved.
4*38e8c45fSAndroid Build Coastguard Worker * Web: http://iki.fi/jetro/
5*38e8c45fSAndroid Build Coastguard Worker *
6*38e8c45fSAndroid Build Coastguard Worker * This source is free software; you can redistribute it and/or
7*38e8c45fSAndroid Build Coastguard Worker * modify it under the terms of EITHER:
8*38e8c45fSAndroid Build Coastguard Worker * (1) The GNU Lesser General Public License as published by the Free
9*38e8c45fSAndroid Build Coastguard Worker * Software Foundation; either version 2.1 of the License, or (at
10*38e8c45fSAndroid Build Coastguard Worker * your option) any later version. The text of the GNU Lesser
11*38e8c45fSAndroid Build Coastguard Worker * General Public License is included with this source in the
12*38e8c45fSAndroid Build Coastguard Worker * file LICENSE-LGPL.txt.
13*38e8c45fSAndroid Build Coastguard Worker * (2) The BSD-style license that is included with this source in
14*38e8c45fSAndroid Build Coastguard Worker * the file LICENSE-BSD.txt.
15*38e8c45fSAndroid Build Coastguard Worker *
16*38e8c45fSAndroid Build Coastguard Worker * This source is distributed in the hope that it will be useful,
17*38e8c45fSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
18*38e8c45fSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
19*38e8c45fSAndroid Build Coastguard Worker * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
20*38e8c45fSAndroid Build Coastguard Worker *
21*38e8c45fSAndroid Build Coastguard Worker * $Id: demo.c,v 1.10 2005/02/08 20:54:39 tonic Exp $
22*38e8c45fSAndroid Build Coastguard Worker * $Revision: 1.10 $
23*38e8c45fSAndroid Build Coastguard Worker */
24*38e8c45fSAndroid Build Coastguard Worker
25*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <math.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <float.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <assert.h>
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker #include <GLES/gl.h>
31*38e8c45fSAndroid Build Coastguard Worker
32*38e8c45fSAndroid Build Coastguard Worker #include "app.h"
33*38e8c45fSAndroid Build Coastguard Worker #include "shapes.h"
34*38e8c45fSAndroid Build Coastguard Worker #include "cams.h"
35*38e8c45fSAndroid Build Coastguard Worker
36*38e8c45fSAndroid Build Coastguard Worker
37*38e8c45fSAndroid Build Coastguard Worker // Total run length is 20 * camera track base unit length (see cams.h).
38*38e8c45fSAndroid Build Coastguard Worker #define RUN_LENGTH (20 * CAMTRACK_LEN)
39*38e8c45fSAndroid Build Coastguard Worker #undef PI
40*38e8c45fSAndroid Build Coastguard Worker #define PI 3.1415926535897932f
41*38e8c45fSAndroid Build Coastguard Worker #define RANDOM_UINT_MAX 65535
42*38e8c45fSAndroid Build Coastguard Worker
43*38e8c45fSAndroid Build Coastguard Worker
44*38e8c45fSAndroid Build Coastguard Worker static unsigned long sRandomSeed = 0;
45*38e8c45fSAndroid Build Coastguard Worker
seedRandom(unsigned long seed)46*38e8c45fSAndroid Build Coastguard Worker static void seedRandom(unsigned long seed)
47*38e8c45fSAndroid Build Coastguard Worker {
48*38e8c45fSAndroid Build Coastguard Worker sRandomSeed = seed;
49*38e8c45fSAndroid Build Coastguard Worker }
50*38e8c45fSAndroid Build Coastguard Worker
randomUInt()51*38e8c45fSAndroid Build Coastguard Worker static unsigned long randomUInt()
52*38e8c45fSAndroid Build Coastguard Worker {
53*38e8c45fSAndroid Build Coastguard Worker sRandomSeed = sRandomSeed * 0x343fd + 0x269ec3;
54*38e8c45fSAndroid Build Coastguard Worker return sRandomSeed >> 16;
55*38e8c45fSAndroid Build Coastguard Worker }
56*38e8c45fSAndroid Build Coastguard Worker
57*38e8c45fSAndroid Build Coastguard Worker
58*38e8c45fSAndroid Build Coastguard Worker // Capped conversion from float to fixed.
floatToFixed(float value)59*38e8c45fSAndroid Build Coastguard Worker static long floatToFixed(float value)
60*38e8c45fSAndroid Build Coastguard Worker {
61*38e8c45fSAndroid Build Coastguard Worker if (value < -32768) value = -32768;
62*38e8c45fSAndroid Build Coastguard Worker if (value > 32767) value = 32767;
63*38e8c45fSAndroid Build Coastguard Worker return (long)(value * 65536);
64*38e8c45fSAndroid Build Coastguard Worker }
65*38e8c45fSAndroid Build Coastguard Worker
66*38e8c45fSAndroid Build Coastguard Worker #define FIXED(value) floatToFixed(value)
67*38e8c45fSAndroid Build Coastguard Worker
68*38e8c45fSAndroid Build Coastguard Worker
69*38e8c45fSAndroid Build Coastguard Worker // Definition of one GL object in this demo.
70*38e8c45fSAndroid Build Coastguard Worker typedef struct {
71*38e8c45fSAndroid Build Coastguard Worker /* Vertex array and color array are enabled for all objects, so their
72*38e8c45fSAndroid Build Coastguard Worker * pointers must always be valid and non-NULL. Normal array is not
73*38e8c45fSAndroid Build Coastguard Worker * used by the ground plane, so when its pointer is NULL then normal
74*38e8c45fSAndroid Build Coastguard Worker * array usage is disabled.
75*38e8c45fSAndroid Build Coastguard Worker *
76*38e8c45fSAndroid Build Coastguard Worker * Vertex array is supposed to use GL_FIXED datatype and stride 0
77*38e8c45fSAndroid Build Coastguard Worker * (i.e. tightly packed array). Color array is supposed to have 4
78*38e8c45fSAndroid Build Coastguard Worker * components per color with GL_UNSIGNED_BYTE datatype and stride 0.
79*38e8c45fSAndroid Build Coastguard Worker * Normal array is supposed to use GL_FIXED datatype and stride 0.
80*38e8c45fSAndroid Build Coastguard Worker */
81*38e8c45fSAndroid Build Coastguard Worker GLfixed *vertexArray;
82*38e8c45fSAndroid Build Coastguard Worker GLubyte *colorArray;
83*38e8c45fSAndroid Build Coastguard Worker GLfixed *normalArray;
84*38e8c45fSAndroid Build Coastguard Worker GLint vertexComponents;
85*38e8c45fSAndroid Build Coastguard Worker GLsizei count;
86*38e8c45fSAndroid Build Coastguard Worker } GLOBJECT;
87*38e8c45fSAndroid Build Coastguard Worker
88*38e8c45fSAndroid Build Coastguard Worker
89*38e8c45fSAndroid Build Coastguard Worker static long sStartTick = 0;
90*38e8c45fSAndroid Build Coastguard Worker static long sTick = 0;
91*38e8c45fSAndroid Build Coastguard Worker
92*38e8c45fSAndroid Build Coastguard Worker static int sCurrentCamTrack = 0;
93*38e8c45fSAndroid Build Coastguard Worker static long sCurrentCamTrackStartTick = 0;
94*38e8c45fSAndroid Build Coastguard Worker static long sNextCamTrackStartTick = 0x7fffffff;
95*38e8c45fSAndroid Build Coastguard Worker
96*38e8c45fSAndroid Build Coastguard Worker static GLOBJECT *sSuperShapeObjects[SUPERSHAPE_COUNT] = { NULL };
97*38e8c45fSAndroid Build Coastguard Worker static GLOBJECT *sGroundPlane = NULL;
98*38e8c45fSAndroid Build Coastguard Worker
99*38e8c45fSAndroid Build Coastguard Worker
100*38e8c45fSAndroid Build Coastguard Worker typedef struct {
101*38e8c45fSAndroid Build Coastguard Worker float x, y, z;
102*38e8c45fSAndroid Build Coastguard Worker } VECTOR3;
103*38e8c45fSAndroid Build Coastguard Worker
104*38e8c45fSAndroid Build Coastguard Worker
freeGLObject(GLOBJECT * object)105*38e8c45fSAndroid Build Coastguard Worker static void freeGLObject(GLOBJECT *object)
106*38e8c45fSAndroid Build Coastguard Worker {
107*38e8c45fSAndroid Build Coastguard Worker if (object == NULL)
108*38e8c45fSAndroid Build Coastguard Worker return;
109*38e8c45fSAndroid Build Coastguard Worker free(object->normalArray);
110*38e8c45fSAndroid Build Coastguard Worker free(object->colorArray);
111*38e8c45fSAndroid Build Coastguard Worker free(object->vertexArray);
112*38e8c45fSAndroid Build Coastguard Worker free(object);
113*38e8c45fSAndroid Build Coastguard Worker }
114*38e8c45fSAndroid Build Coastguard Worker
115*38e8c45fSAndroid Build Coastguard Worker
newGLObject(long vertices,int vertexComponents,int useNormalArray)116*38e8c45fSAndroid Build Coastguard Worker static GLOBJECT * newGLObject(long vertices, int vertexComponents,
117*38e8c45fSAndroid Build Coastguard Worker int useNormalArray)
118*38e8c45fSAndroid Build Coastguard Worker {
119*38e8c45fSAndroid Build Coastguard Worker GLOBJECT *result;
120*38e8c45fSAndroid Build Coastguard Worker result = (GLOBJECT *)malloc(sizeof(GLOBJECT));
121*38e8c45fSAndroid Build Coastguard Worker if (result == NULL)
122*38e8c45fSAndroid Build Coastguard Worker return NULL;
123*38e8c45fSAndroid Build Coastguard Worker result->count = vertices;
124*38e8c45fSAndroid Build Coastguard Worker result->vertexComponents = vertexComponents;
125*38e8c45fSAndroid Build Coastguard Worker result->vertexArray = (GLfixed *)malloc(vertices * vertexComponents *
126*38e8c45fSAndroid Build Coastguard Worker sizeof(GLfixed));
127*38e8c45fSAndroid Build Coastguard Worker result->colorArray = (GLubyte *)malloc(vertices * 4 * sizeof(GLubyte));
128*38e8c45fSAndroid Build Coastguard Worker if (useNormalArray)
129*38e8c45fSAndroid Build Coastguard Worker {
130*38e8c45fSAndroid Build Coastguard Worker result->normalArray = (GLfixed *)malloc(vertices * 3 *
131*38e8c45fSAndroid Build Coastguard Worker sizeof(GLfixed));
132*38e8c45fSAndroid Build Coastguard Worker }
133*38e8c45fSAndroid Build Coastguard Worker else
134*38e8c45fSAndroid Build Coastguard Worker result->normalArray = NULL;
135*38e8c45fSAndroid Build Coastguard Worker if (result->vertexArray == NULL ||
136*38e8c45fSAndroid Build Coastguard Worker result->colorArray == NULL ||
137*38e8c45fSAndroid Build Coastguard Worker (useNormalArray && result->normalArray == NULL))
138*38e8c45fSAndroid Build Coastguard Worker {
139*38e8c45fSAndroid Build Coastguard Worker freeGLObject(result);
140*38e8c45fSAndroid Build Coastguard Worker return NULL;
141*38e8c45fSAndroid Build Coastguard Worker }
142*38e8c45fSAndroid Build Coastguard Worker return result;
143*38e8c45fSAndroid Build Coastguard Worker }
144*38e8c45fSAndroid Build Coastguard Worker
145*38e8c45fSAndroid Build Coastguard Worker
drawGLObject(GLOBJECT * object)146*38e8c45fSAndroid Build Coastguard Worker static void drawGLObject(GLOBJECT *object)
147*38e8c45fSAndroid Build Coastguard Worker {
148*38e8c45fSAndroid Build Coastguard Worker assert(object != NULL);
149*38e8c45fSAndroid Build Coastguard Worker
150*38e8c45fSAndroid Build Coastguard Worker glVertexPointer(object->vertexComponents, GL_FIXED,
151*38e8c45fSAndroid Build Coastguard Worker 0, object->vertexArray);
152*38e8c45fSAndroid Build Coastguard Worker glColorPointer(4, GL_UNSIGNED_BYTE, 0, object->colorArray);
153*38e8c45fSAndroid Build Coastguard Worker
154*38e8c45fSAndroid Build Coastguard Worker // Already done in initialization:
155*38e8c45fSAndroid Build Coastguard Worker //glEnableClientState(GL_VERTEX_ARRAY);
156*38e8c45fSAndroid Build Coastguard Worker //glEnableClientState(GL_COLOR_ARRAY);
157*38e8c45fSAndroid Build Coastguard Worker
158*38e8c45fSAndroid Build Coastguard Worker if (object->normalArray)
159*38e8c45fSAndroid Build Coastguard Worker {
160*38e8c45fSAndroid Build Coastguard Worker glNormalPointer(GL_FIXED, 0, object->normalArray);
161*38e8c45fSAndroid Build Coastguard Worker glEnableClientState(GL_NORMAL_ARRAY);
162*38e8c45fSAndroid Build Coastguard Worker }
163*38e8c45fSAndroid Build Coastguard Worker else
164*38e8c45fSAndroid Build Coastguard Worker glDisableClientState(GL_NORMAL_ARRAY);
165*38e8c45fSAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, object->count);
166*38e8c45fSAndroid Build Coastguard Worker }
167*38e8c45fSAndroid Build Coastguard Worker
168*38e8c45fSAndroid Build Coastguard Worker
vector3Sub(VECTOR3 * dest,VECTOR3 * v1,VECTOR3 * v2)169*38e8c45fSAndroid Build Coastguard Worker static void vector3Sub(VECTOR3 *dest, VECTOR3 *v1, VECTOR3 *v2)
170*38e8c45fSAndroid Build Coastguard Worker {
171*38e8c45fSAndroid Build Coastguard Worker dest->x = v1->x - v2->x;
172*38e8c45fSAndroid Build Coastguard Worker dest->y = v1->y - v2->y;
173*38e8c45fSAndroid Build Coastguard Worker dest->z = v1->z - v2->z;
174*38e8c45fSAndroid Build Coastguard Worker }
175*38e8c45fSAndroid Build Coastguard Worker
176*38e8c45fSAndroid Build Coastguard Worker
superShapeMap(VECTOR3 * point,float r1,float r2,float t,float p)177*38e8c45fSAndroid Build Coastguard Worker static void superShapeMap(VECTOR3 *point, float r1, float r2, float t, float p)
178*38e8c45fSAndroid Build Coastguard Worker {
179*38e8c45fSAndroid Build Coastguard Worker // sphere-mapping of supershape parameters
180*38e8c45fSAndroid Build Coastguard Worker point->x = (float)(cos(t) * cos(p) / r1 / r2);
181*38e8c45fSAndroid Build Coastguard Worker point->y = (float)(sin(t) * cos(p) / r1 / r2);
182*38e8c45fSAndroid Build Coastguard Worker point->z = (float)(sin(p) / r2);
183*38e8c45fSAndroid Build Coastguard Worker }
184*38e8c45fSAndroid Build Coastguard Worker
185*38e8c45fSAndroid Build Coastguard Worker
ssFunc(const float t,const float * p)186*38e8c45fSAndroid Build Coastguard Worker static float ssFunc(const float t, const float *p)
187*38e8c45fSAndroid Build Coastguard Worker {
188*38e8c45fSAndroid Build Coastguard Worker return (float)(pow(pow(fabs(cos(p[0] * t / 4)) / p[1], p[4]) +
189*38e8c45fSAndroid Build Coastguard Worker pow(fabs(sin(p[0] * t / 4)) / p[2], p[5]), 1 / p[3]));
190*38e8c45fSAndroid Build Coastguard Worker }
191*38e8c45fSAndroid Build Coastguard Worker
192*38e8c45fSAndroid Build Coastguard Worker
193*38e8c45fSAndroid Build Coastguard Worker // Creates and returns a supershape object.
194*38e8c45fSAndroid Build Coastguard Worker // Based on Paul Bourke's POV-Ray implementation.
195*38e8c45fSAndroid Build Coastguard Worker // http://astronomy.swin.edu.au/~pbourke/povray/supershape/
createSuperShape(const float * params)196*38e8c45fSAndroid Build Coastguard Worker static GLOBJECT * createSuperShape(const float *params)
197*38e8c45fSAndroid Build Coastguard Worker {
198*38e8c45fSAndroid Build Coastguard Worker const int resol1 = (int)params[SUPERSHAPE_PARAMS - 3];
199*38e8c45fSAndroid Build Coastguard Worker const int resol2 = (int)params[SUPERSHAPE_PARAMS - 2];
200*38e8c45fSAndroid Build Coastguard Worker // latitude 0 to pi/2 for no mirrored bottom
201*38e8c45fSAndroid Build Coastguard Worker // (latitudeBegin==0 for -pi/2 to pi/2 originally)
202*38e8c45fSAndroid Build Coastguard Worker const int latitudeBegin = resol2 / 4;
203*38e8c45fSAndroid Build Coastguard Worker const int latitudeEnd = resol2 / 2; // non-inclusive
204*38e8c45fSAndroid Build Coastguard Worker const int longitudeCount = resol1;
205*38e8c45fSAndroid Build Coastguard Worker const int latitudeCount = latitudeEnd - latitudeBegin;
206*38e8c45fSAndroid Build Coastguard Worker const long triangleCount = longitudeCount * latitudeCount * 2;
207*38e8c45fSAndroid Build Coastguard Worker const long vertices = triangleCount * 3;
208*38e8c45fSAndroid Build Coastguard Worker GLOBJECT *result;
209*38e8c45fSAndroid Build Coastguard Worker float baseColor[3];
210*38e8c45fSAndroid Build Coastguard Worker int a, longitude, latitude;
211*38e8c45fSAndroid Build Coastguard Worker long currentVertex, currentQuad;
212*38e8c45fSAndroid Build Coastguard Worker
213*38e8c45fSAndroid Build Coastguard Worker result = newGLObject(vertices, 3, 1);
214*38e8c45fSAndroid Build Coastguard Worker if (result == NULL)
215*38e8c45fSAndroid Build Coastguard Worker return NULL;
216*38e8c45fSAndroid Build Coastguard Worker
217*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < 3; ++a)
218*38e8c45fSAndroid Build Coastguard Worker baseColor[a] = ((randomUInt() % 155) + 100) / 255.f;
219*38e8c45fSAndroid Build Coastguard Worker
220*38e8c45fSAndroid Build Coastguard Worker currentQuad = 0;
221*38e8c45fSAndroid Build Coastguard Worker currentVertex = 0;
222*38e8c45fSAndroid Build Coastguard Worker
223*38e8c45fSAndroid Build Coastguard Worker // longitude -pi to pi
224*38e8c45fSAndroid Build Coastguard Worker for (longitude = 0; longitude < longitudeCount; ++longitude)
225*38e8c45fSAndroid Build Coastguard Worker {
226*38e8c45fSAndroid Build Coastguard Worker
227*38e8c45fSAndroid Build Coastguard Worker // latitude 0 to pi/2
228*38e8c45fSAndroid Build Coastguard Worker for (latitude = latitudeBegin; latitude < latitudeEnd; ++latitude)
229*38e8c45fSAndroid Build Coastguard Worker {
230*38e8c45fSAndroid Build Coastguard Worker float t1 = -PI + longitude * 2 * PI / resol1;
231*38e8c45fSAndroid Build Coastguard Worker float t2 = -PI + (longitude + 1) * 2 * PI / resol1;
232*38e8c45fSAndroid Build Coastguard Worker float p1 = -PI / 2 + latitude * 2 * PI / resol2;
233*38e8c45fSAndroid Build Coastguard Worker float p2 = -PI / 2 + (latitude + 1) * 2 * PI / resol2;
234*38e8c45fSAndroid Build Coastguard Worker float r0, r1, r2, r3;
235*38e8c45fSAndroid Build Coastguard Worker
236*38e8c45fSAndroid Build Coastguard Worker r0 = ssFunc(t1, params);
237*38e8c45fSAndroid Build Coastguard Worker r1 = ssFunc(p1, ¶ms[6]);
238*38e8c45fSAndroid Build Coastguard Worker r2 = ssFunc(t2, params);
239*38e8c45fSAndroid Build Coastguard Worker r3 = ssFunc(p2, ¶ms[6]);
240*38e8c45fSAndroid Build Coastguard Worker
241*38e8c45fSAndroid Build Coastguard Worker if (r0 != 0 && r1 != 0 && r2 != 0 && r3 != 0)
242*38e8c45fSAndroid Build Coastguard Worker {
243*38e8c45fSAndroid Build Coastguard Worker VECTOR3 pa, pb, pc, pd;
244*38e8c45fSAndroid Build Coastguard Worker VECTOR3 v1, v2, n;
245*38e8c45fSAndroid Build Coastguard Worker float ca;
246*38e8c45fSAndroid Build Coastguard Worker int i;
247*38e8c45fSAndroid Build Coastguard Worker //float lenSq, invLenSq;
248*38e8c45fSAndroid Build Coastguard Worker
249*38e8c45fSAndroid Build Coastguard Worker superShapeMap(&pa, r0, r1, t1, p1);
250*38e8c45fSAndroid Build Coastguard Worker superShapeMap(&pb, r2, r1, t2, p1);
251*38e8c45fSAndroid Build Coastguard Worker superShapeMap(&pc, r2, r3, t2, p2);
252*38e8c45fSAndroid Build Coastguard Worker superShapeMap(&pd, r0, r3, t1, p2);
253*38e8c45fSAndroid Build Coastguard Worker
254*38e8c45fSAndroid Build Coastguard Worker // kludge to set lower edge of the object to fixed level
255*38e8c45fSAndroid Build Coastguard Worker if (latitude == latitudeBegin + 1)
256*38e8c45fSAndroid Build Coastguard Worker pa.z = pb.z = 0;
257*38e8c45fSAndroid Build Coastguard Worker
258*38e8c45fSAndroid Build Coastguard Worker vector3Sub(&v1, &pb, &pa);
259*38e8c45fSAndroid Build Coastguard Worker vector3Sub(&v2, &pd, &pa);
260*38e8c45fSAndroid Build Coastguard Worker
261*38e8c45fSAndroid Build Coastguard Worker // Calculate normal with cross product.
262*38e8c45fSAndroid Build Coastguard Worker /* i j k i j
263*38e8c45fSAndroid Build Coastguard Worker * v1.x v1.y v1.z | v1.x v1.y
264*38e8c45fSAndroid Build Coastguard Worker * v2.x v2.y v2.z | v2.x v2.y
265*38e8c45fSAndroid Build Coastguard Worker */
266*38e8c45fSAndroid Build Coastguard Worker
267*38e8c45fSAndroid Build Coastguard Worker n.x = v1.y * v2.z - v1.z * v2.y;
268*38e8c45fSAndroid Build Coastguard Worker n.y = v1.z * v2.x - v1.x * v2.z;
269*38e8c45fSAndroid Build Coastguard Worker n.z = v1.x * v2.y - v1.y * v2.x;
270*38e8c45fSAndroid Build Coastguard Worker
271*38e8c45fSAndroid Build Coastguard Worker /* Pre-normalization of the normals is disabled here because
272*38e8c45fSAndroid Build Coastguard Worker * they will be normalized anyway later due to automatic
273*38e8c45fSAndroid Build Coastguard Worker * normalization (GL_NORMALIZE). It is enabled because the
274*38e8c45fSAndroid Build Coastguard Worker * objects are scaled with glScale.
275*38e8c45fSAndroid Build Coastguard Worker */
276*38e8c45fSAndroid Build Coastguard Worker /*
277*38e8c45fSAndroid Build Coastguard Worker lenSq = n.x * n.x + n.y * n.y + n.z * n.z;
278*38e8c45fSAndroid Build Coastguard Worker invLenSq = (float)(1 / sqrt(lenSq));
279*38e8c45fSAndroid Build Coastguard Worker n.x *= invLenSq;
280*38e8c45fSAndroid Build Coastguard Worker n.y *= invLenSq;
281*38e8c45fSAndroid Build Coastguard Worker n.z *= invLenSq;
282*38e8c45fSAndroid Build Coastguard Worker */
283*38e8c45fSAndroid Build Coastguard Worker
284*38e8c45fSAndroid Build Coastguard Worker ca = pa.z + 0.5f;
285*38e8c45fSAndroid Build Coastguard Worker
286*38e8c45fSAndroid Build Coastguard Worker for (i = currentVertex * 3;
287*38e8c45fSAndroid Build Coastguard Worker i < (currentVertex + 6) * 3;
288*38e8c45fSAndroid Build Coastguard Worker i += 3)
289*38e8c45fSAndroid Build Coastguard Worker {
290*38e8c45fSAndroid Build Coastguard Worker result->normalArray[i] = FIXED(n.x);
291*38e8c45fSAndroid Build Coastguard Worker result->normalArray[i + 1] = FIXED(n.y);
292*38e8c45fSAndroid Build Coastguard Worker result->normalArray[i + 2] = FIXED(n.z);
293*38e8c45fSAndroid Build Coastguard Worker }
294*38e8c45fSAndroid Build Coastguard Worker for (i = currentVertex * 4;
295*38e8c45fSAndroid Build Coastguard Worker i < (currentVertex + 6) * 4;
296*38e8c45fSAndroid Build Coastguard Worker i += 4)
297*38e8c45fSAndroid Build Coastguard Worker {
298*38e8c45fSAndroid Build Coastguard Worker int a, color[3];
299*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < 3; ++a)
300*38e8c45fSAndroid Build Coastguard Worker {
301*38e8c45fSAndroid Build Coastguard Worker color[a] = (int)(ca * baseColor[a] * 255);
302*38e8c45fSAndroid Build Coastguard Worker if (color[a] > 255) color[a] = 255;
303*38e8c45fSAndroid Build Coastguard Worker }
304*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i] = (GLubyte)color[0];
305*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i + 1] = (GLubyte)color[1];
306*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i + 2] = (GLubyte)color[2];
307*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i + 3] = 0;
308*38e8c45fSAndroid Build Coastguard Worker }
309*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3] = FIXED(pa.x);
310*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 1] = FIXED(pa.y);
311*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 2] = FIXED(pa.z);
312*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
313*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3] = FIXED(pb.x);
314*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 1] = FIXED(pb.y);
315*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 2] = FIXED(pb.z);
316*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
317*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3] = FIXED(pd.x);
318*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 1] = FIXED(pd.y);
319*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 2] = FIXED(pd.z);
320*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
321*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3] = FIXED(pb.x);
322*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 1] = FIXED(pb.y);
323*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 2] = FIXED(pb.z);
324*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
325*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3] = FIXED(pc.x);
326*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 1] = FIXED(pc.y);
327*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 2] = FIXED(pc.z);
328*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
329*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3] = FIXED(pd.x);
330*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 1] = FIXED(pd.y);
331*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 3 + 2] = FIXED(pd.z);
332*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
333*38e8c45fSAndroid Build Coastguard Worker } // r0 && r1 && r2 && r3
334*38e8c45fSAndroid Build Coastguard Worker ++currentQuad;
335*38e8c45fSAndroid Build Coastguard Worker } // latitude
336*38e8c45fSAndroid Build Coastguard Worker } // longitude
337*38e8c45fSAndroid Build Coastguard Worker
338*38e8c45fSAndroid Build Coastguard Worker // Set number of vertices in object to the actual amount created.
339*38e8c45fSAndroid Build Coastguard Worker result->count = currentVertex;
340*38e8c45fSAndroid Build Coastguard Worker
341*38e8c45fSAndroid Build Coastguard Worker return result;
342*38e8c45fSAndroid Build Coastguard Worker }
343*38e8c45fSAndroid Build Coastguard Worker
344*38e8c45fSAndroid Build Coastguard Worker
createGroundPlane()345*38e8c45fSAndroid Build Coastguard Worker static GLOBJECT * createGroundPlane()
346*38e8c45fSAndroid Build Coastguard Worker {
347*38e8c45fSAndroid Build Coastguard Worker const int scale = 4;
348*38e8c45fSAndroid Build Coastguard Worker const int yBegin = -15, yEnd = 15; // ends are non-inclusive
349*38e8c45fSAndroid Build Coastguard Worker const int xBegin = -15, xEnd = 15;
350*38e8c45fSAndroid Build Coastguard Worker const long triangleCount = (yEnd - yBegin) * (xEnd - xBegin) * 2;
351*38e8c45fSAndroid Build Coastguard Worker const long vertices = triangleCount * 3;
352*38e8c45fSAndroid Build Coastguard Worker GLOBJECT *result;
353*38e8c45fSAndroid Build Coastguard Worker int x, y;
354*38e8c45fSAndroid Build Coastguard Worker long currentVertex, currentQuad;
355*38e8c45fSAndroid Build Coastguard Worker
356*38e8c45fSAndroid Build Coastguard Worker result = newGLObject(vertices, 2, 0);
357*38e8c45fSAndroid Build Coastguard Worker if (result == NULL)
358*38e8c45fSAndroid Build Coastguard Worker return NULL;
359*38e8c45fSAndroid Build Coastguard Worker
360*38e8c45fSAndroid Build Coastguard Worker currentQuad = 0;
361*38e8c45fSAndroid Build Coastguard Worker currentVertex = 0;
362*38e8c45fSAndroid Build Coastguard Worker
363*38e8c45fSAndroid Build Coastguard Worker for (y = yBegin; y < yEnd; ++y)
364*38e8c45fSAndroid Build Coastguard Worker {
365*38e8c45fSAndroid Build Coastguard Worker for (x = xBegin; x < xEnd; ++x)
366*38e8c45fSAndroid Build Coastguard Worker {
367*38e8c45fSAndroid Build Coastguard Worker GLubyte color;
368*38e8c45fSAndroid Build Coastguard Worker int i, a;
369*38e8c45fSAndroid Build Coastguard Worker color = (GLubyte)((randomUInt() & 0x5f) + 81); // 101 1111
370*38e8c45fSAndroid Build Coastguard Worker for (i = currentVertex * 4; i < (currentVertex + 6) * 4; i += 4)
371*38e8c45fSAndroid Build Coastguard Worker {
372*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i] = color;
373*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i + 1] = color;
374*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i + 2] = color;
375*38e8c45fSAndroid Build Coastguard Worker result->colorArray[i + 3] = 0;
376*38e8c45fSAndroid Build Coastguard Worker }
377*38e8c45fSAndroid Build Coastguard Worker
378*38e8c45fSAndroid Build Coastguard Worker // Axis bits for quad triangles:
379*38e8c45fSAndroid Build Coastguard Worker // x: 011100 (0x1c), y: 110001 (0x31) (clockwise)
380*38e8c45fSAndroid Build Coastguard Worker // x: 001110 (0x0e), y: 100011 (0x23) (counter-clockwise)
381*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < 6; ++a)
382*38e8c45fSAndroid Build Coastguard Worker {
383*38e8c45fSAndroid Build Coastguard Worker const int xm = x + ((0x1c >> a) & 1);
384*38e8c45fSAndroid Build Coastguard Worker const int ym = y + ((0x31 >> a) & 1);
385*38e8c45fSAndroid Build Coastguard Worker const float m = (float)(cos(xm * 2) * sin(ym * 4) * 0.75f);
386*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 2] =
387*38e8c45fSAndroid Build Coastguard Worker FIXED(xm * scale + m);
388*38e8c45fSAndroid Build Coastguard Worker result->vertexArray[currentVertex * 2 + 1] =
389*38e8c45fSAndroid Build Coastguard Worker FIXED(ym * scale + m);
390*38e8c45fSAndroid Build Coastguard Worker ++currentVertex;
391*38e8c45fSAndroid Build Coastguard Worker }
392*38e8c45fSAndroid Build Coastguard Worker ++currentQuad;
393*38e8c45fSAndroid Build Coastguard Worker }
394*38e8c45fSAndroid Build Coastguard Worker }
395*38e8c45fSAndroid Build Coastguard Worker return result;
396*38e8c45fSAndroid Build Coastguard Worker }
397*38e8c45fSAndroid Build Coastguard Worker
398*38e8c45fSAndroid Build Coastguard Worker
drawGroundPlane()399*38e8c45fSAndroid Build Coastguard Worker static void drawGroundPlane()
400*38e8c45fSAndroid Build Coastguard Worker {
401*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_CULL_FACE);
402*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_DEPTH_TEST);
403*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_BLEND);
404*38e8c45fSAndroid Build Coastguard Worker glBlendFunc(GL_ZERO, GL_SRC_COLOR);
405*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_LIGHTING);
406*38e8c45fSAndroid Build Coastguard Worker
407*38e8c45fSAndroid Build Coastguard Worker drawGLObject(sGroundPlane);
408*38e8c45fSAndroid Build Coastguard Worker
409*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_LIGHTING);
410*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_BLEND);
411*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_DEPTH_TEST);
412*38e8c45fSAndroid Build Coastguard Worker }
413*38e8c45fSAndroid Build Coastguard Worker
414*38e8c45fSAndroid Build Coastguard Worker
drawFadeQuad()415*38e8c45fSAndroid Build Coastguard Worker static void drawFadeQuad()
416*38e8c45fSAndroid Build Coastguard Worker {
417*38e8c45fSAndroid Build Coastguard Worker static const GLfixed quadVertices[] = {
418*38e8c45fSAndroid Build Coastguard Worker -0x10000, -0x10000,
419*38e8c45fSAndroid Build Coastguard Worker 0x10000, -0x10000,
420*38e8c45fSAndroid Build Coastguard Worker -0x10000, 0x10000,
421*38e8c45fSAndroid Build Coastguard Worker 0x10000, -0x10000,
422*38e8c45fSAndroid Build Coastguard Worker 0x10000, 0x10000,
423*38e8c45fSAndroid Build Coastguard Worker -0x10000, 0x10000
424*38e8c45fSAndroid Build Coastguard Worker };
425*38e8c45fSAndroid Build Coastguard Worker
426*38e8c45fSAndroid Build Coastguard Worker const int beginFade = sTick - sCurrentCamTrackStartTick;
427*38e8c45fSAndroid Build Coastguard Worker const int endFade = sNextCamTrackStartTick - sTick;
428*38e8c45fSAndroid Build Coastguard Worker const int minFade = beginFade < endFade ? beginFade : endFade;
429*38e8c45fSAndroid Build Coastguard Worker
430*38e8c45fSAndroid Build Coastguard Worker if (minFade < 1024)
431*38e8c45fSAndroid Build Coastguard Worker {
432*38e8c45fSAndroid Build Coastguard Worker const GLfixed fadeColor = minFade << 6;
433*38e8c45fSAndroid Build Coastguard Worker glColor4x(fadeColor, fadeColor, fadeColor, 0);
434*38e8c45fSAndroid Build Coastguard Worker
435*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_DEPTH_TEST);
436*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_BLEND);
437*38e8c45fSAndroid Build Coastguard Worker glBlendFunc(GL_ZERO, GL_SRC_COLOR);
438*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_LIGHTING);
439*38e8c45fSAndroid Build Coastguard Worker
440*38e8c45fSAndroid Build Coastguard Worker glMatrixMode(GL_MODELVIEW);
441*38e8c45fSAndroid Build Coastguard Worker glLoadIdentity();
442*38e8c45fSAndroid Build Coastguard Worker
443*38e8c45fSAndroid Build Coastguard Worker glMatrixMode(GL_PROJECTION);
444*38e8c45fSAndroid Build Coastguard Worker glLoadIdentity();
445*38e8c45fSAndroid Build Coastguard Worker
446*38e8c45fSAndroid Build Coastguard Worker glDisableClientState(GL_COLOR_ARRAY);
447*38e8c45fSAndroid Build Coastguard Worker glDisableClientState(GL_NORMAL_ARRAY);
448*38e8c45fSAndroid Build Coastguard Worker glVertexPointer(2, GL_FIXED, 0, quadVertices);
449*38e8c45fSAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, 6);
450*38e8c45fSAndroid Build Coastguard Worker
451*38e8c45fSAndroid Build Coastguard Worker glEnableClientState(GL_COLOR_ARRAY);
452*38e8c45fSAndroid Build Coastguard Worker
453*38e8c45fSAndroid Build Coastguard Worker glMatrixMode(GL_MODELVIEW);
454*38e8c45fSAndroid Build Coastguard Worker
455*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_LIGHTING);
456*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_BLEND);
457*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_DEPTH_TEST);
458*38e8c45fSAndroid Build Coastguard Worker }
459*38e8c45fSAndroid Build Coastguard Worker }
460*38e8c45fSAndroid Build Coastguard Worker
461*38e8c45fSAndroid Build Coastguard Worker
462*38e8c45fSAndroid Build Coastguard Worker // Called from the app framework.
appInit()463*38e8c45fSAndroid Build Coastguard Worker void appInit()
464*38e8c45fSAndroid Build Coastguard Worker {
465*38e8c45fSAndroid Build Coastguard Worker unsigned int a;
466*38e8c45fSAndroid Build Coastguard Worker
467*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_NORMALIZE);
468*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_DEPTH_TEST);
469*38e8c45fSAndroid Build Coastguard Worker glDisable(GL_CULL_FACE);
470*38e8c45fSAndroid Build Coastguard Worker glShadeModel(GL_FLAT);
471*38e8c45fSAndroid Build Coastguard Worker
472*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_LIGHTING);
473*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_LIGHT0);
474*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_LIGHT1);
475*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_LIGHT2);
476*38e8c45fSAndroid Build Coastguard Worker
477*38e8c45fSAndroid Build Coastguard Worker glEnableClientState(GL_VERTEX_ARRAY);
478*38e8c45fSAndroid Build Coastguard Worker glEnableClientState(GL_COLOR_ARRAY);
479*38e8c45fSAndroid Build Coastguard Worker
480*38e8c45fSAndroid Build Coastguard Worker seedRandom(15);
481*38e8c45fSAndroid Build Coastguard Worker
482*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < SUPERSHAPE_COUNT; ++a)
483*38e8c45fSAndroid Build Coastguard Worker {
484*38e8c45fSAndroid Build Coastguard Worker sSuperShapeObjects[a] = createSuperShape(sSuperShapeParams[a]);
485*38e8c45fSAndroid Build Coastguard Worker assert(sSuperShapeObjects[a] != NULL);
486*38e8c45fSAndroid Build Coastguard Worker }
487*38e8c45fSAndroid Build Coastguard Worker sGroundPlane = createGroundPlane();
488*38e8c45fSAndroid Build Coastguard Worker assert(sGroundPlane != NULL);
489*38e8c45fSAndroid Build Coastguard Worker }
490*38e8c45fSAndroid Build Coastguard Worker
491*38e8c45fSAndroid Build Coastguard Worker
492*38e8c45fSAndroid Build Coastguard Worker // Called from the app framework.
appDeinit()493*38e8c45fSAndroid Build Coastguard Worker void appDeinit()
494*38e8c45fSAndroid Build Coastguard Worker {
495*38e8c45fSAndroid Build Coastguard Worker unsigned int a;
496*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < SUPERSHAPE_COUNT; ++a)
497*38e8c45fSAndroid Build Coastguard Worker freeGLObject(sSuperShapeObjects[a]);
498*38e8c45fSAndroid Build Coastguard Worker freeGLObject(sGroundPlane);
499*38e8c45fSAndroid Build Coastguard Worker }
500*38e8c45fSAndroid Build Coastguard Worker
501*38e8c45fSAndroid Build Coastguard Worker
gluPerspective(GLfloat fovy,GLfloat aspect,GLfloat zNear,GLfloat zFar)502*38e8c45fSAndroid Build Coastguard Worker static void gluPerspective(GLfloat fovy, GLfloat aspect,
503*38e8c45fSAndroid Build Coastguard Worker GLfloat zNear, GLfloat zFar)
504*38e8c45fSAndroid Build Coastguard Worker {
505*38e8c45fSAndroid Build Coastguard Worker GLfloat xmin, xmax, ymin, ymax;
506*38e8c45fSAndroid Build Coastguard Worker
507*38e8c45fSAndroid Build Coastguard Worker ymax = zNear * (GLfloat)tan(fovy * PI / 360);
508*38e8c45fSAndroid Build Coastguard Worker ymin = -ymax;
509*38e8c45fSAndroid Build Coastguard Worker xmin = ymin * aspect;
510*38e8c45fSAndroid Build Coastguard Worker xmax = ymax * aspect;
511*38e8c45fSAndroid Build Coastguard Worker
512*38e8c45fSAndroid Build Coastguard Worker glFrustumx((GLfixed)(xmin * 65536), (GLfixed)(xmax * 65536),
513*38e8c45fSAndroid Build Coastguard Worker (GLfixed)(ymin * 65536), (GLfixed)(ymax * 65536),
514*38e8c45fSAndroid Build Coastguard Worker (GLfixed)(zNear * 65536), (GLfixed)(zFar * 65536));
515*38e8c45fSAndroid Build Coastguard Worker }
516*38e8c45fSAndroid Build Coastguard Worker
517*38e8c45fSAndroid Build Coastguard Worker
prepareFrame(int width,int height)518*38e8c45fSAndroid Build Coastguard Worker static void prepareFrame(int width, int height)
519*38e8c45fSAndroid Build Coastguard Worker {
520*38e8c45fSAndroid Build Coastguard Worker glViewport(0, 0, width, height);
521*38e8c45fSAndroid Build Coastguard Worker
522*38e8c45fSAndroid Build Coastguard Worker glClearColorx((GLfixed)(0.1f * 65536),
523*38e8c45fSAndroid Build Coastguard Worker (GLfixed)(0.2f * 65536),
524*38e8c45fSAndroid Build Coastguard Worker (GLfixed)(0.3f * 65536), 0x10000);
525*38e8c45fSAndroid Build Coastguard Worker glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
526*38e8c45fSAndroid Build Coastguard Worker
527*38e8c45fSAndroid Build Coastguard Worker glMatrixMode(GL_PROJECTION);
528*38e8c45fSAndroid Build Coastguard Worker glLoadIdentity();
529*38e8c45fSAndroid Build Coastguard Worker gluPerspective(45, (float)width / height, 0.5f, 150);
530*38e8c45fSAndroid Build Coastguard Worker
531*38e8c45fSAndroid Build Coastguard Worker glMatrixMode(GL_MODELVIEW);
532*38e8c45fSAndroid Build Coastguard Worker
533*38e8c45fSAndroid Build Coastguard Worker glLoadIdentity();
534*38e8c45fSAndroid Build Coastguard Worker }
535*38e8c45fSAndroid Build Coastguard Worker
536*38e8c45fSAndroid Build Coastguard Worker
configureLightAndMaterial()537*38e8c45fSAndroid Build Coastguard Worker static void configureLightAndMaterial()
538*38e8c45fSAndroid Build Coastguard Worker {
539*38e8c45fSAndroid Build Coastguard Worker static GLfixed light0Position[] = { -0x40000, 0x10000, 0x10000, 0 };
540*38e8c45fSAndroid Build Coastguard Worker static GLfixed light0Diffuse[] = { 0x10000, 0x6666, 0, 0x10000 };
541*38e8c45fSAndroid Build Coastguard Worker static GLfixed light1Position[] = { 0x10000, -0x20000, -0x10000, 0 };
542*38e8c45fSAndroid Build Coastguard Worker static GLfixed light1Diffuse[] = { 0x11eb, 0x23d7, 0x5999, 0x10000 };
543*38e8c45fSAndroid Build Coastguard Worker static GLfixed light2Position[] = { -0x10000, 0, -0x40000, 0 };
544*38e8c45fSAndroid Build Coastguard Worker static GLfixed light2Diffuse[] = { 0x11eb, 0x2b85, 0x23d7, 0x10000 };
545*38e8c45fSAndroid Build Coastguard Worker static GLfixed materialSpecular[] = { 0x10000, 0x10000, 0x10000, 0x10000 };
546*38e8c45fSAndroid Build Coastguard Worker
547*38e8c45fSAndroid Build Coastguard Worker glLightxv(GL_LIGHT0, GL_POSITION, light0Position);
548*38e8c45fSAndroid Build Coastguard Worker glLightxv(GL_LIGHT0, GL_DIFFUSE, light0Diffuse);
549*38e8c45fSAndroid Build Coastguard Worker glLightxv(GL_LIGHT1, GL_POSITION, light1Position);
550*38e8c45fSAndroid Build Coastguard Worker glLightxv(GL_LIGHT1, GL_DIFFUSE, light1Diffuse);
551*38e8c45fSAndroid Build Coastguard Worker glLightxv(GL_LIGHT2, GL_POSITION, light2Position);
552*38e8c45fSAndroid Build Coastguard Worker glLightxv(GL_LIGHT2, GL_DIFFUSE, light2Diffuse);
553*38e8c45fSAndroid Build Coastguard Worker glMaterialxv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpecular);
554*38e8c45fSAndroid Build Coastguard Worker
555*38e8c45fSAndroid Build Coastguard Worker glMaterialx(GL_FRONT_AND_BACK, GL_SHININESS, 60 << 16);
556*38e8c45fSAndroid Build Coastguard Worker glEnable(GL_COLOR_MATERIAL);
557*38e8c45fSAndroid Build Coastguard Worker }
558*38e8c45fSAndroid Build Coastguard Worker
559*38e8c45fSAndroid Build Coastguard Worker
drawModels(float zScale)560*38e8c45fSAndroid Build Coastguard Worker static void drawModels(float zScale)
561*38e8c45fSAndroid Build Coastguard Worker {
562*38e8c45fSAndroid Build Coastguard Worker const int translationScale = 9;
563*38e8c45fSAndroid Build Coastguard Worker int x, y;
564*38e8c45fSAndroid Build Coastguard Worker
565*38e8c45fSAndroid Build Coastguard Worker seedRandom(9);
566*38e8c45fSAndroid Build Coastguard Worker
567*38e8c45fSAndroid Build Coastguard Worker glScalex(1 << 16, 1 << 16, (GLfixed)(zScale * 65536));
568*38e8c45fSAndroid Build Coastguard Worker
569*38e8c45fSAndroid Build Coastguard Worker for (y = -5; y <= 5; ++y)
570*38e8c45fSAndroid Build Coastguard Worker {
571*38e8c45fSAndroid Build Coastguard Worker for (x = -5; x <= 5; ++x)
572*38e8c45fSAndroid Build Coastguard Worker {
573*38e8c45fSAndroid Build Coastguard Worker float buildingScale;
574*38e8c45fSAndroid Build Coastguard Worker GLfixed fixedScale;
575*38e8c45fSAndroid Build Coastguard Worker
576*38e8c45fSAndroid Build Coastguard Worker int curShape = randomUInt() % SUPERSHAPE_COUNT;
577*38e8c45fSAndroid Build Coastguard Worker buildingScale = sSuperShapeParams[curShape][SUPERSHAPE_PARAMS - 1];
578*38e8c45fSAndroid Build Coastguard Worker fixedScale = (GLfixed)(buildingScale * 65536);
579*38e8c45fSAndroid Build Coastguard Worker
580*38e8c45fSAndroid Build Coastguard Worker glPushMatrix();
581*38e8c45fSAndroid Build Coastguard Worker glTranslatex((x * translationScale) * 65536,
582*38e8c45fSAndroid Build Coastguard Worker (y * translationScale) * 65536,
583*38e8c45fSAndroid Build Coastguard Worker 0);
584*38e8c45fSAndroid Build Coastguard Worker glRotatex((GLfixed)((randomUInt() % 360) << 16), 0, 0, 1 << 16);
585*38e8c45fSAndroid Build Coastguard Worker glScalex(fixedScale, fixedScale, fixedScale);
586*38e8c45fSAndroid Build Coastguard Worker
587*38e8c45fSAndroid Build Coastguard Worker drawGLObject(sSuperShapeObjects[curShape]);
588*38e8c45fSAndroid Build Coastguard Worker glPopMatrix();
589*38e8c45fSAndroid Build Coastguard Worker }
590*38e8c45fSAndroid Build Coastguard Worker }
591*38e8c45fSAndroid Build Coastguard Worker
592*38e8c45fSAndroid Build Coastguard Worker for (x = -2; x <= 2; ++x)
593*38e8c45fSAndroid Build Coastguard Worker {
594*38e8c45fSAndroid Build Coastguard Worker const int shipScale100 = translationScale * 500;
595*38e8c45fSAndroid Build Coastguard Worker const int offs100 = x * shipScale100 + (sTick % shipScale100);
596*38e8c45fSAndroid Build Coastguard Worker float offs = offs100 * 0.01f;
597*38e8c45fSAndroid Build Coastguard Worker GLfixed fixedOffs = (GLfixed)(offs * 65536);
598*38e8c45fSAndroid Build Coastguard Worker glPushMatrix();
599*38e8c45fSAndroid Build Coastguard Worker glTranslatex(fixedOffs, -4 * 65536, 2 << 16);
600*38e8c45fSAndroid Build Coastguard Worker drawGLObject(sSuperShapeObjects[SUPERSHAPE_COUNT - 1]);
601*38e8c45fSAndroid Build Coastguard Worker glPopMatrix();
602*38e8c45fSAndroid Build Coastguard Worker glPushMatrix();
603*38e8c45fSAndroid Build Coastguard Worker glTranslatex(-4 * 65536, fixedOffs, 4 << 16);
604*38e8c45fSAndroid Build Coastguard Worker glRotatex(90 << 16, 0, 0, 1 << 16);
605*38e8c45fSAndroid Build Coastguard Worker drawGLObject(sSuperShapeObjects[SUPERSHAPE_COUNT - 1]);
606*38e8c45fSAndroid Build Coastguard Worker glPopMatrix();
607*38e8c45fSAndroid Build Coastguard Worker }
608*38e8c45fSAndroid Build Coastguard Worker }
609*38e8c45fSAndroid Build Coastguard Worker
610*38e8c45fSAndroid Build Coastguard Worker
611*38e8c45fSAndroid Build Coastguard Worker /* Following gluLookAt implementation is adapted from the
612*38e8c45fSAndroid Build Coastguard Worker * Mesa 3D Graphics library. http://www.mesa3d.org
613*38e8c45fSAndroid Build Coastguard Worker */
gluLookAt(GLfloat eyex,GLfloat eyey,GLfloat eyez,GLfloat centerx,GLfloat centery,GLfloat centerz,GLfloat upx,GLfloat upy,GLfloat upz)614*38e8c45fSAndroid Build Coastguard Worker static void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
615*38e8c45fSAndroid Build Coastguard Worker GLfloat centerx, GLfloat centery, GLfloat centerz,
616*38e8c45fSAndroid Build Coastguard Worker GLfloat upx, GLfloat upy, GLfloat upz)
617*38e8c45fSAndroid Build Coastguard Worker {
618*38e8c45fSAndroid Build Coastguard Worker GLfloat m[16];
619*38e8c45fSAndroid Build Coastguard Worker GLfloat x[3], y[3], z[3];
620*38e8c45fSAndroid Build Coastguard Worker GLfloat mag;
621*38e8c45fSAndroid Build Coastguard Worker
622*38e8c45fSAndroid Build Coastguard Worker /* Make rotation matrix */
623*38e8c45fSAndroid Build Coastguard Worker
624*38e8c45fSAndroid Build Coastguard Worker /* Z vector */
625*38e8c45fSAndroid Build Coastguard Worker z[0] = eyex - centerx;
626*38e8c45fSAndroid Build Coastguard Worker z[1] = eyey - centery;
627*38e8c45fSAndroid Build Coastguard Worker z[2] = eyez - centerz;
628*38e8c45fSAndroid Build Coastguard Worker mag = (float)sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
629*38e8c45fSAndroid Build Coastguard Worker if (mag) { /* mpichler, 19950515 */
630*38e8c45fSAndroid Build Coastguard Worker z[0] /= mag;
631*38e8c45fSAndroid Build Coastguard Worker z[1] /= mag;
632*38e8c45fSAndroid Build Coastguard Worker z[2] /= mag;
633*38e8c45fSAndroid Build Coastguard Worker }
634*38e8c45fSAndroid Build Coastguard Worker
635*38e8c45fSAndroid Build Coastguard Worker /* Y vector */
636*38e8c45fSAndroid Build Coastguard Worker y[0] = upx;
637*38e8c45fSAndroid Build Coastguard Worker y[1] = upy;
638*38e8c45fSAndroid Build Coastguard Worker y[2] = upz;
639*38e8c45fSAndroid Build Coastguard Worker
640*38e8c45fSAndroid Build Coastguard Worker /* X vector = Y cross Z */
641*38e8c45fSAndroid Build Coastguard Worker x[0] = y[1] * z[2] - y[2] * z[1];
642*38e8c45fSAndroid Build Coastguard Worker x[1] = -y[0] * z[2] + y[2] * z[0];
643*38e8c45fSAndroid Build Coastguard Worker x[2] = y[0] * z[1] - y[1] * z[0];
644*38e8c45fSAndroid Build Coastguard Worker
645*38e8c45fSAndroid Build Coastguard Worker /* Recompute Y = Z cross X */
646*38e8c45fSAndroid Build Coastguard Worker y[0] = z[1] * x[2] - z[2] * x[1];
647*38e8c45fSAndroid Build Coastguard Worker y[1] = -z[0] * x[2] + z[2] * x[0];
648*38e8c45fSAndroid Build Coastguard Worker y[2] = z[0] * x[1] - z[1] * x[0];
649*38e8c45fSAndroid Build Coastguard Worker
650*38e8c45fSAndroid Build Coastguard Worker /* mpichler, 19950515 */
651*38e8c45fSAndroid Build Coastguard Worker /* cross product gives area of parallelogram, which is < 1.0 for
652*38e8c45fSAndroid Build Coastguard Worker * non-perpendicular unit-length vectors; so normalize x, y here
653*38e8c45fSAndroid Build Coastguard Worker */
654*38e8c45fSAndroid Build Coastguard Worker
655*38e8c45fSAndroid Build Coastguard Worker mag = (float)sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
656*38e8c45fSAndroid Build Coastguard Worker if (mag) {
657*38e8c45fSAndroid Build Coastguard Worker x[0] /= mag;
658*38e8c45fSAndroid Build Coastguard Worker x[1] /= mag;
659*38e8c45fSAndroid Build Coastguard Worker x[2] /= mag;
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker
662*38e8c45fSAndroid Build Coastguard Worker mag = (float)sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
663*38e8c45fSAndroid Build Coastguard Worker if (mag) {
664*38e8c45fSAndroid Build Coastguard Worker y[0] /= mag;
665*38e8c45fSAndroid Build Coastguard Worker y[1] /= mag;
666*38e8c45fSAndroid Build Coastguard Worker y[2] /= mag;
667*38e8c45fSAndroid Build Coastguard Worker }
668*38e8c45fSAndroid Build Coastguard Worker
669*38e8c45fSAndroid Build Coastguard Worker #define M(row,col) m[(col)*4+(row)]
670*38e8c45fSAndroid Build Coastguard Worker M(0, 0) = x[0];
671*38e8c45fSAndroid Build Coastguard Worker M(0, 1) = x[1];
672*38e8c45fSAndroid Build Coastguard Worker M(0, 2) = x[2];
673*38e8c45fSAndroid Build Coastguard Worker M(0, 3) = 0.0;
674*38e8c45fSAndroid Build Coastguard Worker M(1, 0) = y[0];
675*38e8c45fSAndroid Build Coastguard Worker M(1, 1) = y[1];
676*38e8c45fSAndroid Build Coastguard Worker M(1, 2) = y[2];
677*38e8c45fSAndroid Build Coastguard Worker M(1, 3) = 0.0;
678*38e8c45fSAndroid Build Coastguard Worker M(2, 0) = z[0];
679*38e8c45fSAndroid Build Coastguard Worker M(2, 1) = z[1];
680*38e8c45fSAndroid Build Coastguard Worker M(2, 2) = z[2];
681*38e8c45fSAndroid Build Coastguard Worker M(2, 3) = 0.0;
682*38e8c45fSAndroid Build Coastguard Worker M(3, 0) = 0.0;
683*38e8c45fSAndroid Build Coastguard Worker M(3, 1) = 0.0;
684*38e8c45fSAndroid Build Coastguard Worker M(3, 2) = 0.0;
685*38e8c45fSAndroid Build Coastguard Worker M(3, 3) = 1.0;
686*38e8c45fSAndroid Build Coastguard Worker #undef M
687*38e8c45fSAndroid Build Coastguard Worker {
688*38e8c45fSAndroid Build Coastguard Worker int a;
689*38e8c45fSAndroid Build Coastguard Worker GLfixed fixedM[16];
690*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < 16; ++a)
691*38e8c45fSAndroid Build Coastguard Worker fixedM[a] = (GLfixed)(m[a] * 65536);
692*38e8c45fSAndroid Build Coastguard Worker glMultMatrixx(fixedM);
693*38e8c45fSAndroid Build Coastguard Worker }
694*38e8c45fSAndroid Build Coastguard Worker
695*38e8c45fSAndroid Build Coastguard Worker /* Translate Eye to Origin */
696*38e8c45fSAndroid Build Coastguard Worker glTranslatex((GLfixed)(-eyex * 65536),
697*38e8c45fSAndroid Build Coastguard Worker (GLfixed)(-eyey * 65536),
698*38e8c45fSAndroid Build Coastguard Worker (GLfixed)(-eyez * 65536));
699*38e8c45fSAndroid Build Coastguard Worker }
700*38e8c45fSAndroid Build Coastguard Worker
701*38e8c45fSAndroid Build Coastguard Worker
camTrack()702*38e8c45fSAndroid Build Coastguard Worker static void camTrack()
703*38e8c45fSAndroid Build Coastguard Worker {
704*38e8c45fSAndroid Build Coastguard Worker float lerp[5];
705*38e8c45fSAndroid Build Coastguard Worker float eX, eY, eZ, cX, cY, cZ;
706*38e8c45fSAndroid Build Coastguard Worker float trackPos;
707*38e8c45fSAndroid Build Coastguard Worker CAMTRACK *cam;
708*38e8c45fSAndroid Build Coastguard Worker long currentCamTick;
709*38e8c45fSAndroid Build Coastguard Worker int a;
710*38e8c45fSAndroid Build Coastguard Worker
711*38e8c45fSAndroid Build Coastguard Worker if (sNextCamTrackStartTick <= sTick)
712*38e8c45fSAndroid Build Coastguard Worker {
713*38e8c45fSAndroid Build Coastguard Worker ++sCurrentCamTrack;
714*38e8c45fSAndroid Build Coastguard Worker sCurrentCamTrackStartTick = sNextCamTrackStartTick;
715*38e8c45fSAndroid Build Coastguard Worker }
716*38e8c45fSAndroid Build Coastguard Worker sNextCamTrackStartTick = sCurrentCamTrackStartTick +
717*38e8c45fSAndroid Build Coastguard Worker sCamTracks[sCurrentCamTrack].len * CAMTRACK_LEN;
718*38e8c45fSAndroid Build Coastguard Worker
719*38e8c45fSAndroid Build Coastguard Worker cam = &sCamTracks[sCurrentCamTrack];
720*38e8c45fSAndroid Build Coastguard Worker currentCamTick = sTick - sCurrentCamTrackStartTick;
721*38e8c45fSAndroid Build Coastguard Worker trackPos = (float)currentCamTick / (CAMTRACK_LEN * cam->len);
722*38e8c45fSAndroid Build Coastguard Worker
723*38e8c45fSAndroid Build Coastguard Worker for (a = 0; a < 5; ++a)
724*38e8c45fSAndroid Build Coastguard Worker lerp[a] = (cam->src[a] + cam->dest[a] * trackPos) * 0.01f;
725*38e8c45fSAndroid Build Coastguard Worker
726*38e8c45fSAndroid Build Coastguard Worker if (cam->dist)
727*38e8c45fSAndroid Build Coastguard Worker {
728*38e8c45fSAndroid Build Coastguard Worker float dist = cam->dist * 0.1f;
729*38e8c45fSAndroid Build Coastguard Worker cX = lerp[0];
730*38e8c45fSAndroid Build Coastguard Worker cY = lerp[1];
731*38e8c45fSAndroid Build Coastguard Worker cZ = lerp[2];
732*38e8c45fSAndroid Build Coastguard Worker eX = cX - (float)cos(lerp[3]) * dist;
733*38e8c45fSAndroid Build Coastguard Worker eY = cY - (float)sin(lerp[3]) * dist;
734*38e8c45fSAndroid Build Coastguard Worker eZ = cZ - lerp[4];
735*38e8c45fSAndroid Build Coastguard Worker }
736*38e8c45fSAndroid Build Coastguard Worker else
737*38e8c45fSAndroid Build Coastguard Worker {
738*38e8c45fSAndroid Build Coastguard Worker eX = lerp[0];
739*38e8c45fSAndroid Build Coastguard Worker eY = lerp[1];
740*38e8c45fSAndroid Build Coastguard Worker eZ = lerp[2];
741*38e8c45fSAndroid Build Coastguard Worker cX = eX + (float)cos(lerp[3]);
742*38e8c45fSAndroid Build Coastguard Worker cY = eY + (float)sin(lerp[3]);
743*38e8c45fSAndroid Build Coastguard Worker cZ = eZ + lerp[4];
744*38e8c45fSAndroid Build Coastguard Worker }
745*38e8c45fSAndroid Build Coastguard Worker gluLookAt(eX, eY, eZ, cX, cY, cZ, 0, 0, 1);
746*38e8c45fSAndroid Build Coastguard Worker }
747*38e8c45fSAndroid Build Coastguard Worker
748*38e8c45fSAndroid Build Coastguard Worker
749*38e8c45fSAndroid Build Coastguard Worker // Called from the app framework.
750*38e8c45fSAndroid Build Coastguard Worker /* The tick is current time in milliseconds, width and height
751*38e8c45fSAndroid Build Coastguard Worker * are the image dimensions to be rendered.
752*38e8c45fSAndroid Build Coastguard Worker */
appRender(long tick,int width,int height)753*38e8c45fSAndroid Build Coastguard Worker void appRender(long tick, int width, int height)
754*38e8c45fSAndroid Build Coastguard Worker {
755*38e8c45fSAndroid Build Coastguard Worker if (sStartTick == 0)
756*38e8c45fSAndroid Build Coastguard Worker sStartTick = tick;
757*38e8c45fSAndroid Build Coastguard Worker if (!gAppAlive)
758*38e8c45fSAndroid Build Coastguard Worker return;
759*38e8c45fSAndroid Build Coastguard Worker
760*38e8c45fSAndroid Build Coastguard Worker // Actual tick value is "blurred" a little bit.
761*38e8c45fSAndroid Build Coastguard Worker sTick = (sTick + tick - sStartTick) >> 1;
762*38e8c45fSAndroid Build Coastguard Worker
763*38e8c45fSAndroid Build Coastguard Worker // Terminate application after running through the demonstration once.
764*38e8c45fSAndroid Build Coastguard Worker if (sTick >= RUN_LENGTH)
765*38e8c45fSAndroid Build Coastguard Worker {
766*38e8c45fSAndroid Build Coastguard Worker gAppAlive = 0;
767*38e8c45fSAndroid Build Coastguard Worker return;
768*38e8c45fSAndroid Build Coastguard Worker }
769*38e8c45fSAndroid Build Coastguard Worker
770*38e8c45fSAndroid Build Coastguard Worker // Prepare OpenGL ES for rendering of the frame.
771*38e8c45fSAndroid Build Coastguard Worker prepareFrame(width, height);
772*38e8c45fSAndroid Build Coastguard Worker
773*38e8c45fSAndroid Build Coastguard Worker // Update the camera position and set the lookat.
774*38e8c45fSAndroid Build Coastguard Worker camTrack();
775*38e8c45fSAndroid Build Coastguard Worker
776*38e8c45fSAndroid Build Coastguard Worker // Configure environment.
777*38e8c45fSAndroid Build Coastguard Worker configureLightAndMaterial();
778*38e8c45fSAndroid Build Coastguard Worker
779*38e8c45fSAndroid Build Coastguard Worker // Draw the reflection by drawing models with negated Z-axis.
780*38e8c45fSAndroid Build Coastguard Worker glPushMatrix();
781*38e8c45fSAndroid Build Coastguard Worker drawModels(-1);
782*38e8c45fSAndroid Build Coastguard Worker glPopMatrix();
783*38e8c45fSAndroid Build Coastguard Worker
784*38e8c45fSAndroid Build Coastguard Worker // Blend the ground plane to the window.
785*38e8c45fSAndroid Build Coastguard Worker drawGroundPlane();
786*38e8c45fSAndroid Build Coastguard Worker
787*38e8c45fSAndroid Build Coastguard Worker // Draw all the models normally.
788*38e8c45fSAndroid Build Coastguard Worker drawModels(1);
789*38e8c45fSAndroid Build Coastguard Worker
790*38e8c45fSAndroid Build Coastguard Worker // Draw fade quad over whole window (when changing cameras).
791*38e8c45fSAndroid Build Coastguard Worker drawFadeQuad();
792*38e8c45fSAndroid Build Coastguard Worker }
793