Files
processing4/android/examples/OpenGL/Earth/Earth.pde
2011-06-23 04:36:23 +00:00

198 lines
5.0 KiB
Plaintext

// Earth
// by Mike 'Flux' Chang (cleaned up by Aaron Koblin).
// Based on code by Toxi.
// Android port by Andres Colubri
//
// This example shows the shape recording functionality in A3D,
// where an entire geometry drawn with the regular API can be
// stored in a PShape3D object for later use. This greatly
// improves the performance of the application.
// Tap on the screen to enable/disable drawing with the recorded
// shape.
PShape globe;
PImage texmap;
int sDetail = 32; // Sphere detail setting
float rotationY = 0;
float globeRadius = 450;
float pushBack = 0;
float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[];
float cosLUT[];
float SINCOS_PRECISION = 0.5f;
int SINCOS_LENGTH = (int)(360.0f / SINCOS_PRECISION);
boolean usingPShape = false;
public void setup() {
size(480, 800, P3D);
orientation(PORTRAIT);
PFont font = createFont(PFont.list()[0], 24);
textFont(font, 24);
texmap = loadImage("world32k.jpg");
initializeSphere(sDetail);
autoNormal(false);
noStroke();
// Everything that is drawn between beginRecord/endRecord
// is saved into the PShape3D returned by beginRecord.
// Drawing the PShape3D object is much faster than redrawing
// all the geometry again in the draw() function.
globe = beginRecord();
texturedSphere(globeRadius, texmap);
endRecord();
}
public void draw() {
background(0);
renderGlobe();
fill(255);
if (usingPShape) {
text("With PShape3D. FPS: " + frameRate, 10, height - 30);
} else {
text("Without PShape3D. FPS: " + frameRate, 10, height - 30);
}
}
void mousePressed() {
usingPShape = !usingPShape;
}
public void renderGlobe() {
pushMatrix();
translate(width/2.0f, height/2.0f, pushBack);
lights();
pushMatrix();
rotateY(rotationY);
if (usingPShape) {
shape(globe);
} else {
texturedSphere(globeRadius, texmap);
}
popMatrix();
popMatrix();
rotationY += 0.01;
}
public void initializeSphere(int res) {
sinLUT = new float[SINCOS_LENGTH];
cosLUT = new float[SINCOS_LENGTH];
for (int i = 0; i < SINCOS_LENGTH; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
}
float delta = (float)SINCOS_LENGTH/res;
float[] cx = new float[res];
float[] cz = new float[res];
// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
}
// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;
// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (SINCOS_LENGTH*0.5f)/res;
float angle = angle_step;
// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}
// Generic routine to draw textured sphere
void texturedSphere(float r, PImage t) {
int v1,v11,v2;
r = (r + 240 ) * 0.33;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
normal(0, -1, 0);
vertex(0, -r, 0,u,0);
normal(sphereX[i], sphereY[i], sphereZ[i]);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
normal(sphereX[0], sphereY[0], sphereZ[0]);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();
// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}
// Close each ring
v1=v11;
v2=voff;
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;
// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
normal(0, 1, 0);
vertex(0, r, 0, u, v+iv);
u+=iu;
}
normal(sphereX[voff], sphereY[voff], sphereZ[voff]);
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();
}