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