146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo/* San Angeles Observation OpenGL ES version example 246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * Copyright 2004-2005 Jetro Lauha 346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * All rights reserved. 446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * Web: http://iki.fi/jetro/ 546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * 646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * This source is free software; you can redistribute it and/or 746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * modify it under the terms of EITHER: 846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * (1) The GNU Lesser General Public License as published by the Free 946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * Software Foundation; either version 2.1 of the License, or (at 1046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * your option) any later version. The text of the GNU Lesser 1146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * General Public License is included with this source in the 1246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * file LICENSE-LGPL.txt. 1346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * (2) The BSD-style license that is included with this source in 1446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * the file LICENSE-BSD.txt. 1546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * 1646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * This source is distributed in the hope that it will be useful, 1746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * but WITHOUT ANY WARRANTY; without even the implied warranty of 1846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files 1946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details. 2046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * 2146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * $Id: demo.c,v 1.10 2005/02/08 20:54:39 tonic Exp $ 2246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * $Revision: 1.10 $ 2346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 2446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 25c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo// The GLES2 implementation is adapted from the javascript implementation 26c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo// upon WebGL by kwaters@. 274545a8e20f4025c2d34bee31f38e45119ef40b22Zhenyao Mo 28c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo// The OpenGL implementation uses VBO extensions instead. 29c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 30c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#include <stdio.h> 3146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include <stdlib.h> 3246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include <math.h> 3346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include <float.h> 3446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include <assert.h> 3546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 36c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 37c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#undef IMPORTGL_API 38c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#undef IMPORTGL_FNPTRINIT 3946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include "importgl.h" 40c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#include "matrixop.h" 41c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#include "shader.h" 42c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // SAN_ANGELES_OBSERVATION_GLES 43c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#undef IMPORTVBO_API 44c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#undef IMPORTVBO_FNPTRINIT 45a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo#include "importvbo.h" 46c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 4746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 4846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include "app.h" 4946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include "shapes.h" 5046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#include "cams.h" 5146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 5246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 5346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Total run length is 20 * camera track base unit length (see cams.h). 5446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#define RUN_LENGTH (20 * CAMTRACK_LEN) 5546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#undef PI 5646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#define PI 3.1415926535897932f 5746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#define RANDOM_UINT_MAX 65535 5846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 5946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 6046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic unsigned long sRandomSeed = 0; 6146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 6246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void seedRandom(unsigned long seed) 6346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 6446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sRandomSeed = seed; 6546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 6646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 6746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic unsigned long randomUInt() 6846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 6946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sRandomSeed = sRandomSeed * 0x343fd + 0x269ec3; 7046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return sRandomSeed >> 16; 7146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 7246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 7346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 7446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Definition of one GL object in this demo. 7546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Motypedef struct { 7646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Vertex array and color array are enabled for all objects, so their 7746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * pointers must always be valid and non-NULL. Normal array is not 7846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * used by the ground plane, so when its pointer is NULL then normal 7946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * array usage is disabled. 8046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * 8146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * Vertex array is supposed to use GL_FIXED datatype and stride 0 8246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * (i.e. tightly packed array). Color array is supposed to have 4 8346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * components per color with GL_UNSIGNED_BYTE datatype and stride 0. 8446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * Normal array is supposed to use GL_FIXED datatype and stride 0. 8546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 86c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLfloat *vertexArray; 87c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLint vertexArraySize; 88fd97ee8636d2e52212eb5d4d8ba6450ec643263fIlja H. Friedel GLintptr vertexArrayOffset; 8946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLubyte *colorArray; 90c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLint colorArraySize; 91fd97ee8636d2e52212eb5d4d8ba6450ec643263fIlja H. Friedel GLintptr colorArrayOffset; 92c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLfloat *normalArray; 93c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLint normalArraySize; 94fd97ee8636d2e52212eb5d4d8ba6450ec643263fIlja H. Friedel GLintptr normalArrayOffset; 9546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLint vertexComponents; 9646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLsizei count; 97c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 98c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLuint shaderProgram; 99c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 10046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} GLOBJECT; 10146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 10246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 10346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic long sStartTick = 0; 10446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic long sTick = 0; 10546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 10646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic int sCurrentCamTrack = 0; 10746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic long sCurrentCamTrackStartTick = 0; 10846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic long sNextCamTrackStartTick = 0x7fffffff; 10946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 11046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic GLOBJECT *sSuperShapeObjects[SUPERSHAPE_COUNT] = { NULL }; 11146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic GLOBJECT *sGroundPlane = NULL; 1123eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mostatic GLOBJECT *sFadeQuad = NULL; 11346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 1143eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mostatic GLuint sVBO = 0; 11546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 11646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Motypedef struct { 11746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float x, y, z; 11846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} VECTOR3; 11946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 12046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 12146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void freeGLObject(GLOBJECT *object) 12246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 12346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (object == NULL) 12446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return; 125c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 12646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo free(object->normalArray); 12746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo free(object->colorArray); 12846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo free(object->vertexArray); 129c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 13046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo free(object); 13146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 13246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 13346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 13446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic GLOBJECT * newGLObject(long vertices, int vertexComponents, 1353eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo int useColorArray, int useNormalArray) 13646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 13746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLOBJECT *result; 138c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result = malloc(sizeof(GLOBJECT)); 13946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (result == NULL) 14046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return NULL; 14146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->count = vertices; 14246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->vertexComponents = vertexComponents; 143c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArraySize = vertices * vertexComponents * sizeof(GLfloat); 144c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray = malloc(result->vertexArraySize); 145c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArrayOffset = 0; 1463eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo if (useColorArray) 1473eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo { 1483eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result->colorArraySize = vertices * 4 * sizeof(GLubyte); 1493eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result->colorArray = malloc(result->colorArraySize); 1503eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo } 1513eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo else 1523eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo { 1533eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result->colorArraySize = 0; 1543eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result->colorArray = NULL; 1553eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo } 156c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->colorArrayOffset = result->vertexArrayOffset + 157c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArraySize; 15846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (useNormalArray) 15946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 160c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArraySize = vertices * 3 * sizeof(GLfloat); 161c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArray = malloc(result->normalArraySize); 16246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 16346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo else 164c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo { 165c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArraySize = 0; 16646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->normalArray = NULL; 167c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo } 168c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArrayOffset = result->colorArrayOffset + 169c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->colorArraySize; 17046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (result->vertexArray == NULL || 1713eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo (useColorArray && result->colorArray == NULL) || 17246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo (useNormalArray && result->normalArray == NULL)) 17346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 17446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo freeGLObject(result); 17546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return NULL; 17646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 177c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 178c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->shaderProgram = 0; 179c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 18046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return result; 18146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 18246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 18346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 1843eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mostatic void appendObjectVBO(GLOBJECT *object, GLint *offset) 185a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo{ 186a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo assert(object != NULL); 187a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo 1883eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo object->vertexArrayOffset += *offset; 1893eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo object->colorArrayOffset += *offset; 1903eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo object->normalArrayOffset += *offset; 1913eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo *offset += object->vertexArraySize + object->colorArraySize + 1923eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo object->normalArraySize; 19308f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel 194c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glBufferSubData(GL_ARRAY_BUFFER, object->vertexArrayOffset, 195c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo object->vertexArraySize, object->vertexArray); 1963eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo if (object->colorArray) 1973eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo glBufferSubData(GL_ARRAY_BUFFER, object->colorArrayOffset, 1983eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo object->colorArraySize, object->colorArray); 199a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo if (object->normalArray) 200c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glBufferSubData(GL_ARRAY_BUFFER, object->normalArrayOffset, 201c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo object->normalArraySize, object->normalArray); 202a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo 203a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo free(object->normalArray); 204c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo object->normalArray = NULL; 205a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo free(object->colorArray); 206c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo object->colorArray = NULL; 207a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo free(object->vertexArray); 208c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo object->vertexArray = NULL; 209a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo} 210a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo 211a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo 2123eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mostatic GLuint createVBO(GLOBJECT **superShapes, int superShapeCount, 2133eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo GLOBJECT *groundPlane, GLOBJECT *fadeQuad) 2143eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo{ 2153eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo GLuint vbo; 2163eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo GLint totalSize = 0; 2173eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo int a; 2183eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo for (a = 0; a < superShapeCount; ++a) 2193eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo { 2203eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo assert(superShapes[a] != NULL); 2213eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo totalSize += superShapes[a]->vertexArraySize + 2223eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo superShapes[a]->colorArraySize + 2233eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo superShapes[a]->normalArraySize; 2243eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo } 2253eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo totalSize += groundPlane->vertexArraySize + 2263eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo groundPlane->colorArraySize + 2273eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo groundPlane->normalArraySize; 2283eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo totalSize += fadeQuad->vertexArraySize + 2293eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo fadeQuad->colorArraySize + 2303eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo fadeQuad->normalArraySize; 23108f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel glGenBuffers(1, &vbo); 23208f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel glBindBuffer(GL_ARRAY_BUFFER, vbo); 2333eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo glBufferData(GL_ARRAY_BUFFER, totalSize, 0, GL_STATIC_DRAW); 2343eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo GLint offset = 0; 2353eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo for (a = 0; a < superShapeCount; ++a) 2363eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo appendObjectVBO(superShapes[a], &offset); 2373eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo appendObjectVBO(groundPlane, &offset); 2383eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo appendObjectVBO(fadeQuad, &offset); 2393eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo assert(offset == totalSize); 2403eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo return vbo; 2413eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo} 2423eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 2433eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 24446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void drawGLObject(GLOBJECT *object) 24546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 246c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 247c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo int loc_pos = -1; 248c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo int loc_colorIn = -1; 249c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo int loc_normal = -1; 250c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 25146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 252c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo assert(object != NULL); 253a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo 254c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 255c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo bindShaderProgram(object->shaderProgram); 256c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo if (object->shaderProgram == sShaderLit.program) 257a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo { 258c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo loc_pos = sShaderLit.pos; 259c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo loc_colorIn = sShaderLit.colorIn; 260c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo loc_normal = sShaderLit.normal; 261c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo } 262c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo else if (object->shaderProgram == sShaderFlat.program) 263c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo { 264c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo loc_pos = sShaderFlat.pos; 265c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo loc_colorIn = sShaderFlat.colorIn; 266a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo } 267a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo else 268c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo { 269c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo assert(0); 270c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo } 271c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glVertexAttribPointer(loc_pos, object->vertexComponents, GL_FLOAT, 27208f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel GL_FALSE, 0, (GLvoid *)object->vertexArrayOffset); 273c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glEnableVertexAttribArray(loc_pos); 274c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glVertexAttribPointer(loc_colorIn, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 27508f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel (GLvoid *)object->colorArrayOffset); 276c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glEnableVertexAttribArray(loc_colorIn); 277c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo if (object->normalArraySize > 0) 278c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo { 279c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glVertexAttribPointer(loc_normal, 3, GL_FLOAT, GL_FALSE, 0, 28008f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel (GLvoid *)object->normalArrayOffset); 281c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glEnableVertexAttribArray(loc_normal); 282c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo } 283a625f7322b08a512761b64ae1485d782dccee8a4Zhenyao Mo glDrawArrays(GL_TRIANGLES, 0, object->count); 28446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 285c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo if (object->normalArraySize > 0) 286c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glDisableVertexAttribArray(loc_normal); 287c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glDisableVertexAttribArray(loc_colorIn); 288c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glDisableVertexAttribArray(loc_pos); 289c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 290c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glVertexPointer(object->vertexComponents, GL_FLOAT, 0, 29108f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel (GLvoid *)object->vertexArrayOffset); 29208f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel glColorPointer(4, GL_UNSIGNED_BYTE, 0, (GLvoid *)object->colorArrayOffset); 293c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo if (object->normalArraySize > 0) 29446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 29508f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel glNormalPointer(GL_FLOAT, 0, (GLvoid *)object->normalArrayOffset); 29646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnableClientState(GL_NORMAL_ARRAY); 29746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 29846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo else 29946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisableClientState(GL_NORMAL_ARRAY); 30046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDrawArrays(GL_TRIANGLES, 0, object->count); 301c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 30246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 30346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 30446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 30546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void vector3Sub(VECTOR3 *dest, VECTOR3 *v1, VECTOR3 *v2) 30646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 30746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo dest->x = v1->x - v2->x; 30846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo dest->y = v1->y - v2->y; 30946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo dest->z = v1->z - v2->z; 31046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 31146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 31246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 31346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void superShapeMap(VECTOR3 *point, float r1, float r2, float t, float p) 31446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 31546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // sphere-mapping of supershape parameters 31646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo point->x = (float)(cos(t) * cos(p) / r1 / r2); 31746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo point->y = (float)(sin(t) * cos(p) / r1 / r2); 31846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo point->z = (float)(sin(p) / r2); 31946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 32046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 32146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 32246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic float ssFunc(const float t, const float *p) 32346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 32446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return (float)(pow(pow(fabs(cos(p[0] * t / 4)) / p[1], p[4]) + 32546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo pow(fabs(sin(p[0] * t / 4)) / p[2], p[5]), 1 / p[3])); 32646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 32746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 32846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 32946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Creates and returns a supershape object. 33046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Based on Paul Bourke's POV-Ray implementation. 33146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// http://astronomy.swin.edu.au/~pbourke/povray/supershape/ 33246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic GLOBJECT * createSuperShape(const float *params) 33346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 33446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int resol1 = (int)params[SUPERSHAPE_PARAMS - 3]; 33546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int resol2 = (int)params[SUPERSHAPE_PARAMS - 2]; 33646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // latitude 0 to pi/2 for no mirrored bottom 33746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // (latitudeBegin==0 for -pi/2 to pi/2 originally) 33846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int latitudeBegin = resol2 / 4; 33946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int latitudeEnd = resol2 / 2; // non-inclusive 34046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int longitudeCount = resol1; 34146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int latitudeCount = latitudeEnd - latitudeBegin; 34246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const long triangleCount = longitudeCount * latitudeCount * 2; 34346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const long vertices = triangleCount * 3; 34446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLOBJECT *result; 34546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float baseColor[3]; 34646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int a, longitude, latitude; 34746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo long currentVertex, currentQuad; 34846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 3493eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result = newGLObject(vertices, 3, 1, 1); 35046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (result == NULL) 35146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return NULL; 35246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 35346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (a = 0; a < 3; ++a) 35446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo baseColor[a] = ((randomUInt() % 155) + 100) / 255.f; 35546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 35646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo currentQuad = 0; 35746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo currentVertex = 0; 35846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 35946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // longitude -pi to pi 36046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (longitude = 0; longitude < longitudeCount; ++longitude) 36146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 36246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 36346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // latitude 0 to pi/2 36446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (latitude = latitudeBegin; latitude < latitudeEnd; ++latitude) 36546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 36646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float t1 = -PI + longitude * 2 * PI / resol1; 36746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float t2 = -PI + (longitude + 1) * 2 * PI / resol1; 36846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float p1 = -PI / 2 + latitude * 2 * PI / resol2; 36946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float p2 = -PI / 2 + (latitude + 1) * 2 * PI / resol2; 37046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float r0, r1, r2, r3; 37146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 37246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo r0 = ssFunc(t1, params); 37346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo r1 = ssFunc(p1, ¶ms[6]); 37446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo r2 = ssFunc(t2, params); 37546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo r3 = ssFunc(p2, ¶ms[6]); 37646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 37746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (r0 != 0 && r1 != 0 && r2 != 0 && r3 != 0) 37846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 37946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo VECTOR3 pa, pb, pc, pd; 38046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo VECTOR3 v1, v2, n; 38146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float ca; 38246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int i; 38346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo //float lenSq, invLenSq; 38446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 38546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo superShapeMap(&pa, r0, r1, t1, p1); 38646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo superShapeMap(&pb, r2, r1, t2, p1); 38746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo superShapeMap(&pc, r2, r3, t2, p2); 38846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo superShapeMap(&pd, r0, r3, t1, p2); 38946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 39046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // kludge to set lower edge of the object to fixed level 39146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (latitude == latitudeBegin + 1) 39246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo pa.z = pb.z = 0; 39346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 39446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo vector3Sub(&v1, &pb, &pa); 39546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo vector3Sub(&v2, &pd, &pa); 39646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 39746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Calculate normal with cross product. 39846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* i j k i j 39946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * v1.x v1.y v1.z | v1.x v1.y 40046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * v2.x v2.y v2.z | v2.x v2.y 40146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 40246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 40346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo n.x = v1.y * v2.z - v1.z * v2.y; 40446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo n.y = v1.z * v2.x - v1.x * v2.z; 40546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo n.z = v1.x * v2.y - v1.y * v2.x; 40646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 40746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Pre-normalization of the normals is disabled here because 40846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * they will be normalized anyway later due to automatic 40946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * normalization (GL_NORMALIZE). It is enabled because the 41046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * objects are scaled with glScale. 41146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 41246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* 41346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo lenSq = n.x * n.x + n.y * n.y + n.z * n.z; 41446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo invLenSq = (float)(1 / sqrt(lenSq)); 41546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo n.x *= invLenSq; 41646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo n.y *= invLenSq; 41746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo n.z *= invLenSq; 41846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 41946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 42046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ca = pa.z + 0.5f; 42146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 42246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (i = currentVertex * 3; 42346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo i < (currentVertex + 6) * 3; 42446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo i += 3) 42546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 426c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArray[i] = n.x; 427c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArray[i + 1] = n.y; 428c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->normalArray[i + 2] = n.z; 42946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 43046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (i = currentVertex * 4; 43146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo i < (currentVertex + 6) * 4; 43246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo i += 4) 43346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 43446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int a, color[3]; 43546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (a = 0; a < 3; ++a) 43646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 43746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo color[a] = (int)(ca * baseColor[a] * 255); 43846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (color[a] > 255) color[a] = 255; 43946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 44046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i] = (GLubyte)color[0]; 44146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i + 1] = (GLubyte)color[1]; 44246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i + 2] = (GLubyte)color[2]; 44346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i + 3] = 0; 44446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 445c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3] = pa.x; 446c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 1] = pa.y; 447c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 2] = pa.z; 44846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 449c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3] = pb.x; 450c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 1] = pb.y; 451c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 2] = pb.z; 45246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 453c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3] = pd.x; 454c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 1] = pd.y; 455c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 2] = pd.z; 45646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 457c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3] = pb.x; 458c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 1] = pb.y; 459c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 2] = pb.z; 46046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 461c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3] = pc.x; 462c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 1] = pc.y; 463c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 2] = pc.z; 46446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 465c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3] = pd.x; 466c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 1] = pd.y; 467c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 3 + 2] = pd.z; 46846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 46946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } // r0 && r1 && r2 && r3 47046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentQuad; 47146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } // latitude 47246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } // longitude 47346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 47446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Set number of vertices in object to the actual amount created. 47546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->count = currentVertex; 476c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 477c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->shaderProgram = sShaderLit.program; 478c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 47946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return result; 48046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 48146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 48246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 48346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic GLOBJECT * createGroundPlane() 48446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 48546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int scale = 4; 48646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int yBegin = -15, yEnd = 15; // ends are non-inclusive 48746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int xBegin = -15, xEnd = 15; 48846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const long triangleCount = (yEnd - yBegin) * (xEnd - xBegin) * 2; 48946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const long vertices = triangleCount * 3; 49046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLOBJECT *result; 49146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int x, y; 49246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo long currentVertex, currentQuad; 49346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 4943eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result = newGLObject(vertices, 2, 1, 0); 49546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (result == NULL) 49646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return NULL; 49746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 49846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo currentQuad = 0; 49946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo currentVertex = 0; 50046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 50146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (y = yBegin; y < yEnd; ++y) 50246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 50346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (x = xBegin; x < xEnd; ++x) 50446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 50546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLubyte color; 50646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int i, a; 50746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo color = (GLubyte)((randomUInt() & 0x5f) + 81); // 101 1111 50846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (i = currentVertex * 4; i < (currentVertex + 6) * 4; i += 4) 50946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 51046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i] = color; 51146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i + 1] = color; 51246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i + 2] = color; 51346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo result->colorArray[i + 3] = 0; 51446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 51546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 51646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Axis bits for quad triangles: 51746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // x: 011100 (0x1c), y: 110001 (0x31) (clockwise) 51846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // x: 001110 (0x0e), y: 100011 (0x23) (counter-clockwise) 51946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (a = 0; a < 6; ++a) 52046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 52146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int xm = x + ((0x1c >> a) & 1); 52246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int ym = y + ((0x31 >> a) & 1); 52346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const float m = (float)(cos(xm * 2) * sin(ym * 4) * 0.75f); 524c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 2] = xm * scale + m; 525c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->vertexArray[currentVertex * 2 + 1] = ym * scale + m; 52646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentVertex; 52746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 52846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++currentQuad; 52946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 53046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 531c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 532c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo result->shaderProgram = sShaderFlat.program; 533c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 53446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return result; 53546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 53646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 53746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 53846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void drawGroundPlane() 53946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 54046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_CULL_FACE); 54146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_DEPTH_TEST); 54246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_BLEND); 54346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glBlendFunc(GL_ZERO, GL_SRC_COLOR); 544c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifndef SAN_ANGELES_OBSERVATION_GLES 54546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_LIGHTING); 546c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // !SAN_ANGELES_OBSERVATION_GLES 54746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 54846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawGLObject(sGroundPlane); 54946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 550c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifndef SAN_ANGELES_OBSERVATION_GLES 55146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_LIGHTING); 552c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // !SAN_ANGELES_OBSERVATION_GLES 55346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_BLEND); 55446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_DEPTH_TEST); 55546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 55646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 55746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 5583eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mostatic GLOBJECT * createFadeQuad() 55946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 560c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo static const GLfloat quadVertices[] = { 5613eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo -1, -1, 5623eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 1, -1, 5633eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo -1, 1, 5643eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 1, -1, 5653eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 1, 1, 5663eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo -1, 1 56746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo }; 56846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 5693eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo GLOBJECT *result; 5703eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo int i; 5713eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 5723eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result = newGLObject(6, 2, 0, 0); 5733eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo if (result == NULL) 5743eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo return NULL; 5753eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 5763eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo for (i = 0; i < 12; ++i) 5773eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result->vertexArray[i] = quadVertices[i]; 5783eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 5793eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 5803eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo result->shaderProgram = sShaderFade.program; 5813eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 5823eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo return result; 5833eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo} 5843eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 5853eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo 5863eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mostatic void drawFadeQuad() 5873eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo{ 58846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int beginFade = sTick - sCurrentCamTrackStartTick; 58946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int endFade = sNextCamTrackStartTick - sTick; 59046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int minFade = beginFade < endFade ? beginFade : endFade; 59146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 59246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (minFade < 1024) 59346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 594c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo const GLfloat fadeColor = minFade / 1024.f; 59546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_DEPTH_TEST); 59646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_BLEND); 59746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glBlendFunc(GL_ZERO, GL_SRC_COLOR); 598c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 599c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo bindShaderProgram(sShaderFade.program); 600c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform1f(sShaderFade.minFade, fadeColor); 6013eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo glVertexAttribPointer(sShaderFade.pos, 2, GL_FLOAT, GL_FALSE, 0, 60208f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel (GLvoid *)sFadeQuad->vertexArrayOffset); 603c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glEnableVertexAttribArray(sShaderFade.pos); 604c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glDrawArrays(GL_TRIANGLES, 0, 6); 605c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glDisableVertexAttribArray(sShaderFade.pos); 606c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 607c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glColor4f(fadeColor, fadeColor, fadeColor, 0); 608c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 60946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_LIGHTING); 61046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 61146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glMatrixMode(GL_MODELVIEW); 61246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glLoadIdentity(); 61346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 61446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glMatrixMode(GL_PROJECTION); 61546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glLoadIdentity(); 61646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 61746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisableClientState(GL_COLOR_ARRAY); 61846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisableClientState(GL_NORMAL_ARRAY); 61908f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel glVertexPointer(2, GL_FLOAT, 0, (GLvoid *)sFadeQuad->vertexArrayOffset); 6204545a8e20f4025c2d34bee31f38e45119ef40b22Zhenyao Mo 62146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDrawArrays(GL_TRIANGLES, 0, 6); 62246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 62346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnableClientState(GL_COLOR_ARRAY); 62446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 62546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glMatrixMode(GL_MODELVIEW); 62646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 62746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_LIGHTING); 628c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 62946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_BLEND); 63046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_DEPTH_TEST); 63146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 63246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 63346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 63446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 63546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Called from the app framework. 636c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Moint appInit() 63746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 63846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int a; 639c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo static GLfloat light0Diffuse[] = { 1.f, 0.4f, 0, 1.f }; 640c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo static GLfloat light1Diffuse[] = { 0.07f, 0.14f, 0.35f, 1.f }; 641c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo static GLfloat light2Diffuse[] = { 0.07f, 0.17f, 0.14f, 1.f }; 642c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo static GLfloat materialSpecular[] = { 1.f, 1.f, 1.f, 1.f }; 643c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 644c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo static GLfloat lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.f }; 645c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 64646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 64746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glDisable(GL_CULL_FACE); 648c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glEnable(GL_DEPTH_TEST); 649c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 650c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo if (initShaderPrograms() == 0) 651c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo { 65208f9dd023db83e838b93b46e432e3e8bfe6680d1Ilja H. Friedel fprintf(stderr, "Error: initShaderPrograms failed\n"); 653c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo return 0; 654c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo } 655c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 65646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glShadeModel(GL_FLAT); 657c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glEnable(GL_NORMALIZE); 65846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 65946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_LIGHTING); 66046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_LIGHT0); 66146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_LIGHT1); 66246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_LIGHT2); 66346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 66446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnableClientState(GL_VERTEX_ARRAY); 66546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnableClientState(GL_COLOR_ARRAY); 666c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 66746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo seedRandom(15); 66846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 66946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (a = 0; a < SUPERSHAPE_COUNT; ++a) 67046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 67146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sSuperShapeObjects[a] = createSuperShape(sSuperShapeParams[a]); 67246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo assert(sSuperShapeObjects[a] != NULL); 67346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 67446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sGroundPlane = createGroundPlane(); 67546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo assert(sGroundPlane != NULL); 6763eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo sFadeQuad = createFadeQuad(); 6773eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo assert(sFadeQuad != NULL); 6783eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo sVBO = createVBO(sSuperShapeObjects, SUPERSHAPE_COUNT, 6793eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo sGroundPlane, sFadeQuad); 680c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 681c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo // setup non-changing lighting parameters 682c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 683c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo bindShaderProgram(sShaderLit.program); 684c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform4fv(sShaderLit.ambient, 1, lightAmbient); 685c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform4fv(sShaderLit.light_0_diffuse, 1, light0Diffuse); 686c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform4fv(sShaderLit.light_1_diffuse, 1, light1Diffuse); 687c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform4fv(sShaderLit.light_2_diffuse, 1, light2Diffuse); 688c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform4fv(sShaderLit.light_0_specular, 1, materialSpecular); 689c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform1f(sShaderLit.shininess, 60.f); 690c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 691c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diffuse); 692c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glLightfv(GL_LIGHT1, GL_DIFFUSE, light1Diffuse); 693c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glLightfv(GL_LIGHT2, GL_DIFFUSE, light2Diffuse); 694c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpecular); 695c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60); 696c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 697c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo return 1; 69846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 69946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 70046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 70146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Called from the app framework. 70246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Movoid appDeinit() 70346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 70446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int a; 70546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (a = 0; a < SUPERSHAPE_COUNT; ++a) 70646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo freeGLObject(sSuperShapeObjects[a]); 70746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo freeGLObject(sGroundPlane); 7083eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo freeGLObject(sFadeQuad); 7093eba93a219c446c336a33e4e3288779eade2ef16Zhenyao Mo glDeleteBuffers(1, &sVBO); 710c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 711c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo deInitShaderPrograms(); 712c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 71346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 71446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 715c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifndef SAN_ANGELES_OBSERVATION_GLES 71646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void gluPerspective(GLfloat fovy, GLfloat aspect, 71746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat zNear, GLfloat zFar) 71846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 71946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat xmin, xmax, ymin, ymax; 72046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 72146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ymax = zNear * (GLfloat)tan(fovy * PI / 360); 72246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ymin = -ymax; 72346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo xmin = ymin * aspect; 72446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo xmax = ymax * aspect; 72546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 726c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glFrustum(xmin, xmax, ymin, ymax, zNear, zFar); 72746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 728c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // !SAN_ANGELES_OBSERVATION_GLES 72946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 73046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void prepareFrame(int width, int height) 73146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 73246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glViewport(0, 0, width, height); 73346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 734c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glClearColor(0.1f, 0.2f, 0.3f, 1.f); 73546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 73646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 737c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 738c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_LoadIdentity(sProjection); 739c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Perspective(sProjection, 740c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 45.f, (float)width / height, 0.5f, 150); 741c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 742c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_LoadIdentity(sModelView); 743c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 74446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glMatrixMode(GL_PROJECTION); 74546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glLoadIdentity(); 74646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo gluPerspective(45, (float)width / height, 0.5f, 150); 74746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 74846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glMatrixMode(GL_MODELVIEW); 74946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glLoadIdentity(); 750c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 75146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 75246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 75346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 75446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void configureLightAndMaterial() 75546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 756c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLfloat light0Position[] = { -4.f, 1.f, 1.f, 0 }; 757c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLfloat light1Position[] = { 1.f, -2.f, -1.f, 0 }; 758c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo GLfloat light2Position[] = { -1.f, 0, -4.f, 0 }; 759c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 760c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 761c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Transform(sModelView, 762c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo light0Position, light0Position + 1, light0Position + 2); 763c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Transform(sModelView, 764c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo light1Position, light1Position + 1, light1Position + 2); 765c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Transform(sModelView, 766c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo light2Position, light2Position + 1, light2Position + 2); 767c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 768c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo bindShaderProgram(sShaderLit.program); 769c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform3fv(sShaderLit.light_0_direction, 1, light0Position); 770c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform3fv(sShaderLit.light_1_direction, 1, light1Position); 771c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glUniform3fv(sShaderLit.light_2_direction, 1, light2Position); 772c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 773c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glLightfv(GL_LIGHT0, GL_POSITION, light0Position); 774c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glLightfv(GL_LIGHT1, GL_POSITION, light1Position); 775c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glLightfv(GL_LIGHT2, GL_POSITION, light2Position); 776c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 77746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glEnable(GL_COLOR_MATERIAL); 778c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 77946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 78046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 78146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 78246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void drawModels(float zScale) 78346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 78446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int translationScale = 9; 78546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int x, y; 78646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 78746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo seedRandom(9); 78846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 789c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 790c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Scale(sModelView, 1.f, 1.f, zScale); 791c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 792c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glScalef(1.f, 1.f, zScale); 793c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 79446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 79546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (y = -5; y <= 5; ++y) 79646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 79746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (x = -5; x <= 5; ++x) 79846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 79946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float buildingScale; 800c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 801c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4 tmp; 802c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 80346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 80446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int curShape = randomUInt() % SUPERSHAPE_COUNT; 80546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo buildingScale = sSuperShapeParams[curShape][SUPERSHAPE_PARAMS - 1]; 806c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 807c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(tmp, sModelView); 808c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Translate(sModelView, x * translationScale, 809c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo y * translationScale, 0); 810c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Rotate(sModelView, randomUInt() % 360, 0, 0, 1.f); 811c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Scale(sModelView, 812c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo buildingScale, buildingScale, buildingScale); 81346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 814c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo drawGLObject(sSuperShapeObjects[curShape]); 815c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(sModelView, tmp); 816c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 81746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPushMatrix(); 818c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glTranslatef(x * translationScale, y * translationScale, 0); 819c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glRotatef(randomUInt() % 360, 0, 0, 1.f); 820c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glScalef(buildingScale, buildingScale, buildingScale); 82146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 82246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawGLObject(sSuperShapeObjects[curShape]); 82346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPopMatrix(); 824c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 82546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 82646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 82746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 82846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (x = -2; x <= 2; ++x) 82946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 83046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int shipScale100 = translationScale * 500; 83146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo const int offs100 = x * shipScale100 + (sTick % shipScale100); 83246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float offs = offs100 * 0.01f; 833c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 834c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4 tmp; 835c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(tmp, sModelView); 836c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Translate(sModelView, offs, -4.f, 2.f); 837c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo drawGLObject(sSuperShapeObjects[SUPERSHAPE_COUNT - 1]); 838c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(sModelView, tmp); 839c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Translate(sModelView, -4.f, offs, 4.f); 840c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Rotate(sModelView, 90.f, 0, 0, 1.f); 841c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo drawGLObject(sSuperShapeObjects[SUPERSHAPE_COUNT - 1]); 842c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(sModelView, tmp); 843c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 84446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPushMatrix(); 845c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glTranslatef(offs, -4.f, 2.f); 84646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawGLObject(sSuperShapeObjects[SUPERSHAPE_COUNT - 1]); 84746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPopMatrix(); 84846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPushMatrix(); 849c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glTranslatef(-4.f, offs, 4.f); 850c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glRotatef(90.f, 0, 0, 1.f); 85146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawGLObject(sSuperShapeObjects[SUPERSHAPE_COUNT - 1]); 85246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPopMatrix(); 853c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 85446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 85546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 85646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 85746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo/* Following gluLookAt implementation is adapted from the 85846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * Mesa 3D Graphics library. http://www.mesa3d.org 85946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 86046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, 86146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat centerx, GLfloat centery, GLfloat centerz, 86246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat upx, GLfloat upy, GLfloat upz) 86346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 864c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 865c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4 m; 866c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 86746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat m[16]; 868c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 86946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat x[3], y[3], z[3]; 87046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo GLfloat mag; 87146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 87246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Make rotation matrix */ 87346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 87446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Z vector */ 87546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo z[0] = eyex - centerx; 87646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo z[1] = eyey - centery; 87746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo z[2] = eyez - centerz; 87846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo mag = (float)sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); 87946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (mag) { /* mpichler, 19950515 */ 88046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo z[0] /= mag; 88146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo z[1] /= mag; 88246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo z[2] /= mag; 88346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 88446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 88546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Y vector */ 88646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[0] = upx; 88746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[1] = upy; 88846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[2] = upz; 88946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 89046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* X vector = Y cross Z */ 89146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo x[0] = y[1] * z[2] - y[2] * z[1]; 89246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo x[1] = -y[0] * z[2] + y[2] * z[0]; 89346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo x[2] = y[0] * z[1] - y[1] * z[0]; 89446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 89546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Recompute Y = Z cross X */ 89646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[0] = z[1] * x[2] - z[2] * x[1]; 89746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[1] = -z[0] * x[2] + z[2] * x[0]; 89846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[2] = z[0] * x[1] - z[1] * x[0]; 89946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 90046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* mpichler, 19950515 */ 90146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* cross product gives area of parallelogram, which is < 1.0 for 90246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * non-perpendicular unit-length vectors; so normalize x, y here 90346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 90446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 90546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo mag = (float)sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); 90646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (mag) { 90746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo x[0] /= mag; 90846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo x[1] /= mag; 90946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo x[2] /= mag; 91046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 91146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 91246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo mag = (float)sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); 91346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (mag) { 91446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[0] /= mag; 91546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[1] /= mag; 91646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo y[2] /= mag; 91746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 91846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 919c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 920c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#define M(row, col) m[col*4 + row] 92146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(0, 0) = x[0]; 92246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(0, 1) = x[1]; 92346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(0, 2) = x[2]; 92446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(0, 3) = 0.0; 92546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(1, 0) = y[0]; 92646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(1, 1) = y[1]; 92746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(1, 2) = y[2]; 92846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(1, 3) = 0.0; 92946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(2, 0) = z[0]; 93046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(2, 1) = z[1]; 93146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(2, 2) = z[2]; 93246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(2, 3) = 0.0; 93346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(3, 0) = 0.0; 93446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(3, 1) = 0.0; 93546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(3, 2) = 0.0; 93646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo M(3, 3) = 1.0; 93746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo#undef M 938c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 939c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Multiply(sModelView, m, sModelView); 940c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 941c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Translate(sModelView, -eyex, -eyey, -eyez); 942c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 943c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#define M(row, col) m[col*4 + row] 944c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(0, 0) = x[0]; 945c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(0, 1) = x[1]; 946c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(0, 2) = x[2]; 947c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(0, 3) = 0.0; 948c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(1, 0) = y[0]; 949c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(1, 1) = y[1]; 950c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(1, 2) = y[2]; 951c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(1, 3) = 0.0; 952c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(2, 0) = z[0]; 953c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(2, 1) = z[1]; 954c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(2, 2) = z[2]; 955c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(2, 3) = 0.0; 956c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(3, 0) = 0.0; 957c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(3, 1) = 0.0; 958c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(3, 2) = 0.0; 959c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo M(3, 3) = 1.0; 960c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#undef M 961c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 962c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glMultMatrixf(m); 96346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 96446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo /* Translate Eye to Origin */ 965c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo glTranslatef(-eyex, -eyey, -eyez); 966c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 96746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 96846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 96946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mostatic void camTrack() 97046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 97146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float lerp[5]; 97246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float eX, eY, eZ, cX, cY, cZ; 97346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float trackPos; 97446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo CAMTRACK *cam; 97546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo long currentCamTick; 97646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo int a; 97746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 97846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (sNextCamTrackStartTick <= sTick) 97946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 98046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo ++sCurrentCamTrack; 98146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sCurrentCamTrackStartTick = sNextCamTrackStartTick; 98246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 98346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sNextCamTrackStartTick = sCurrentCamTrackStartTick + 98446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sCamTracks[sCurrentCamTrack].len * CAMTRACK_LEN; 98546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 98646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cam = &sCamTracks[sCurrentCamTrack]; 98746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo currentCamTick = sTick - sCurrentCamTrackStartTick; 98846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo trackPos = (float)currentCamTick / (CAMTRACK_LEN * cam->len); 98946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 99046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo for (a = 0; a < 5; ++a) 99146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo lerp[a] = (cam->src[a] + cam->dest[a] * trackPos) * 0.01f; 99246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 99346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (cam->dist) 99446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 99546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo float dist = cam->dist * 0.1f; 99646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cX = lerp[0]; 99746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cY = lerp[1]; 99846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cZ = lerp[2]; 99946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo eX = cX - (float)cos(lerp[3]) * dist; 100046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo eY = cY - (float)sin(lerp[3]) * dist; 100146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo eZ = cZ - lerp[4]; 100246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 100346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo else 100446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 100546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo eX = lerp[0]; 100646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo eY = lerp[1]; 100746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo eZ = lerp[2]; 100846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cX = eX + (float)cos(lerp[3]); 100946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cY = eY + (float)sin(lerp[3]); 101046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo cZ = eZ + lerp[4]; 101146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 101246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo gluLookAt(eX, eY, eZ, cX, cY, cZ, 0, 0, 1); 101346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 101446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 101546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 101646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo// Called from the app framework. 101746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo/* The tick is current time in milliseconds, width and height 101846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo * are the image dimensions to be rendered. 101946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo */ 102046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Movoid appRender(long tick, int width, int height) 102146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo{ 1022c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 1023c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4 tmp; 1024c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES 1025c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo 102646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (sStartTick == 0) 102746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sStartTick = tick; 102846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (!gAppAlive) 102946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return; 103046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 103146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Actual tick value is "blurred" a little bit. 103246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo sTick = (sTick + tick - sStartTick) >> 1; 103346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 103446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Terminate application after running through the demonstration once. 103546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo if (sTick >= RUN_LENGTH) 103646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo { 103746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo gAppAlive = 0; 103846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo return; 103946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo } 104046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 104146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Prepare OpenGL ES for rendering of the frame. 104246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo prepareFrame(width, height); 104346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 104446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Update the camera position and set the lookat. 104546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo camTrack(); 104646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 104746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Configure environment. 104846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo configureLightAndMaterial(); 104946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 105046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Draw the reflection by drawing models with negated Z-axis. 1051c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#ifdef SAN_ANGELES_OBSERVATION_GLES 1052c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(tmp, sModelView); 1053c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo drawModels(-1); 1054c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo Matrix4x4_Copy(sModelView, tmp); 1055c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#else // !SAN_ANGELES_OBSERVATION_GLES 105646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPushMatrix(); 105746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawModels(-1); 105846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo glPopMatrix(); 1059c8ab85b5ab0cf6bc500d8b31cfcb199a7107c8e8Zhenyao Mo#endif // SAN_ANGELES_OBSERVATION_GLES | !SAN_ANGELES_OBSERVATION_GLES 106046645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 106146645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Blend the ground plane to the window. 106246645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawGroundPlane(); 106346645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 106446645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Draw all the models normally. 106546645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawModels(1); 106646645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo 106746645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo // Draw fade quad over whole window (when changing cameras). 106846645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo drawFadeQuad(); 106946645d3bc30237d5be6552a255c9100fd6d1c5c3Zhenyao Mo} 10704545a8e20f4025c2d34bee31f38e45119ef40b22Zhenyao Mo 1071