auto import from //depot/cupcake/@135843
This commit is contained in:
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A class that draws a ring with a given center and inner and outer radii.
|
||||
* The inner and outer rings each have a color and the remaining pixels are
|
||||
* colored by interpolation. GlobalTime uses this class to simulate an
|
||||
* "atmosphere" around the earth.
|
||||
*/
|
||||
public class Annulus extends Shape {
|
||||
|
||||
/**
|
||||
* Constructs an annulus.
|
||||
*
|
||||
* @param centerX the X coordinate of the center point
|
||||
* @param centerY the Y coordinate of the center point
|
||||
* @param Z the fixed Z for the entire ring
|
||||
* @param innerRadius the inner radius
|
||||
* @param outerRadius the outer radius
|
||||
* @param rInner the red channel of the color of the inner ring
|
||||
* @param gInner the green channel of the color of the inner ring
|
||||
* @param bInner the blue channel of the color of the inner ring
|
||||
* @param aInner the alpha channel of the color of the inner ring
|
||||
* @param rOuter the red channel of the color of the outer ring
|
||||
* @param gOuter the green channel of the color of the outer ring
|
||||
* @param bOuter the blue channel of the color of the outer ring
|
||||
* @param aOuter the alpha channel of the color of the outer ring
|
||||
* @param sectors the number of sectors used to approximate curvature
|
||||
*/
|
||||
public Annulus(float centerX, float centerY, float Z,
|
||||
float innerRadius, float outerRadius,
|
||||
float rInner, float gInner, float bInner, float aInner,
|
||||
float rOuter, float gOuter, float bOuter, float aOuter,
|
||||
int sectors) {
|
||||
super(GL10.GL_TRIANGLES, GL10.GL_UNSIGNED_SHORT,
|
||||
false, false, true);
|
||||
|
||||
int radii = sectors + 1;
|
||||
|
||||
int[] vertices = new int[2 * 3 * radii];
|
||||
int[] colors = new int[2 * 4 * radii];
|
||||
short[] indices = new short[2 * 3 * radii];
|
||||
|
||||
int vidx = 0;
|
||||
int cidx = 0;
|
||||
int iidx = 0;
|
||||
|
||||
for (int i = 0; i < radii; i++) {
|
||||
float theta = (i * TWO_PI) / (radii - 1);
|
||||
float cosTheta = (float) Math.cos(theta);
|
||||
float sinTheta = (float) Math.sin(theta);
|
||||
|
||||
vertices[vidx++] = toFixed(centerX + innerRadius * cosTheta);
|
||||
vertices[vidx++] = toFixed(centerY + innerRadius * sinTheta);
|
||||
vertices[vidx++] = toFixed(Z);
|
||||
|
||||
vertices[vidx++] = toFixed(centerX + outerRadius * cosTheta);
|
||||
vertices[vidx++] = toFixed(centerY + outerRadius * sinTheta);
|
||||
vertices[vidx++] = toFixed(Z);
|
||||
|
||||
colors[cidx++] = toFixed(rInner);
|
||||
colors[cidx++] = toFixed(gInner);
|
||||
colors[cidx++] = toFixed(bInner);
|
||||
colors[cidx++] = toFixed(aInner);
|
||||
|
||||
colors[cidx++] = toFixed(rOuter);
|
||||
colors[cidx++] = toFixed(gOuter);
|
||||
colors[cidx++] = toFixed(bOuter);
|
||||
colors[cidx++] = toFixed(aOuter);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sectors; i++) {
|
||||
indices[iidx++] = (short) (2 * i);
|
||||
indices[iidx++] = (short) (2 * i + 1);
|
||||
indices[iidx++] = (short) (2 * i + 2);
|
||||
|
||||
indices[iidx++] = (short) (2 * i + 1);
|
||||
indices[iidx++] = (short) (2 * i + 3);
|
||||
indices[iidx++] = (short) (2 * i + 2);
|
||||
}
|
||||
|
||||
allocateBuffers(vertices, null, null, colors, indices);
|
||||
}
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* A class representing a city, with an associated position, time zone name,
|
||||
* and raw offset from UTC.
|
||||
*/
|
||||
public class City implements Comparable<City> {
|
||||
|
||||
private static Map<String,City> cities = new HashMap<String,City>();
|
||||
private static City[] citiesByRawOffset;
|
||||
|
||||
private String name;
|
||||
private String timeZoneID;
|
||||
private TimeZone timeZone = null;
|
||||
private int rawOffset;
|
||||
private float latitude, longitude;
|
||||
private float x, y, z;
|
||||
|
||||
/**
|
||||
* Loads the city database. The cities must be stored in order by raw
|
||||
* offset from UTC.
|
||||
*/
|
||||
public static void loadCities(InputStream is) throws IOException {
|
||||
DataInputStream dis = new DataInputStream(is);
|
||||
int numCities = dis.readInt();
|
||||
citiesByRawOffset = new City[numCities];
|
||||
|
||||
byte[] buf = new byte[24];
|
||||
for (int i = 0; i < numCities; i++) {
|
||||
String name = dis.readUTF();
|
||||
String tzid = dis.readUTF();
|
||||
dis.read(buf);
|
||||
|
||||
// The code below is a faster version of:
|
||||
// int rawOffset = dis.readInt();
|
||||
// float latitude = dis.readFloat();
|
||||
// float longitude = dis.readFloat();
|
||||
// float cx = dis.readFloat();
|
||||
// float cy = dis.readFloat();
|
||||
// float cz = dis.readFloat();
|
||||
|
||||
int rawOffset =
|
||||
(buf[ 0] << 24) | ((buf[ 1] & 0xff) << 16) |
|
||||
((buf[ 2] & 0xff) << 8) | (buf[ 3] & 0xff);
|
||||
int ilat = (buf[ 4] << 24) | ((buf[ 5] & 0xff) << 16) |
|
||||
((buf[ 6] & 0xff) << 8) | (buf[ 7] & 0xff);
|
||||
int ilon = (buf[ 8] << 24) | ((buf[ 9] & 0xff) << 16) |
|
||||
((buf[10] & 0xff) << 8) | (buf[11] & 0xff);
|
||||
int icx = (buf[12] << 24) | ((buf[13] & 0xff) << 16) |
|
||||
((buf[14] & 0xff) << 8) | (buf[15] & 0xff);
|
||||
int icy = (buf[16] << 24) | ((buf[17] & 0xff) << 16) |
|
||||
((buf[18] & 0xff) << 8) | (buf[19] & 0xff);
|
||||
int icz = (buf[20] << 24) | ((buf[21] & 0xff) << 16) |
|
||||
((buf[22] & 0xff) << 8) | (buf[23] & 0xff);
|
||||
float latitude = Float.intBitsToFloat(ilat);
|
||||
float longitude = Float.intBitsToFloat(ilon);
|
||||
float cx = Float.intBitsToFloat(icx);
|
||||
float cy = Float.intBitsToFloat(icy);
|
||||
float cz = Float.intBitsToFloat(icz);
|
||||
|
||||
City city = new City(name, tzid, rawOffset,
|
||||
latitude, longitude, cx, cy, cz);
|
||||
|
||||
cities.put(name, city);
|
||||
citiesByRawOffset[i] = city;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cities, ordered by name.
|
||||
*/
|
||||
public static City[] getCitiesByName() {
|
||||
City[] ocities = new City[cities.size()];
|
||||
Iterator<City> iter = cities.values().iterator();
|
||||
int idx = 0;
|
||||
while (iter.hasNext()) {
|
||||
ocities[idx++] = iter.next();
|
||||
}
|
||||
Arrays.sort(ocities);
|
||||
return ocities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cities, ordered by offset, accounting for summer/daylight
|
||||
* savings time. This requires reading the entire time zone database
|
||||
* behind the scenes.
|
||||
*/
|
||||
public static City[] getCitiesByOffset() {
|
||||
City[] ocities = new City[cities.size()];
|
||||
Iterator<City> iter = cities.values().iterator();
|
||||
int idx = 0;
|
||||
while (iter.hasNext()) {
|
||||
ocities[idx++] = iter.next();
|
||||
}
|
||||
Arrays.sort(ocities, new Comparator() {
|
||||
public int compare(Object o1, Object o2) {
|
||||
long now = System.currentTimeMillis();
|
||||
City c1 = (City)o1;
|
||||
City c2 = (City)o2;
|
||||
TimeZone tz1 = c1.getTimeZone();
|
||||
TimeZone tz2 = c2.getTimeZone();
|
||||
int off1 = tz1.getOffset(now);
|
||||
int off2 = tz2.getOffset(now);
|
||||
if (off1 == off2) {
|
||||
float dlat = c2.getLatitude() - c1.getLatitude();
|
||||
if (dlat < 0.0f) return -1;
|
||||
if (dlat > 0.0f) return 1;
|
||||
return 0;
|
||||
}
|
||||
return off1 - off2;
|
||||
}
|
||||
});
|
||||
return ocities;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the cities, ordered by offset, accounting for summer/daylight
|
||||
* savings time. This does not require reading the time zone database
|
||||
* since the cities are pre-sorted.
|
||||
*/
|
||||
public static City[] getCitiesByRawOffset() {
|
||||
return citiesByRawOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator over all cities, in raw offset order.
|
||||
*/
|
||||
public static Iterator<City> iterator() {
|
||||
return cities.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of cities.
|
||||
*/
|
||||
public static int numCities() {
|
||||
return cities.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a city with the given name, time zone name, raw offset,
|
||||
* latitude, longitude, and 3D (X, Y, Z) coordinate.
|
||||
*/
|
||||
public City(String name, String timeZoneID,
|
||||
int rawOffset,
|
||||
float latitude, float longitude,
|
||||
float x, float y, float z) {
|
||||
this.name = name;
|
||||
this.timeZoneID = timeZoneID;
|
||||
this.rawOffset = rawOffset;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public TimeZone getTimeZone() {
|
||||
if (timeZone == null) {
|
||||
timeZone = TimeZone.getTimeZone(timeZoneID);
|
||||
}
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public float getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public float getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public float getRawOffset() {
|
||||
return rawOffset / 3600000.0f;
|
||||
}
|
||||
|
||||
public int getRawOffsetMillis() {
|
||||
return rawOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this city's offset from UTC, taking summer/daylight savigns
|
||||
* time into account.
|
||||
*/
|
||||
public float getOffset() {
|
||||
long now = System.currentTimeMillis();
|
||||
if (timeZone == null) {
|
||||
timeZone = TimeZone.getTimeZone(timeZoneID);
|
||||
}
|
||||
return timeZone.getOffset(now) / 3600000.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this city to another by name.
|
||||
*/
|
||||
public int compareTo(City o) {
|
||||
return name.compareTo(o.name);
|
||||
}
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* A class that draws an analog clock face with information about the current
|
||||
* time in a given city.
|
||||
*/
|
||||
public class Clock {
|
||||
|
||||
static final int MILLISECONDS_PER_MINUTE = 60 * 1000;
|
||||
static final int MILLISECONDS_PER_HOUR = 60 * 60 * 1000;
|
||||
|
||||
private City mCity = null;
|
||||
private long mCitySwitchTime;
|
||||
private long mTime;
|
||||
|
||||
private float mColorRed = 1.0f;
|
||||
private float mColorGreen = 1.0f;
|
||||
private float mColorBlue = 1.0f;
|
||||
|
||||
private long mOldOffset;
|
||||
|
||||
private Interpolator mClockHandInterpolator =
|
||||
new AccelerateDecelerateInterpolator();
|
||||
|
||||
public Clock() {
|
||||
// Empty constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a line to the given Path. The line extends from
|
||||
* radius r0 to radius r1 about the center point (cx, cy),
|
||||
* at an angle given by pos.
|
||||
*
|
||||
* @param path the Path to draw to
|
||||
* @param radius the radius of the outer rim of the clock
|
||||
* @param pos the angle, with 0 and 1 at 12:00
|
||||
* @param cx the X coordinate of the clock center
|
||||
* @param cy the Y coordinate of the clock center
|
||||
* @param r0 the starting radius for the line
|
||||
* @param r1 the ending radius for the line
|
||||
*/
|
||||
private static void drawLine(Path path,
|
||||
float radius, float pos, float cx, float cy, float r0, float r1) {
|
||||
float theta = pos * Shape.TWO_PI - Shape.PI_OVER_TWO;
|
||||
float dx = (float) Math.cos(theta);
|
||||
float dy = (float) Math.sin(theta);
|
||||
float p0x = cx + dx * r0;
|
||||
float p0y = cy + dy * r0;
|
||||
float p1x = cx + dx * r1;
|
||||
float p1y = cy + dy * r1;
|
||||
|
||||
float ox = (p1y - p0y);
|
||||
float oy = -(p1x - p0x);
|
||||
|
||||
float norm = (radius / 2.0f) / (float) Math.sqrt(ox * ox + oy * oy);
|
||||
ox *= norm;
|
||||
oy *= norm;
|
||||
|
||||
path.moveTo(p0x - ox, p0y - oy);
|
||||
path.lineTo(p1x - ox, p1y - oy);
|
||||
path.lineTo(p1x + ox, p1y + oy);
|
||||
path.lineTo(p0x + ox, p0y + oy);
|
||||
path.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a vertical arrow to the given Path.
|
||||
*
|
||||
* @param path the Path to draw to
|
||||
*/
|
||||
private static void drawVArrow(Path path,
|
||||
float cx, float cy, float width, float height) {
|
||||
path.moveTo(cx - width / 2.0f, cy);
|
||||
path.lineTo(cx, cy + height);
|
||||
path.lineTo(cx + width / 2.0f, cy);
|
||||
path.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a horizontal arrow to the given Path.
|
||||
*
|
||||
* @param path the Path to draw to
|
||||
*/
|
||||
private static void drawHArrow(Path path,
|
||||
float cx, float cy, float width, float height) {
|
||||
path.moveTo(cx, cy - height / 2.0f);
|
||||
path.lineTo(cx + width, cy);
|
||||
path.lineTo(cx, cy + height / 2.0f);
|
||||
path.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an offset in milliseconds to be subtracted from the current time
|
||||
* in order to obtain an smooth interpolation between the previously
|
||||
* displayed time and the current time.
|
||||
*/
|
||||
private long getOffset(float lerp) {
|
||||
long doffset = (long) (mCity.getOffset() *
|
||||
(float) MILLISECONDS_PER_HOUR - mOldOffset);
|
||||
int sign;
|
||||
if (doffset < 0) {
|
||||
doffset = -doffset;
|
||||
sign = -1;
|
||||
} else {
|
||||
sign = 1;
|
||||
}
|
||||
|
||||
while (doffset > 12L * MILLISECONDS_PER_HOUR) {
|
||||
doffset -= 12L * MILLISECONDS_PER_HOUR;
|
||||
}
|
||||
if (doffset > 6L * MILLISECONDS_PER_HOUR) {
|
||||
doffset = 12L * MILLISECONDS_PER_HOUR - doffset;
|
||||
sign = -sign;
|
||||
}
|
||||
|
||||
// Interpolate doffset towards 0
|
||||
doffset = (long)((1.0f - lerp)*doffset);
|
||||
|
||||
// Keep the same seconds count
|
||||
long dh = doffset / (MILLISECONDS_PER_HOUR);
|
||||
doffset -= dh * MILLISECONDS_PER_HOUR;
|
||||
long dm = doffset / MILLISECONDS_PER_MINUTE;
|
||||
doffset = sign * (60 * dh + dm) * MILLISECONDS_PER_MINUTE;
|
||||
|
||||
return doffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the city to be displayed. setCity(null) resets things so the clock
|
||||
* hand animation won't occur next time.
|
||||
*/
|
||||
public void setCity(City city) {
|
||||
if (mCity != city) {
|
||||
if (mCity != null) {
|
||||
mOldOffset =
|
||||
(long) (mCity.getOffset() * (float) MILLISECONDS_PER_HOUR);
|
||||
} else if (city != null) {
|
||||
mOldOffset =
|
||||
(long) (city.getOffset() * (float) MILLISECONDS_PER_HOUR);
|
||||
} else {
|
||||
mOldOffset = 0L; // this will never be used
|
||||
}
|
||||
this.mCitySwitchTime = System.currentTimeMillis();
|
||||
this.mCity = city;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.mTime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the clock face.
|
||||
*
|
||||
* @param canvas the Canvas to draw to
|
||||
* @param cx the X coordinate of the clock center
|
||||
* @param cy the Y coordinate of the clock center
|
||||
* @param radius the radius of the clock face
|
||||
* @param alpha the translucency of the clock face
|
||||
* @param textAlpha the translucency of the text
|
||||
* @param showCityName if true, display the city name
|
||||
* @param showTime if true, display the time digitally
|
||||
* @param showUpArrow if true, display an up arrow
|
||||
* @param showDownArrow if true, display a down arrow
|
||||
* @param showLeftRightArrows if true, display left and right arrows
|
||||
* @param prefixChars number of characters of the city name to draw in bold
|
||||
*/
|
||||
public void drawClock(Canvas canvas,
|
||||
float cx, float cy, float radius, float alpha, float textAlpha,
|
||||
boolean showCityName, boolean showTime,
|
||||
boolean showUpArrow, boolean showDownArrow, boolean showLeftRightArrows,
|
||||
int prefixChars) {
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
int iradius = (int)radius;
|
||||
|
||||
TimeZone tz = mCity.getTimeZone();
|
||||
|
||||
// Compute an interpolated time to animate between the previously
|
||||
// displayed time and the current time
|
||||
float lerp = Math.min(1.0f,
|
||||
(System.currentTimeMillis() - mCitySwitchTime) / 500.0f);
|
||||
lerp = mClockHandInterpolator.getInterpolation(lerp);
|
||||
long doffset = lerp < 1.0f ? getOffset(lerp) : 0L;
|
||||
|
||||
// Determine the interpolated time for the given time zone
|
||||
Calendar cal = Calendar.getInstance(tz);
|
||||
cal.setTimeInMillis(mTime - doffset);
|
||||
int hour = cal.get(Calendar.HOUR_OF_DAY);
|
||||
int minute = cal.get(Calendar.MINUTE);
|
||||
int second = cal.get(Calendar.SECOND);
|
||||
int milli = cal.get(Calendar.MILLISECOND);
|
||||
|
||||
float offset = tz.getRawOffset() / (float) MILLISECONDS_PER_HOUR;
|
||||
float daylightOffset = tz.inDaylightTime(new Date(mTime)) ?
|
||||
tz.getDSTSavings() / (float) MILLISECONDS_PER_HOUR : 0.0f;
|
||||
|
||||
float absOffset = offset < 0 ? -offset : offset;
|
||||
int offsetH = (int) absOffset;
|
||||
int offsetM = (int) (60.0f * (absOffset - offsetH));
|
||||
hour %= 12;
|
||||
|
||||
// Get the city name and digital time strings
|
||||
String cityName = mCity.getName();
|
||||
cal.setTimeInMillis(mTime);
|
||||
String time = DateUtils.timeString(cal.getTimeInMillis()) + " " +
|
||||
DateUtils.getDayOfWeekString(cal.get(Calendar.DAY_OF_WEEK),
|
||||
DateUtils.LENGTH_SHORT) + " " +
|
||||
" (UTC" +
|
||||
(offset >= 0 ? "+" : "-") +
|
||||
offsetH +
|
||||
(offsetM == 0 ? "" : ":" + offsetM) +
|
||||
(daylightOffset == 0 ? "" : "+" + daylightOffset) +
|
||||
")";
|
||||
|
||||
float th = paint.getTextSize();
|
||||
float tw;
|
||||
|
||||
// Set the text color
|
||||
paint.setARGB((int) (textAlpha * 255.0f),
|
||||
(int) (mColorRed * 255.0f),
|
||||
(int) (mColorGreen * 255.0f),
|
||||
(int) (mColorBlue * 255.0f));
|
||||
|
||||
tw = paint.measureText(cityName);
|
||||
if (showCityName) {
|
||||
// Increment prefixChars to include any spaces
|
||||
for (int i = 0; i < prefixChars; i++) {
|
||||
if (cityName.charAt(i) == ' ') {
|
||||
++prefixChars;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the city name
|
||||
canvas.drawText(cityName, cx - tw / 2, cy - radius - th, paint);
|
||||
// Overstrike the first 'prefixChars' characters
|
||||
canvas.drawText(cityName.substring(0, prefixChars),
|
||||
cx - tw / 2 + 1, cy - radius - th, paint);
|
||||
}
|
||||
tw = paint.measureText(time);
|
||||
if (showTime) {
|
||||
canvas.drawText(time, cx - tw / 2, cy + radius + th + 5, paint);
|
||||
}
|
||||
|
||||
paint.setARGB((int)(alpha * 255.0f),
|
||||
(int)(mColorRed * 255.0f),
|
||||
(int)(mColorGreen * 255.0f),
|
||||
(int)(mColorBlue * 255.0f));
|
||||
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawOval(new RectF(cx - 2, cy - 2, cx + 2, cy + 2), paint);
|
||||
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(radius * 0.12f);
|
||||
|
||||
canvas.drawOval(new RectF(cx - iradius, cy - iradius,
|
||||
cx + iradius, cy + iradius),
|
||||
paint);
|
||||
|
||||
float r0 = radius * 0.1f;
|
||||
float r1 = radius * 0.4f;
|
||||
float r2 = radius * 0.6f;
|
||||
float r3 = radius * 0.65f;
|
||||
float r4 = radius * 0.7f;
|
||||
float r5 = radius * 0.9f;
|
||||
|
||||
Path path = new Path();
|
||||
|
||||
float ss = second + milli / 1000.0f;
|
||||
float mm = minute + ss / 60.0f;
|
||||
float hh = hour + mm / 60.0f;
|
||||
|
||||
// Tics for the hours
|
||||
for (int i = 0; i < 12; i++) {
|
||||
drawLine(path, radius * 0.12f, i / 12.0f, cx, cy, r4, r5);
|
||||
}
|
||||
|
||||
// Hour hand
|
||||
drawLine(path, radius * 0.12f, hh / 12.0f, cx, cy, r0, r1);
|
||||
// Minute hand
|
||||
drawLine(path, radius * 0.12f, mm / 60.0f, cx, cy, r0, r2);
|
||||
// Second hand
|
||||
drawLine(path, radius * 0.036f, ss / 60.0f, cx, cy, r0, r3);
|
||||
|
||||
if (showUpArrow) {
|
||||
drawVArrow(path, cx + radius * 1.13f, cy - radius,
|
||||
radius * 0.15f, -radius * 0.1f);
|
||||
}
|
||||
if (showDownArrow) {
|
||||
drawVArrow(path, cx + radius * 1.13f, cy + radius,
|
||||
radius * 0.15f, radius * 0.1f);
|
||||
}
|
||||
if (showLeftRightArrows) {
|
||||
drawHArrow(path, cx - radius * 1.3f, cy, -radius * 0.1f,
|
||||
radius * 0.15f);
|
||||
drawHArrow(path, cx + radius * 1.3f, cy, radius * 0.1f,
|
||||
radius * 0.15f);
|
||||
}
|
||||
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
}
|
||||
@@ -1,927 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
class Message {
|
||||
|
||||
private String mText;
|
||||
private long mExpirationTime;
|
||||
|
||||
public Message(String text, long expirationTime) {
|
||||
this.mText = text;
|
||||
this.mExpirationTime = expirationTime;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return mText;
|
||||
}
|
||||
|
||||
public long getExpirationTime() {
|
||||
return mExpirationTime;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class to simplify writing an Activity that renders using
|
||||
* OpenGL ES.
|
||||
*
|
||||
* <p> A GLView object stores common elements of GL state and allows
|
||||
* them to be modified interactively. This is particularly useful for
|
||||
* determining the proper settings of parameters such as the view
|
||||
* frustum and light intensities during application development.
|
||||
*
|
||||
* <p> A GLView is not an actual View; instead, it is meant to be
|
||||
* called from within a View to perform event processing on behalf of the
|
||||
* actual View.
|
||||
*
|
||||
* <p> By passing key events to the GLView object from the View,
|
||||
* the application can automatically allow certain parameters to
|
||||
* be user-controlled from the keyboard. Key events may be passed as
|
||||
* shown below:
|
||||
*
|
||||
* <pre>
|
||||
* GLView mGlView = new GLView();
|
||||
*
|
||||
* public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
* // Hand the key to the GLView object first
|
||||
* if (mGlView.processKey(keyCode)) {
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* switch (keyCode) {
|
||||
* case KeyEvent.KEY_CODE_X:
|
||||
* // perform app processing
|
||||
* break;
|
||||
*
|
||||
* default:
|
||||
* super.onKeyDown(keyCode, event);
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p> During drawing of a frame, the GLView object should be given the
|
||||
* opportunity to manage GL parameters as shown below:
|
||||
*
|
||||
* OpenGLContext mGLContext; // initialization not shown
|
||||
* int mNumTrianglesDrawn = 0;
|
||||
*
|
||||
* protected void onDraw(Canvas canvas) {
|
||||
* int w = getWidth();
|
||||
* int h = getHeight();
|
||||
*
|
||||
* float ratio = (float) w / h;
|
||||
* mGLView.setAspectRatio(ratio);
|
||||
*
|
||||
* GL10 gl = (GL10) mGLContext.getGL();
|
||||
* mGLContext.waitNative(canvas, this);
|
||||
*
|
||||
* // Enable a light for the GLView to manipulate
|
||||
* gl.glEnable(GL10.GL_LIGHTING);
|
||||
* gl.glEnable(GL10.GL_LIGHT0);
|
||||
*
|
||||
* // Allow the GLView to set GL parameters
|
||||
* mGLView.setTextureParameters(gl);
|
||||
* mGLView.setProjection(gl);
|
||||
* mGLView.setView(gl);
|
||||
* mGLView.setLights(gl, GL10.GL_LIGHT0);
|
||||
*
|
||||
* // Draw some stuff (not shown)
|
||||
* mNumTrianglesDrawn += <num triangles just drawn>;
|
||||
*
|
||||
* // Wait for GL drawing to complete
|
||||
* mGLContext.waitGL();
|
||||
*
|
||||
* // Inform the GLView of what was drawn, and ask it to display statistics
|
||||
* mGLView.setNumTriangles(mNumTrianglesDrawn);
|
||||
* mGLView.showMessages(canvas);
|
||||
* mGLView.showStatistics(canvas, w);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p> At the end of each frame, following the call to
|
||||
* GLContext.waitGL, the showStatistics and showMessages methods
|
||||
* will cause additional information to be displayed.
|
||||
*
|
||||
* <p> To enter the interactive command mode, the 'tab' key must be
|
||||
* pressed twice in succession. A subsequent press of the 'tab' key
|
||||
* exits the interactive command mode. Entering a multi-letter code
|
||||
* sets the parameter to be modified. The 'newline' key erases the
|
||||
* current code, and the 'del' key deletes the last letter of
|
||||
* the code. The parameter value may be modified by pressing the
|
||||
* keypad left or up to decrement the value and right or down to
|
||||
* increment the value. The current value will be displayed as an
|
||||
* overlay above the GL rendered content.
|
||||
*
|
||||
* <p> The supported keyboard commands are as follows:
|
||||
*
|
||||
* <ul>
|
||||
* <li> h - display a list of commands
|
||||
* <li> fn - near frustum
|
||||
* <li> ff - far frustum
|
||||
* <li> tx - translate x
|
||||
* <li> ty - translate y
|
||||
* <li> tz - translate z
|
||||
* <li> z - zoom (frustum size)
|
||||
* <li> la - ambient light (all RGB channels)
|
||||
* <li> lar - ambient light red channel
|
||||
* <li> lag - ambient light green channel
|
||||
* <li> lab - ambient light blue channel
|
||||
* <li> ld - diffuse light (all RGB channels)
|
||||
* <li> ldr - diffuse light red channel
|
||||
* <li> ldg - diffuse light green channel
|
||||
* <li> ldb - diffuse light blue channel
|
||||
* <li> ls - specular light (all RGB channels)
|
||||
* <li> lsr - specular light red channel
|
||||
* <li> lsg - specular light green channel
|
||||
* <li> lsb - specular light blue channel
|
||||
* <li> lma - light model ambient (all RGB channels)
|
||||
* <li> lmar - light model ambient light red channel
|
||||
* <li> lmag - light model ambient green channel
|
||||
* <li> lmab - light model ambient blue channel
|
||||
* <li> tmin - texture min filter
|
||||
* <li> tmag - texture mag filter
|
||||
* <li> tper - texture perspective correction
|
||||
* </ul>
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public class GLView {
|
||||
|
||||
private static final int DEFAULT_DURATION_MILLIS = 1000;
|
||||
private static final int STATE_KEY = KeyEvent.KEYCODE_TAB;
|
||||
private static final int HAVE_NONE = 0;
|
||||
private static final int HAVE_ONE = 1;
|
||||
private static final int HAVE_TWO = 2;
|
||||
|
||||
private static final float MESSAGE_Y_SPACING = 12.0f;
|
||||
|
||||
private int mState = HAVE_NONE;
|
||||
|
||||
private static final int NEAR_FRUSTUM = 0;
|
||||
private static final int FAR_FRUSTUM = 1;
|
||||
private static final int TRANSLATE_X = 2;
|
||||
private static final int TRANSLATE_Y = 3;
|
||||
private static final int TRANSLATE_Z = 4;
|
||||
private static final int ZOOM_EXPONENT = 5;
|
||||
|
||||
private static final int AMBIENT_INTENSITY = 6;
|
||||
private static final int AMBIENT_RED = 7;
|
||||
private static final int AMBIENT_GREEN = 8;
|
||||
private static final int AMBIENT_BLUE = 9;
|
||||
|
||||
private static final int DIFFUSE_INTENSITY = 10;
|
||||
private static final int DIFFUSE_RED = 11;
|
||||
private static final int DIFFUSE_GREEN = 12;
|
||||
private static final int DIFFUSE_BLUE = 13;
|
||||
|
||||
private static final int SPECULAR_INTENSITY = 14;
|
||||
private static final int SPECULAR_RED = 15;
|
||||
private static final int SPECULAR_GREEN = 16;
|
||||
private static final int SPECULAR_BLUE = 17;
|
||||
|
||||
private static final int LIGHT_MODEL_AMBIENT_INTENSITY = 18;
|
||||
private static final int LIGHT_MODEL_AMBIENT_RED = 19;
|
||||
private static final int LIGHT_MODEL_AMBIENT_GREEN = 20;
|
||||
private static final int LIGHT_MODEL_AMBIENT_BLUE = 21;
|
||||
|
||||
private static final int TEXTURE_MIN_FILTER = 22;
|
||||
private static final int TEXTURE_MAG_FILTER = 23;
|
||||
private static final int TEXTURE_PERSPECTIVE_CORRECTION = 24;
|
||||
|
||||
private static final String[] commands = {
|
||||
"fn",
|
||||
"ff",
|
||||
"tx",
|
||||
"ty",
|
||||
"tz",
|
||||
"z",
|
||||
"la", "lar", "lag", "lab",
|
||||
"ld", "ldr", "ldg", "ldb",
|
||||
"ls", "lsr", "lsg", "lsb",
|
||||
"lma", "lmar", "lmag", "lmab",
|
||||
"tmin", "tmag", "tper"
|
||||
};
|
||||
|
||||
private static final String[] labels = {
|
||||
"Near Frustum",
|
||||
"Far Frustum",
|
||||
"Translate X",
|
||||
"Translate Y",
|
||||
"Translate Z",
|
||||
"Zoom",
|
||||
"Ambient Intensity",
|
||||
"Ambient Red",
|
||||
"Ambient Green",
|
||||
"Ambient Blue",
|
||||
"Diffuse Intensity",
|
||||
"Diffuse Red",
|
||||
"Diffuse Green",
|
||||
"Diffuse Blue",
|
||||
"Specular Intenstity",
|
||||
"Specular Red",
|
||||
"Specular Green",
|
||||
"Specular Blue",
|
||||
"Light Model Ambient Intensity",
|
||||
"Light Model Ambient Red",
|
||||
"Light Model Ambient Green",
|
||||
"Light Model Ambient Blue",
|
||||
"Texture Min Filter",
|
||||
"Texture Mag Filter",
|
||||
"Texture Perspective Correction",
|
||||
};
|
||||
|
||||
private static final float[] defaults = {
|
||||
5.0f, 100.0f,
|
||||
0.0f, 0.0f, -50.0f,
|
||||
0,
|
||||
0.125f, 1.0f, 1.0f, 1.0f,
|
||||
0.125f, 1.0f, 1.0f, 1.0f,
|
||||
0.125f, 1.0f, 1.0f, 1.0f,
|
||||
0.125f, 1.0f, 1.0f, 1.0f,
|
||||
GL10.GL_NEAREST, GL10.GL_NEAREST,
|
||||
GL10.GL_FASTEST
|
||||
};
|
||||
|
||||
private static final float[] increments = {
|
||||
0.01f, 0.5f,
|
||||
0.125f, 0.125f, 0.125f,
|
||||
1.0f,
|
||||
0.03125f, 0.1f, 0.1f, 0.1f,
|
||||
0.03125f, 0.1f, 0.1f, 0.1f,
|
||||
0.03125f, 0.1f, 0.1f, 0.1f,
|
||||
0.03125f, 0.1f, 0.1f, 0.1f,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
private float[] params = new float[commands.length];
|
||||
|
||||
private static final float mZoomScale = 0.109f;
|
||||
private static final float mZoomBase = 1.01f;
|
||||
|
||||
private int mParam = -1;
|
||||
private float mIncr = 0;
|
||||
|
||||
private Paint mPaint = new Paint();
|
||||
|
||||
private float mAspectRatio = 1.0f;
|
||||
|
||||
private float mZoom;
|
||||
|
||||
// private boolean mPerspectiveCorrection = false;
|
||||
// private int mTextureMinFilter = GL10.GL_NEAREST;
|
||||
// private int mTextureMagFilter = GL10.GL_NEAREST;
|
||||
|
||||
// Counters for FPS calculation
|
||||
private boolean mDisplayFPS = false;
|
||||
private boolean mDisplayCounts = false;
|
||||
private int mFramesFPS = 10;
|
||||
private long[] mTimes = new long[mFramesFPS];
|
||||
private int mTimesIdx = 0;
|
||||
|
||||
private Map<String,Message> mMessages = new HashMap<String,Message>();
|
||||
|
||||
/**
|
||||
* Constructs a new GLView.
|
||||
*/
|
||||
public GLView() {
|
||||
mPaint.setColor(0xffffffff);
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the aspect ratio (width/height) of the screen.
|
||||
*
|
||||
* @param aspectRatio the screen width divided by the screen height
|
||||
*/
|
||||
public void setAspectRatio(float aspectRatio) {
|
||||
this.mAspectRatio = aspectRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the overall ambient light intensity. This intensity will
|
||||
* be used to modify the ambient light value for each of the red,
|
||||
* green, and blue channels passed to glLightfv(...GL_AMBIENT...).
|
||||
* The default value is 0.125f.
|
||||
*
|
||||
* @param intensity a floating-point value controlling the overall
|
||||
* ambient light intensity.
|
||||
*/
|
||||
public void setAmbientIntensity(float intensity) {
|
||||
params[AMBIENT_INTENSITY] = intensity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the light model ambient intensity. This intensity will be
|
||||
* used to modify the ambient light value for each of the red,
|
||||
* green, and blue channels passed to
|
||||
* glLightModelfv(GL_LIGHT_MODEL_AMBIENT...). The default value
|
||||
* is 0.125f.
|
||||
*
|
||||
* @param intensity a floating-point value controlling the overall
|
||||
* light model ambient intensity.
|
||||
*/
|
||||
public void setLightModelAmbientIntensity(float intensity) {
|
||||
params[LIGHT_MODEL_AMBIENT_INTENSITY] = intensity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ambient color for the red, green, and blue channels
|
||||
* that will be multiplied by the value of setAmbientIntensity and
|
||||
* passed to glLightfv(...GL_AMBIENT...). The default values are
|
||||
* {1, 1, 1}.
|
||||
*
|
||||
* @param ambient an arry of three floats containing ambient
|
||||
* red, green, and blue intensity values.
|
||||
*/
|
||||
public void setAmbientColor(float[] ambient) {
|
||||
params[AMBIENT_RED] = ambient[0];
|
||||
params[AMBIENT_GREEN] = ambient[1];
|
||||
params[AMBIENT_BLUE] = ambient[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the overall diffuse light intensity. This intensity will
|
||||
* be used to modify the diffuse light value for each of the red,
|
||||
* green, and blue channels passed to glLightfv(...GL_DIFFUSE...).
|
||||
* The default value is 0.125f.
|
||||
*
|
||||
* @param intensity a floating-point value controlling the overall
|
||||
* ambient light intensity.
|
||||
*/
|
||||
public void setDiffuseIntensity(float intensity) {
|
||||
params[DIFFUSE_INTENSITY] = intensity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the diffuse color for the red, green, and blue channels
|
||||
* that will be multiplied by the value of setDiffuseIntensity and
|
||||
* passed to glLightfv(...GL_DIFFUSE...). The default values are
|
||||
* {1, 1, 1}.
|
||||
*
|
||||
* @param diffuse an array of three floats containing diffuse
|
||||
* red, green, and blue intensity values.
|
||||
*/
|
||||
public void setDiffuseColor(float[] diffuse) {
|
||||
params[DIFFUSE_RED] = diffuse[0];
|
||||
params[DIFFUSE_GREEN] = diffuse[1];
|
||||
params[DIFFUSE_BLUE] = diffuse[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the overall specular light intensity. This intensity will
|
||||
* be used to modify the diffuse light value for each of the red,
|
||||
* green, and blue channels passed to glLightfv(...GL_SPECULAR...).
|
||||
* The default value is 0.125f.
|
||||
*
|
||||
* @param intensity a floating-point value controlling the overall
|
||||
* ambient light intensity.
|
||||
*/
|
||||
public void setSpecularIntensity(float intensity) {
|
||||
params[SPECULAR_INTENSITY] = intensity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specular color for the red, green, and blue channels
|
||||
* that will be multiplied by the value of setSpecularIntensity and
|
||||
* passed to glLightfv(...GL_SPECULAR...). The default values are
|
||||
* {1, 1, 1}.
|
||||
*
|
||||
* @param specular an array of three floats containing specular
|
||||
* red, green, and blue intensity values.
|
||||
*/
|
||||
public void setSpecularColor(float[] specular) {
|
||||
params[SPECULAR_RED] = specular[0];
|
||||
params[SPECULAR_GREEN] = specular[1];
|
||||
params[SPECULAR_BLUE] = specular[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current X translation of the modelview
|
||||
* transformation as passed to glTranslatef. The default value is
|
||||
* 0.0f.
|
||||
*
|
||||
* @return the X modelview translation as a float.
|
||||
*/
|
||||
public float getTranslateX() {
|
||||
return params[TRANSLATE_X];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Y translation of the modelview
|
||||
* transformation as passed to glTranslatef. The default value is
|
||||
* 0.0f.
|
||||
*
|
||||
* @return the Y modelview translation as a float.
|
||||
*/
|
||||
public float getTranslateY() {
|
||||
return params[TRANSLATE_Y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Z translation of the modelview
|
||||
* transformation as passed to glTranslatef. The default value is
|
||||
* -50.0f.
|
||||
*
|
||||
* @return the Z modelview translation as a float.
|
||||
*/
|
||||
public float getTranslateZ() {
|
||||
return params[TRANSLATE_Z];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the near frustum clipping plane as passed
|
||||
* to glFrustumf. The default value is 5.0f;
|
||||
*
|
||||
* @param nearFrustum the near frustum clipping plane distance as
|
||||
* a float.
|
||||
*/
|
||||
public void setNearFrustum(float nearFrustum) {
|
||||
params[NEAR_FRUSTUM] = nearFrustum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the far frustum clipping plane as passed
|
||||
* to glFrustumf. The default value is 100.0f;
|
||||
*
|
||||
* @param farFrustum the far frustum clipping plane distance as a
|
||||
* float.
|
||||
*/
|
||||
public void setFarFrustum(float farFrustum) {
|
||||
params[FAR_FRUSTUM] = farFrustum;
|
||||
}
|
||||
|
||||
private void computeZoom() {
|
||||
mZoom = mZoomScale*(float)Math.pow(mZoomBase, -params[ZOOM_EXPONENT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all parameters to their default values.
|
||||
*/
|
||||
public void reset() {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
params[i] = defaults[i];
|
||||
}
|
||||
computeZoom();
|
||||
}
|
||||
|
||||
private void removeExpiredMessages() {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
List<String> toBeRemoved = new ArrayList<String>();
|
||||
|
||||
Iterator<String> keyIter = mMessages.keySet().iterator();
|
||||
while (keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
Message msg = mMessages.get(key);
|
||||
if (msg.getExpirationTime() < now) {
|
||||
toBeRemoved.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<String> tbrIter = toBeRemoved.iterator();
|
||||
while (tbrIter.hasNext()) {
|
||||
String key = tbrIter.next();
|
||||
mMessages.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the message overlay on the given Canvas. The
|
||||
* GLContext.waitGL method should be called prior to calling this
|
||||
* method. The interactive command display is drawn by this
|
||||
* method.
|
||||
*
|
||||
* @param canvas the Canvas on which messages are to appear.
|
||||
*/
|
||||
public void showMessages(Canvas canvas) {
|
||||
removeExpiredMessages();
|
||||
|
||||
float y = 10.0f;
|
||||
|
||||
List<String> l = new ArrayList<String>();
|
||||
l.addAll(mMessages.keySet());
|
||||
Collections.sort(l);
|
||||
|
||||
Iterator<String> iter = l.iterator();
|
||||
while (iter.hasNext()) {
|
||||
String key = iter.next();
|
||||
String text = mMessages.get(key).getText();
|
||||
canvas.drawText(text, 10.0f, y, mPaint);
|
||||
y += MESSAGE_Y_SPACING;
|
||||
}
|
||||
}
|
||||
|
||||
private int mTriangles;
|
||||
|
||||
/**
|
||||
* Sets the number of triangles drawn in the previous frame for
|
||||
* display by the showStatistics method. The number of triangles
|
||||
* is not computed by GLView but must be supplied by the
|
||||
* calling Activity.
|
||||
*
|
||||
* @param triangles an Activity-supplied estimate of the number of
|
||||
* triangles drawn in the previous frame.
|
||||
*/
|
||||
public void setNumTriangles(int triangles) {
|
||||
this.mTriangles = triangles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays statistics on frames and triangles per second. The
|
||||
* GLContext.waitGL method should be called prior to calling this
|
||||
* method.
|
||||
*
|
||||
* @param canvas the Canvas on which statistics are to appear.
|
||||
* @param width the width of the Canvas.
|
||||
*/
|
||||
public void showStatistics(Canvas canvas, int width) {
|
||||
long endTime = mTimes[mTimesIdx] = System.currentTimeMillis();
|
||||
mTimesIdx = (mTimesIdx + 1) % mFramesFPS;
|
||||
|
||||
float th = mPaint.getTextSize();
|
||||
|
||||
if (mDisplayFPS) {
|
||||
// Use end time from mFramesFPS frames ago
|
||||
long startTime = mTimes[mTimesIdx];
|
||||
String fps = "" + (1000.0f*mFramesFPS/(endTime - startTime));
|
||||
|
||||
// Normalize fps to XX.XX format
|
||||
if (fps.indexOf(".") == 1) {
|
||||
fps = " " + fps;
|
||||
}
|
||||
int len = fps.length();
|
||||
if (len == 2) {
|
||||
fps += ".00";
|
||||
} else if (len == 4) {
|
||||
fps += "0";
|
||||
} else if (len > 5) {
|
||||
fps = fps.substring(0, 5);
|
||||
}
|
||||
|
||||
canvas.drawText(fps + " fps", width - 60.0f, 10.0f, mPaint);
|
||||
}
|
||||
|
||||
if (mDisplayCounts) {
|
||||
canvas.drawText(mTriangles + " triangles",
|
||||
width - 100.0f, 10.0f + th + 5, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMessage(String key, String text, int durationMillis) {
|
||||
long expirationTime = System.currentTimeMillis() + durationMillis;
|
||||
|
||||
mMessages.put(key, new Message(text, expirationTime));
|
||||
}
|
||||
|
||||
private void addMessage(String key, String text) {
|
||||
addMessage(key, text, DEFAULT_DURATION_MILLIS);
|
||||
}
|
||||
|
||||
private void addMessage(String text) {
|
||||
addMessage(text, text, DEFAULT_DURATION_MILLIS);
|
||||
}
|
||||
|
||||
private void clearMessages() {
|
||||
mMessages.clear();
|
||||
}
|
||||
|
||||
String command = "";
|
||||
|
||||
private void toggleFilter() {
|
||||
if (params[mParam] == GL10.GL_NEAREST) {
|
||||
params[mParam] = GL10.GL_LINEAR;
|
||||
} else {
|
||||
params[mParam] = GL10.GL_NEAREST;
|
||||
}
|
||||
addMessage(commands[mParam],
|
||||
"Texture " +
|
||||
(mParam == TEXTURE_MIN_FILTER ? "min" : "mag") +
|
||||
" filter = " +
|
||||
(params[mParam] == GL10.GL_NEAREST ?
|
||||
"nearest" : "linear"));
|
||||
}
|
||||
|
||||
private void togglePerspectiveCorrection() {
|
||||
if (params[mParam] == GL10.GL_NICEST) {
|
||||
params[mParam] = GL10.GL_FASTEST;
|
||||
} else {
|
||||
params[mParam] = GL10.GL_NICEST;
|
||||
}
|
||||
addMessage(commands[mParam],
|
||||
"Texture perspective correction = " +
|
||||
(params[mParam] == GL10.GL_FASTEST ?
|
||||
"fastest" : "nicest"));
|
||||
}
|
||||
|
||||
private String valueString() {
|
||||
if (mParam == TEXTURE_MIN_FILTER ||
|
||||
mParam == TEXTURE_MAG_FILTER) {
|
||||
if (params[mParam] == GL10.GL_NEAREST) {
|
||||
return "nearest";
|
||||
}
|
||||
if (params[mParam] == GL10.GL_LINEAR) {
|
||||
return "linear";
|
||||
}
|
||||
}
|
||||
if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
|
||||
if (params[mParam] == GL10.GL_FASTEST) {
|
||||
return "fastest";
|
||||
}
|
||||
if (params[mParam] == GL10.GL_NICEST) {
|
||||
return "nicest";
|
||||
}
|
||||
}
|
||||
return "" + params[mParam];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if the view
|
||||
*/
|
||||
public boolean hasMessages() {
|
||||
return mState == HAVE_TWO || mDisplayFPS || mDisplayCounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a key stroke. The calling Activity should pass all
|
||||
* keys from its onKeyDown method to this method. If the key is
|
||||
* part of a GLView command, true is returned and the calling
|
||||
* Activity should ignore the key event. Otherwise, false is
|
||||
* returned and the calling Activity may process the key event
|
||||
* normally.
|
||||
*
|
||||
* @param keyCode the key code as passed to Activity.onKeyDown.
|
||||
*
|
||||
* @return true if the key is part of a GLView command sequence,
|
||||
* false otherwise.
|
||||
*/
|
||||
public boolean processKey(int keyCode) {
|
||||
// Pressing the state key twice enters the UI
|
||||
// Pressing it again exits the UI
|
||||
if ((keyCode == STATE_KEY) ||
|
||||
(keyCode == KeyEvent.KEYCODE_SLASH) ||
|
||||
(keyCode == KeyEvent.KEYCODE_PERIOD))
|
||||
{
|
||||
mState = (mState + 1) % 3;
|
||||
if (mState == HAVE_NONE) {
|
||||
clearMessages();
|
||||
}
|
||||
if (mState == HAVE_TWO) {
|
||||
clearMessages();
|
||||
addMessage("aaaa", "GL", Integer.MAX_VALUE);
|
||||
addMessage("aaab", "", Integer.MAX_VALUE);
|
||||
command = "";
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (mState == HAVE_ONE) {
|
||||
mState = HAVE_NONE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not in the UI, exit without handling the key
|
||||
if (mState != HAVE_TWO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||
command = "";
|
||||
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
|
||||
if (command.length() > 0) {
|
||||
command = command.substring(0, command.length() - 1);
|
||||
}
|
||||
|
||||
} else if (keyCode >= KeyEvent.KEYCODE_A &&
|
||||
keyCode <= KeyEvent.KEYCODE_Z) {
|
||||
command += "" + (char)(keyCode - KeyEvent.KEYCODE_A + 'a');
|
||||
}
|
||||
|
||||
addMessage("aaaa", "GL " + command, Integer.MAX_VALUE);
|
||||
|
||||
if (command.equals("h")) {
|
||||
addMessage("aaaa", "GL", Integer.MAX_VALUE);
|
||||
addMessage("h - help");
|
||||
addMessage("fn/ff - frustum near/far clip Z");
|
||||
addMessage("la/lar/lag/lab - abmient intensity/r/g/b");
|
||||
addMessage("ld/ldr/ldg/ldb - diffuse intensity/r/g/b");
|
||||
addMessage("ls/lsr/lsg/lsb - specular intensity/r/g/b");
|
||||
addMessage("s - toggle statistics display");
|
||||
addMessage("tmin/tmag - texture min/mag filter");
|
||||
addMessage("tpersp - texture perspective correction");
|
||||
addMessage("tx/ty/tz - view translate x/y/z");
|
||||
addMessage("z - zoom");
|
||||
command = "";
|
||||
return true;
|
||||
} else if (command.equals("s")) {
|
||||
mDisplayCounts = !mDisplayCounts;
|
||||
mDisplayFPS = !mDisplayFPS;
|
||||
command = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
mParam = -1;
|
||||
for (int i = 0; i < commands.length; i++) {
|
||||
if (command.equals(commands[i])) {
|
||||
mParam = i;
|
||||
mIncr = increments[i];
|
||||
}
|
||||
}
|
||||
if (mParam == -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean addMessage = true;
|
||||
|
||||
// Increment or decrement
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ||
|
||||
keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
||||
if (mParam == ZOOM_EXPONENT) {
|
||||
params[mParam] += mIncr;
|
||||
computeZoom();
|
||||
} else if ((mParam == TEXTURE_MIN_FILTER) ||
|
||||
(mParam == TEXTURE_MAG_FILTER)) {
|
||||
toggleFilter();
|
||||
} else if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
|
||||
togglePerspectiveCorrection();
|
||||
} else {
|
||||
params[mParam] += mIncr;
|
||||
}
|
||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP ||
|
||||
keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
|
||||
if (mParam == ZOOM_EXPONENT) {
|
||||
params[mParam] -= mIncr;
|
||||
computeZoom();
|
||||
} else if ((mParam == TEXTURE_MIN_FILTER) ||
|
||||
(mParam == TEXTURE_MAG_FILTER)) {
|
||||
toggleFilter();
|
||||
} else if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
|
||||
togglePerspectiveCorrection();
|
||||
} else {
|
||||
params[mParam] -= mIncr;
|
||||
}
|
||||
}
|
||||
|
||||
if (addMessage) {
|
||||
addMessage(commands[mParam],
|
||||
labels[mParam] + ": " + valueString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom in by a given number of steps. A negative value of steps
|
||||
* zooms out. Each step zooms in by 1%.
|
||||
*
|
||||
* @param steps the number of steps to zoom by.
|
||||
*/
|
||||
public void zoom(int steps) {
|
||||
params[ZOOM_EXPONENT] += steps;
|
||||
computeZoom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the projection matrix using glFrustumf. The left and right
|
||||
* clipping planes are set at -+(aspectRatio*zoom), the bottom and
|
||||
* top clipping planes are set at -+zoom, and the near and far
|
||||
* clipping planes are set to the values set by setNearFrustum and
|
||||
* setFarFrustum or interactively.
|
||||
*
|
||||
* <p> GL side effects:
|
||||
* <ul>
|
||||
* <li>overwrites the matrix mode</li>
|
||||
* <li>overwrites the projection matrix</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param gl a GL10 instance whose projection matrix is to be modified.
|
||||
*/
|
||||
public void setProjection(GL10 gl) {
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
if (mAspectRatio >= 1.0f) {
|
||||
gl.glFrustumf(-mAspectRatio*mZoom, mAspectRatio*mZoom,
|
||||
-mZoom, mZoom,
|
||||
params[NEAR_FRUSTUM], params[FAR_FRUSTUM]);
|
||||
} else {
|
||||
gl.glFrustumf(-mZoom, mZoom,
|
||||
-mZoom / mAspectRatio, mZoom / mAspectRatio,
|
||||
params[NEAR_FRUSTUM], params[FAR_FRUSTUM]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the modelview matrix using glLoadIdentity and glTranslatef.
|
||||
* The translation values are set interactively.
|
||||
*
|
||||
* <p> GL side effects:
|
||||
* <ul>
|
||||
* <li>overwrites the matrix mode</li>
|
||||
* <li>overwrites the modelview matrix</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param gl a GL10 instance whose modelview matrix is to be modified.
|
||||
*/
|
||||
public void setView(GL10 gl) {
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
// Move the viewpoint backwards
|
||||
gl.glTranslatef(params[TRANSLATE_X],
|
||||
params[TRANSLATE_Y],
|
||||
params[TRANSLATE_Z]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets texture parameters.
|
||||
*
|
||||
* <p> GL side effects:
|
||||
* <ul>
|
||||
* <li>sets the GL_PERSPECTIVE_CORRECTION_HINT</li>
|
||||
* <li>sets the GL_TEXTURE_MIN_FILTER texture parameter</li>
|
||||
* <li>sets the GL_TEXTURE_MAX_FILTER texture parameter</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param gl a GL10 instance whose texture parameters are to be modified.
|
||||
*/
|
||||
public void setTextureParameters(GL10 gl) {
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
||||
(int)params[TEXTURE_PERSPECTIVE_CORRECTION]);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
|
||||
GL10.GL_TEXTURE_MIN_FILTER,
|
||||
params[TEXTURE_MIN_FILTER]);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
|
||||
GL10.GL_TEXTURE_MAG_FILTER,
|
||||
params[TEXTURE_MAG_FILTER]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lighting parameters for the given light.
|
||||
*
|
||||
* <p> GL side effects:
|
||||
* <ul>
|
||||
* <li>sets the GL_LIGHT_MODEL_AMBIENT intensities
|
||||
* <li>sets the GL_AMBIENT intensities for the given light</li>
|
||||
* <li>sets the GL_DIFFUSE intensities for the given light</li>
|
||||
* <li>sets the GL_SPECULAR intensities for the given light</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param gl a GL10 instance whose texture parameters are to be modified.
|
||||
*/
|
||||
public void setLights(GL10 gl, int lightNum) {
|
||||
float[] light = new float[4];
|
||||
light[3] = 1.0f;
|
||||
|
||||
float lmi = params[LIGHT_MODEL_AMBIENT_INTENSITY];
|
||||
light[0] = params[LIGHT_MODEL_AMBIENT_RED]*lmi;
|
||||
light[1] = params[LIGHT_MODEL_AMBIENT_GREEN]*lmi;
|
||||
light[2] = params[LIGHT_MODEL_AMBIENT_BLUE]*lmi;
|
||||
gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, light, 0);
|
||||
|
||||
float ai = params[AMBIENT_INTENSITY];
|
||||
light[0] = params[AMBIENT_RED]*ai;
|
||||
light[1] = params[AMBIENT_GREEN]*ai;
|
||||
light[2] = params[AMBIENT_BLUE]*ai;
|
||||
gl.glLightfv(lightNum, GL10.GL_AMBIENT, light, 0);
|
||||
|
||||
float di = params[DIFFUSE_INTENSITY];
|
||||
light[0] = params[DIFFUSE_RED]*di;
|
||||
light[1] = params[DIFFUSE_GREEN]*di;
|
||||
light[2] = params[DIFFUSE_BLUE]*di;
|
||||
gl.glLightfv(lightNum, GL10.GL_DIFFUSE, light, 0);
|
||||
|
||||
float si = params[SPECULAR_INTENSITY];
|
||||
light[0] = params[SPECULAR_RED]*si;
|
||||
light[1] = params[SPECULAR_GREEN]*si;
|
||||
light[2] = params[SPECULAR_BLUE]*si;
|
||||
gl.glLightfv(lightNum, GL10.GL_SPECULAR, light, 0);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
public class LatLongSphere extends Sphere {
|
||||
|
||||
public LatLongSphere(float centerX, float centerY, float centerZ,
|
||||
float radius, int lats, int longs,
|
||||
float minLongitude, float maxLongitude,
|
||||
boolean emitTextureCoordinates,
|
||||
boolean emitNormals,
|
||||
boolean emitColors,
|
||||
boolean flatten) {
|
||||
super(emitTextureCoordinates, emitNormals, emitColors);
|
||||
|
||||
int tris = 2 * (lats - 1) * (longs - 1);
|
||||
int[] vertices = new int[3 * lats * longs];
|
||||
int[] texcoords = new int[2 * lats * longs];
|
||||
int[] colors = new int[4 * lats * longs];
|
||||
int[] normals = new int[3 * lats * longs];
|
||||
short[] indices = new short[3 * tris];
|
||||
|
||||
int vidx = 0;
|
||||
int tidx = 0;
|
||||
int nidx = 0;
|
||||
int cidx = 0;
|
||||
int iidx = 0;
|
||||
|
||||
minLongitude *= DEGREES_TO_RADIANS;
|
||||
maxLongitude *= DEGREES_TO_RADIANS;
|
||||
|
||||
for (int i = 0; i < longs; i++) {
|
||||
float fi = (float) i / (longs - 1);
|
||||
// theta is the longitude
|
||||
float theta =
|
||||
(maxLongitude - minLongitude) * (1.0f - fi) + minLongitude;
|
||||
float sinTheta = (float) Math.sin(theta);
|
||||
float cosTheta = (float) Math.cos(theta);
|
||||
|
||||
for (int j = 0; j < lats; j++) {
|
||||
float fj = (float) j / (lats - 1);
|
||||
// phi is the latitude
|
||||
float phi = PI * fj;
|
||||
float sinPhi = (float) Math.sin(phi);
|
||||
float cosPhi = (float) Math.cos(phi);
|
||||
float x = cosTheta * sinPhi;
|
||||
float y = cosPhi;
|
||||
float z = sinTheta * sinPhi;
|
||||
|
||||
if (flatten) {
|
||||
// Place vertices onto a flat projection
|
||||
vertices[vidx++] = toFixed(2.0f * fi - 1.0f);
|
||||
vertices[vidx++] = toFixed(0.5f - fj);
|
||||
vertices[vidx++] = toFixed(0.0f);
|
||||
} else {
|
||||
// Place vertices onto the surface of a sphere
|
||||
// with the given center and radius
|
||||
vertices[vidx++] = toFixed(x * radius + centerX);
|
||||
vertices[vidx++] = toFixed(y * radius + centerY);
|
||||
vertices[vidx++] = toFixed(z * radius + centerZ);
|
||||
}
|
||||
|
||||
if (emitTextureCoordinates) {
|
||||
texcoords[tidx++] = toFixed(1.0f - (theta / (TWO_PI)));
|
||||
texcoords[tidx++] = toFixed(fj);
|
||||
}
|
||||
|
||||
if (emitNormals) {
|
||||
float norm = 1.0f / Shape.length(x, y, z);
|
||||
normals[nidx++] = toFixed(x * norm);
|
||||
normals[nidx++] = toFixed(y * norm);
|
||||
normals[nidx++] = toFixed(z * norm);
|
||||
}
|
||||
|
||||
// 0 == black, 65536 == white
|
||||
if (emitColors) {
|
||||
colors[cidx++] = (i % 2) * 65536;
|
||||
colors[cidx++] = 0;
|
||||
colors[cidx++] = (j % 2) * 65536;
|
||||
colors[cidx++] = 65536;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < longs - 1; i++) {
|
||||
for (int j = 0; j < lats - 1; j++) {
|
||||
int base = i * lats + j;
|
||||
|
||||
// Ensure both triangles have the same final vertex
|
||||
// since this vertex carries the color for flat
|
||||
// shading
|
||||
indices[iidx++] = (short) (base);
|
||||
indices[iidx++] = (short) (base + 1);
|
||||
indices[iidx++] = (short) (base + lats + 1);
|
||||
|
||||
indices[iidx++] = (short) (base + lats);
|
||||
indices[iidx++] = (short) (base);
|
||||
indices[iidx++] = (short) (base + lats + 1);
|
||||
}
|
||||
}
|
||||
|
||||
allocateBuffers(vertices, texcoords, normals, colors, indices);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A class representing a set of GL_POINT objects. GlobalTime uses this class
|
||||
* to draw city lights on the night side of the earth.
|
||||
*/
|
||||
public class PointCloud extends Shape {
|
||||
|
||||
/**
|
||||
* Constructs a PointCloud with a point at each of the given vertex
|
||||
* (x, y, z) positions.
|
||||
* @param vertices an array of (x, y, z) positions given in fixed-point.
|
||||
*/
|
||||
public PointCloud(int[] vertices) {
|
||||
this(vertices, 0, vertices.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a PointCloud with a point at each of the given vertex
|
||||
* (x, y, z) positions.
|
||||
* @param vertices an array of (x, y, z) positions given in fixed-point.
|
||||
* @param off the starting offset of the vertices array
|
||||
* @param len the number of elements of the vertices array to use
|
||||
*/
|
||||
public PointCloud(int[] vertices, int off, int len) {
|
||||
super(GL10.GL_POINTS, GL10.GL_UNSIGNED_SHORT,
|
||||
false, false, false);
|
||||
|
||||
int numPoints = len / 3;
|
||||
short[] indices = new short[numPoints];
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
indices[i] = (short)i;
|
||||
}
|
||||
|
||||
allocateBuffers(vertices, null, null, null, indices);
|
||||
this.mNumIndices = mIndexBuffer.capacity();
|
||||
}
|
||||
|
||||
@Override public int getNumTriangles() {
|
||||
return mNumIndices * 2;
|
||||
}
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* An abstract superclass for various three-dimensional objects to be drawn
|
||||
* using OpenGL ES. Each subclass is responsible for setting up NIO buffers
|
||||
* containing vertices, texture coordinates, colors, normals, and indices.
|
||||
* The {@link #draw(GL10)} method draws the object to the given OpenGL context.
|
||||
*/
|
||||
public abstract class Shape {
|
||||
|
||||
public static final int INT_BYTES = 4;
|
||||
public static final int SHORT_BYTES = 2;
|
||||
|
||||
public static final float DEGREES_TO_RADIANS = (float) Math.PI / 180.0f;
|
||||
public static final float PI = (float) Math.PI;
|
||||
public static final float TWO_PI = (float) (2.0 * Math.PI);
|
||||
public static final float PI_OVER_TWO = (float) (Math.PI / 2.0);
|
||||
|
||||
protected int mPrimitive;
|
||||
protected int mIndexDatatype;
|
||||
|
||||
protected boolean mEmitTextureCoordinates;
|
||||
protected boolean mEmitNormals;
|
||||
protected boolean mEmitColors;
|
||||
|
||||
protected IntBuffer mVertexBuffer;
|
||||
protected IntBuffer mTexcoordBuffer;
|
||||
protected IntBuffer mColorBuffer;
|
||||
protected IntBuffer mNormalBuffer;
|
||||
protected Buffer mIndexBuffer;
|
||||
protected int mNumIndices = -1;
|
||||
|
||||
/**
|
||||
* Constructs a Shape.
|
||||
*
|
||||
* @param primitive a GL primitive type understood by glDrawElements,
|
||||
* such as GL10.GL_TRIANGLES
|
||||
* @param indexDatatype the GL datatype for the index buffer, such as
|
||||
* GL10.GL_UNSIGNED_SHORT
|
||||
* @param emitTextureCoordinates true to enable use of the texture
|
||||
* coordinate buffer
|
||||
* @param emitNormals true to enable use of the normal buffer
|
||||
* @param emitColors true to enable use of the color buffer
|
||||
*/
|
||||
protected Shape(int primitive,
|
||||
int indexDatatype,
|
||||
boolean emitTextureCoordinates,
|
||||
boolean emitNormals,
|
||||
boolean emitColors) {
|
||||
mPrimitive = primitive;
|
||||
mIndexDatatype = indexDatatype;
|
||||
mEmitTextureCoordinates = emitTextureCoordinates;
|
||||
mEmitNormals = emitNormals;
|
||||
mEmitColors = emitColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given floating-point value to fixed-point.
|
||||
*/
|
||||
public static int toFixed(float x) {
|
||||
return (int) (x * 65536.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given fixed-point value to floating-point.
|
||||
*/
|
||||
public static float toFloat(int x) {
|
||||
return (float) (x / 65536.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cross-product of two vectors p and q and places
|
||||
* the result in out.
|
||||
*/
|
||||
public static void cross(float[] p, float[] q, float[] out) {
|
||||
out[0] = p[1] * q[2] - p[2] * q[1];
|
||||
out[1] = p[2] * q[0] - p[0] * q[2];
|
||||
out[2] = p[0] * q[1] - p[1] * q[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of a vector, given as three floats.
|
||||
*/
|
||||
public static float length(float vx, float vy, float vz) {
|
||||
return (float) Math.sqrt(vx * vx + vy * vy + vz * vz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of a vector, given as an array of three floats.
|
||||
*/
|
||||
public static float length(float[] v) {
|
||||
return length(v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the given vector of three floats to have length == 1.0.
|
||||
* Vectors with length zero are unaffected.
|
||||
*/
|
||||
public static void normalize(float[] v) {
|
||||
float length = length(v);
|
||||
if (length != 0.0f) {
|
||||
float norm = 1.0f / length;
|
||||
v[0] *= norm;
|
||||
v[1] *= norm;
|
||||
v[2] *= norm;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of triangles associated with this shape.
|
||||
*/
|
||||
public int getNumTriangles() {
|
||||
if (mPrimitive == GL10.GL_TRIANGLES) {
|
||||
return mIndexBuffer.capacity() / 3;
|
||||
} else if (mPrimitive == GL10.GL_TRIANGLE_STRIP) {
|
||||
return mIndexBuffer.capacity() - 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the given data into the instance
|
||||
* variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
|
||||
* and mIndexBuffer.
|
||||
*
|
||||
* @param vertices an array of fixed-point vertex coordinates
|
||||
* @param texcoords an array of fixed-point texture coordinates
|
||||
* @param normals an array of fixed-point normal vector coordinates
|
||||
* @param colors an array of fixed-point color channel values
|
||||
* @param indices an array of short indices
|
||||
*/
|
||||
public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
|
||||
int[] colors, short[] indices) {
|
||||
allocate(vertices, texcoords, normals, colors);
|
||||
|
||||
ByteBuffer ibb =
|
||||
ByteBuffer.allocateDirect(indices.length * SHORT_BYTES);
|
||||
ibb.order(ByteOrder.nativeOrder());
|
||||
ShortBuffer shortIndexBuffer = ibb.asShortBuffer();
|
||||
shortIndexBuffer.put(indices);
|
||||
shortIndexBuffer.position(0);
|
||||
this.mIndexBuffer = shortIndexBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the given data into the instance
|
||||
* variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
|
||||
* and mIndexBuffer.
|
||||
*
|
||||
* @param vertices an array of fixed-point vertex coordinates
|
||||
* @param texcoords an array of fixed-point texture coordinates
|
||||
* @param normals an array of fixed-point normal vector coordinates
|
||||
* @param colors an array of fixed-point color channel values
|
||||
* @param indices an array of int indices
|
||||
*/
|
||||
public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
|
||||
int[] colors, int[] indices) {
|
||||
allocate(vertices, texcoords, normals, colors);
|
||||
|
||||
ByteBuffer ibb =
|
||||
ByteBuffer.allocateDirect(indices.length * INT_BYTES);
|
||||
ibb.order(ByteOrder.nativeOrder());
|
||||
IntBuffer intIndexBuffer = ibb.asIntBuffer();
|
||||
intIndexBuffer.put(indices);
|
||||
intIndexBuffer.position(0);
|
||||
this.mIndexBuffer = intIndexBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the vertex, texture coordinate, normal, and color buffer.
|
||||
*/
|
||||
private void allocate(int[] vertices, int[] texcoords, int[] normals,
|
||||
int[] colors) {
|
||||
ByteBuffer vbb =
|
||||
ByteBuffer.allocateDirect(vertices.length * INT_BYTES);
|
||||
vbb.order(ByteOrder.nativeOrder());
|
||||
mVertexBuffer = vbb.asIntBuffer();
|
||||
mVertexBuffer.put(vertices);
|
||||
mVertexBuffer.position(0);
|
||||
|
||||
if ((texcoords != null) && mEmitTextureCoordinates) {
|
||||
ByteBuffer tbb =
|
||||
ByteBuffer.allocateDirect(texcoords.length * INT_BYTES);
|
||||
tbb.order(ByteOrder.nativeOrder());
|
||||
mTexcoordBuffer = tbb.asIntBuffer();
|
||||
mTexcoordBuffer.put(texcoords);
|
||||
mTexcoordBuffer.position(0);
|
||||
}
|
||||
|
||||
if ((normals != null) && mEmitNormals) {
|
||||
ByteBuffer nbb =
|
||||
ByteBuffer.allocateDirect(normals.length * INT_BYTES);
|
||||
nbb.order(ByteOrder.nativeOrder());
|
||||
mNormalBuffer = nbb.asIntBuffer();
|
||||
mNormalBuffer.put(normals);
|
||||
mNormalBuffer.position(0);
|
||||
}
|
||||
|
||||
if ((colors != null) && mEmitColors) {
|
||||
ByteBuffer cbb =
|
||||
ByteBuffer.allocateDirect(colors.length * INT_BYTES);
|
||||
cbb.order(ByteOrder.nativeOrder());
|
||||
mColorBuffer = cbb.asIntBuffer();
|
||||
mColorBuffer.put(colors);
|
||||
mColorBuffer.position(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the shape to the given OpenGL ES 1.0 context. Texture coordinates,
|
||||
* normals, and colors are emitted according the the preferences set for
|
||||
* this shape.
|
||||
*/
|
||||
public void draw(GL10 gl) {
|
||||
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
|
||||
if (mEmitTextureCoordinates) {
|
||||
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTexcoordBuffer);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
if (mEmitNormals) {
|
||||
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
|
||||
gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
if (mEmitColors) {
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
gl.glDrawElements(mPrimitive,
|
||||
mNumIndices > 0 ? mNumIndices : mIndexBuffer.capacity(),
|
||||
mIndexDatatype,
|
||||
mIndexBuffer);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
public class Sphere extends Shape {
|
||||
|
||||
public Sphere(boolean emitTextureCoordinates,
|
||||
boolean emitNormals, boolean emitColors) {
|
||||
super(GL10.GL_TRIANGLES, GL10.GL_UNSIGNED_SHORT,
|
||||
emitTextureCoordinates, emitNormals, emitColors);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class Texture {
|
||||
|
||||
private ByteBuffer data;
|
||||
private int width, height;
|
||||
|
||||
public Texture(ByteBuffer data, int width, int height) {
|
||||
this.data = data;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user