diff --git a/android/examples/OpenGL/Animation/Yellowtail/AndroidManifest.xml b/android/examples/OpenGL/Animation/Yellowtail/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Animation/Yellowtail/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Animation/Yellowtail/Gesture.pde b/android/examples/OpenGL/Animation/Yellowtail/Gesture.pde
new file mode 100644
index 000000000..a869848db
--- /dev/null
+++ b/android/examples/OpenGL/Animation/Yellowtail/Gesture.pde
@@ -0,0 +1,256 @@
+class Gesture {
+
+ float damp = 5.0;
+ float dampInv = 1.0 / damp;
+ float damp1 = damp - 1;
+
+ int w;
+ int h;
+ int capacity;
+
+ Vec3f path[];
+ int crosses[];
+ Polygon polygons[];
+ int nPoints;
+ int nPolys;
+
+ float jumpDx, jumpDy;
+ boolean exists;
+ float INIT_TH = 14;
+ float thickness = INIT_TH;
+
+ Gesture(int mw, int mh) {
+ w = mw;
+ h = mh;
+ capacity = 600;
+ path = new Vec3f[capacity];
+ polygons = new Polygon[capacity];
+ crosses = new int[capacity];
+ for (int i=0;i= capacity) {
+ // there are all sorts of possible solutions here,
+ // but for abject simplicity, I don't do anything.
+ }
+ else {
+ float v = distToLast(x, y);
+ float p = getPressureFromVelocity(v);
+ path[nPoints++].set(x,y,p);
+
+ if (nPoints > 1) {
+ exists = true;
+ jumpDx = path[nPoints-1].x - path[0].x;
+ jumpDy = path[nPoints-1].y - path[0].y;
+ }
+ }
+
+ }
+
+ float getPressureFromVelocity(float v) {
+ final float scale = 18;
+ final float minP = 0.02;
+ final float oldP = (nPoints > 0) ? path[nPoints-1].p : 0;
+ return ((minP + max(0, 1.0 - v/scale)) + (damp1*oldP))*dampInv;
+ }
+
+ void setPressures() {
+ // pressures vary from 0...1
+ float pressure;
+ Vec3f tmp;
+ float t = 0;
+ float u = 1.0 / (nPoints - 1)*TWO_PI;
+ for (int i = 0; i < nPoints; i++) {
+ pressure = sqrt((1.0 - cos(t))*0.5);
+ path[i].p = pressure;
+ t += u;
+ }
+ }
+
+ float distToLast(float ix, float iy) {
+ if (nPoints > 0) {
+ Vec3f v = path[nPoints-1];
+ float dx = v.x - ix;
+ float dy = v.y - iy;
+ return mag(dx, dy);
+ }
+ else {
+ return 30;
+ }
+ }
+
+ void compile() {
+ // compute the polygons from the path of Vec3f's
+ if (exists) {
+ clearPolys();
+
+ Vec3f p0, p1, p2;
+ float radius0, radius1;
+ float ax, bx, cx, dx;
+ float ay, by, cy, dy;
+ int axi, bxi, cxi, dxi, axip, axid;
+ int ayi, byi, cyi, dyi, ayip, ayid;
+ float p1x, p1y;
+ float dx01, dy01, hp01, si01, co01;
+ float dx02, dy02, hp02, si02, co02;
+ float dx13, dy13, hp13, si13, co13;
+ float taper = 1.0;
+
+ int nPathPoints = nPoints - 1;
+ int lastPolyIndex = nPathPoints - 1;
+ float npm1finv = 1.0 / max(1, nPathPoints - 1);
+
+ // handle the first point
+ p0 = path[0];
+ p1 = path[1];
+ radius0 = p0.p * thickness;
+ dx01 = p1.x - p0.x;
+ dy01 = p1.y - p0.y;
+ hp01 = sqrt(dx01*dx01 + dy01*dy01);
+ if (hp01 == 0) {
+ hp02 = 0.0001;
+ }
+ co01 = radius0 * dx01 / hp01;
+ si01 = radius0 * dy01 / hp01;
+ ax = p0.x - si01;
+ ay = p0.y + co01;
+ bx = p0.x + si01;
+ by = p0.y - co01;
+
+ int xpts[];
+ int ypts[];
+
+ int LC = 20;
+ int RC = w-LC;
+ int TC = 20;
+ int BC = h-TC;
+ float mint = 0.618;
+ float tapow = 0.4;
+
+ // handle the middle points
+ int i = 1;
+ Polygon apoly;
+ for (i = 1; i < nPathPoints; i++) {
+ taper = pow((lastPolyIndex-i)*npm1finv,tapow);
+
+ p0 = path[i-1];
+ p1 = path[i ];
+ p2 = path[i+1];
+ p1x = p1.x;
+ p1y = p1.y;
+ radius1 = Math.max(mint,taper*p1.p*thickness);
+
+ // assumes all segments are roughly the same length...
+ dx02 = p2.x - p0.x;
+ dy02 = p2.y - p0.y;
+ hp02 = (float) Math.sqrt(dx02*dx02 + dy02*dy02);
+ if (hp02 != 0) {
+ hp02 = radius1/hp02;
+ }
+ co02 = dx02 * hp02;
+ si02 = dy02 * hp02;
+
+ // translate the integer coordinates to the viewing rectangle
+ axi = axip = (int)ax;
+ ayi = ayip = (int)ay;
+ axi=(axi<0)?(w-((-axi)%w)):axi%w;
+ axid = axi-axip;
+ ayi=(ayi<0)?(h-((-ayi)%h)):ayi%h;
+ ayid = ayi-ayip;
+
+ // set the vertices of the polygon
+ apoly = polygons[nPolys++];
+ xpts = apoly.xpoints;
+ ypts = apoly.ypoints;
+ xpts[0] = axi = axid + axip;
+ xpts[1] = bxi = axid + (int) bx;
+ xpts[2] = cxi = axid + (int)(cx = p1x + si02);
+ xpts[3] = dxi = axid + (int)(dx = p1x - si02);
+ ypts[0] = ayi = ayid + ayip;
+ ypts[1] = byi = ayid + (int) by;
+ ypts[2] = cyi = ayid + (int)(cy = p1y - co02);
+ ypts[3] = dyi = ayid + (int)(dy = p1y + co02);
+
+ // keep a record of where we cross the edge of the screen
+ crosses[i] = 0;
+ if ((axi<=LC)||(bxi<=LC)||(cxi<=LC)||(dxi<=LC)) {
+ crosses[i]|=1;
+ }
+ if ((axi>=RC)||(bxi>=RC)||(cxi>=RC)||(dxi>=RC)) {
+ crosses[i]|=2;
+ }
+ if ((ayi<=TC)||(byi<=TC)||(cyi<=TC)||(dyi<=TC)) {
+ crosses[i]|=4;
+ }
+ if ((ayi>=BC)||(byi>=BC)||(cyi>=BC)||(dyi>=BC)) {
+ crosses[i]|=8;
+ }
+
+ //swap data for next time
+ ax = dx;
+ ay = dy;
+ bx = cx;
+ by = cy;
+ }
+
+ // handle the last point
+ p2 = path[nPathPoints];
+ apoly = polygons[nPolys++];
+ xpts = apoly.xpoints;
+ ypts = apoly.ypoints;
+
+ xpts[0] = (int)ax;
+ xpts[1] = (int)bx;
+ xpts[2] = (int)(p2.x);
+ xpts[3] = (int)(p2.x);
+
+ ypts[0] = (int)ay;
+ ypts[1] = (int)by;
+ ypts[2] = (int)(p2.y);
+ ypts[3] = (int)(p2.y);
+
+ }
+ }
+
+ void smooth() {
+ // average neighboring points
+
+ final float weight = 18;
+ final float scale = 1.0 / (weight + 2);
+ int nPointsMinusTwo = nPoints - 2;
+ Vec3f lower, upper, center;
+
+ for (int i = 1; i < nPointsMinusTwo; i++) {
+ lower = path[i-1];
+ center = path[i];
+ upper = path[i+1];
+
+ center.x = (lower.x + weight*center.x + upper.x)*scale;
+ center.y = (lower.y + weight*center.y + upper.y)*scale;
+ }
+ }
+}
+
diff --git a/android/examples/OpenGL/Animation/Yellowtail/Polygon.pde b/android/examples/OpenGL/Animation/Yellowtail/Polygon.pde
new file mode 100644
index 000000000..f00d53875
--- /dev/null
+++ b/android/examples/OpenGL/Animation/Yellowtail/Polygon.pde
@@ -0,0 +1,12 @@
+public class Polygon {
+ int npoints;
+ int[] xpoints;
+ int[] ypoints;
+
+ public Polygon(int n) {
+ npoints = n;
+ xpoints = new int[n];
+ ypoints = new int[n];
+ }
+}
+
diff --git a/android/examples/OpenGL/Animation/Yellowtail/Vec3f.pde b/android/examples/OpenGL/Animation/Yellowtail/Vec3f.pde
new file mode 100644
index 000000000..865d3c32f
--- /dev/null
+++ b/android/examples/OpenGL/Animation/Yellowtail/Vec3f.pde
@@ -0,0 +1,19 @@
+class Vec3f {
+ float x;
+ float y;
+ float p; // Pressure
+
+ Vec3f() {
+ set(0, 0, 0);
+ }
+
+ Vec3f(float ix, float iy, float ip) {
+ set(ix, iy, ip);
+ }
+
+ void set(float ix, float iy, float ip) {
+ x = ix;
+ y = iy;
+ p = ip;
+ }
+}
diff --git a/android/examples/OpenGL/Animation/Yellowtail/Yellowtail.pde b/android/examples/OpenGL/Animation/Yellowtail/Yellowtail.pde
new file mode 100644
index 000000000..24c90a04b
--- /dev/null
+++ b/android/examples/OpenGL/Animation/Yellowtail/Yellowtail.pde
@@ -0,0 +1,186 @@
+// Yellowtail
+// by Golan Levin (www.flong.com).
+
+// Click, drag, and release to create a kinetic gesture.
+//
+// Yellowtail (1998-2000) is an interactive software system for the gestural
+// creation and performance of real-time abstract animation. Yellowtail repeats
+// a user's strokes end-over-end, enabling simultaneous specification of a
+// line's shape and quality of movement. Each line repeats according to its
+// own period, producing an ever-changing and responsive display of lively,
+// worm-like textures.
+
+Gesture gestureArray[];
+final int nGestures = 36; // Number of gestures
+final int minMove = 3; // Minimum travel for a new point
+int currentGestureID;
+
+Polygon tempP;
+int tmpXp[];
+int tmpYp[];
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ orientation(PORTRAIT);
+
+ background(0, 0, 0);
+ noStroke();
+
+ currentGestureID = -1;
+ gestureArray = new Gesture[nGestures];
+ for (int i = 0; i < nGestures; i++) {
+ gestureArray[i] = new Gesture(width, height);
+ }
+ clearGestures();
+}
+
+
+void draw() {
+ background(0);
+
+ updateGeometry();
+ fill(255, 255, 245);
+ for (int i = 0; i < nGestures; i++) {
+ renderGesture(gestureArray[i], width, height);
+ }
+}
+
+void mousePressed() {
+ currentGestureID = (currentGestureID+1) % nGestures;
+ Gesture G = gestureArray[currentGestureID];
+ G.clear();
+ G.clearPolys();
+ G.addPoint(mouseX, mouseY);
+}
+
+
+void mouseDragged() {
+ if (currentGestureID >= 0) {
+ Gesture G = gestureArray[currentGestureID];
+ if (G.distToLast(mouseX, mouseY) > minMove) {
+ G.addPoint(mouseX, mouseY);
+ G.smooth();
+ G.compile();
+ }
+ }
+}
+
+
+void keyPressed() {
+ if (key == '+' || key == '=') {
+ if (currentGestureID >= 0) {
+ float th = gestureArray[currentGestureID].thickness;
+ gestureArray[currentGestureID].thickness = min(96, th+1);
+ gestureArray[currentGestureID].compile();
+ }
+ } else if (key == '-') {
+ if (currentGestureID >= 0) {
+ float th = gestureArray[currentGestureID].thickness;
+ gestureArray[currentGestureID].thickness = max(2, th-1);
+ gestureArray[currentGestureID].compile();
+ }
+ } else if (key == ' ') {
+ clearGestures();
+ }
+}
+
+
+void renderGesture(Gesture gesture, int w, int h) {
+ if (gesture.exists) {
+ if (gesture.nPolys > 0) {
+ Polygon polygons[] = gesture.polygons;
+ int crosses[] = gesture.crosses;
+
+ int xpts[];
+ int ypts[];
+ Polygon p;
+ int cr;
+
+ beginShape(QUADS);
+ int gnp = gesture.nPolys;
+ for (int i=0; i 0) {
+ if ((cr & 3)>0) {
+ vertex(xpts[0]+w, ypts[0]);
+ vertex(xpts[1]+w, ypts[1]);
+ vertex(xpts[2]+w, ypts[2]);
+ vertex(xpts[3]+w, ypts[3]);
+
+ vertex(xpts[0]-w, ypts[0]);
+ vertex(xpts[1]-w, ypts[1]);
+ vertex(xpts[2]-w, ypts[2]);
+ vertex(xpts[3]-w, ypts[3]);
+ }
+ if ((cr & 12)>0) {
+ vertex(xpts[0], ypts[0]+h);
+ vertex(xpts[1], ypts[1]+h);
+ vertex(xpts[2], ypts[2]+h);
+ vertex(xpts[3], ypts[3]+h);
+
+ vertex(xpts[0], ypts[0]-h);
+ vertex(xpts[1], ypts[1]-h);
+ vertex(xpts[2], ypts[2]-h);
+ vertex(xpts[3], ypts[3]-h);
+ }
+
+ // I have knowingly retained the small flaw of not
+ // completely dealing with the corner conditions
+ // (the case in which both of the above are true).
+ }
+ }
+ endShape();
+ }
+ }
+}
+
+void updateGeometry() {
+ Gesture J;
+ for (int g=0; g 0) {
+ path = gesture.path;
+ for (int i = nPts1; i > 0; i--) {
+ path[i].x = path[i-1].x;
+ path[i].y = path[i-1].y;
+ }
+ path[0].x = path[nPts1].x - jx;
+ path[0].y = path[nPts1].y - jy;
+ gesture.compile();
+ }
+ }
+}
+
+void clearGestures() {
+ for (int i = 0; i < nGestures; i++) {
+ gestureArray[i].clear();
+ }
+}
+
diff --git a/android/examples/OpenGL/Camera/MoveEye/AndroidManifest.xml b/android/examples/OpenGL/Camera/MoveEye/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Camera/MoveEye/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Camera/MoveEye/MoveEye.pde b/android/examples/OpenGL/Camera/MoveEye/MoveEye.pde
new file mode 100644
index 000000000..9fd0c1cee
--- /dev/null
+++ b/android/examples/OpenGL/Camera/MoveEye/MoveEye.pde
@@ -0,0 +1,31 @@
+// Status: Fixed
+
+/**
+ * Move Eye.
+ * by Simon Greenwold.
+ *
+ * The camera lifts up (controlled by mouseY) while looking at the same point.
+ */
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ fill(204);
+}
+
+void draw() {
+ lights();
+ background(0);
+
+ // Change height of the camera with mouseY
+ camera(30.0, mouseY, 220.0, // eyeX, eyeY, eyeZ
+ 0.0, 0.0, 0.0, // centerX, centerY, centerZ
+ 0.0, 1.0, 0.0); // upX, upY, upZ
+
+ noStroke();
+ box(90);
+ stroke(255);
+ line(-100, 0, 0, 100, 0, 0);
+ line(0, -100, 0, 0, 100, 0);
+ line(0, 0, -100, 0, 0, 100);
+}
diff --git a/android/examples/OpenGL/Camera/OrthoVSPerspective/AndroidManifest.xml b/android/examples/OpenGL/Camera/OrthoVSPerspective/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Camera/OrthoVSPerspective/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Camera/OrthoVSPerspective/OrthoVSPerspective.pde b/android/examples/OpenGL/Camera/OrthoVSPerspective/OrthoVSPerspective.pde
new file mode 100644
index 000000000..92498119f
--- /dev/null
+++ b/android/examples/OpenGL/Camera/OrthoVSPerspective/OrthoVSPerspective.pde
@@ -0,0 +1,44 @@
+// Status: Fixed
+
+/**
+ * Ortho vs Perspective.
+ *
+ * Click to see the difference between orthographic projection
+ * and perspective projection as applied to a simple box.
+ * The ortho() function sets an orthographic projection and
+ * defines a parallel clipping volume. All objects with the
+ * same dimension appear the same size, regardless of whether
+ * they are near or far from the camera. The parameters to this
+ * function specify the clipping volume where left and right
+ * are the minimum and maximum x values, top and bottom are the
+ * minimum and maximum y values, and near and far are the minimum
+ * and maximum z values.
+ */
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ fill(204);
+}
+
+void draw()
+{
+ background(0);
+ lights();
+
+ if(mousePressed) {
+ float fov = PI/3.0;
+ float cameraZ = (height/2.0) / tan(fov/2.0);
+ perspective(fov, float(width)/float(height),
+ cameraZ/2.0, cameraZ*2.0);
+ } else {
+ ortho(0, width, 0, height, -200, +200);
+ }
+
+ translate(width/2, height/2, 0);
+ rotateX(-PI/6);
+ rotateY(PI/3);
+ box(160);
+}
diff --git a/android/examples/OpenGL/Camera/Perspective/AndroidManifest.xml b/android/examples/OpenGL/Camera/Perspective/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Camera/Perspective/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Camera/Perspective/Perspective.pde b/android/examples/OpenGL/Camera/Perspective/Perspective.pde
new file mode 100644
index 000000000..c2d53e42d
--- /dev/null
+++ b/android/examples/OpenGL/Camera/Perspective/Perspective.pde
@@ -0,0 +1,42 @@
+/**
+ * Perspective.
+ *
+ * Move the mouse left and right to change the field of view (fov).
+ * Click to modify the aspect ratio. The perspective() function
+ * sets a perspective projection applying foreshortening, making
+ * distant objects appear smaller than closer ones. The parameters
+ * define a viewing volume with the shape of truncated pyramid.
+ * Objects near to the front of the volume appear their actual size,
+ * while farther objects appear smaller. This projection simulates
+ * the perspective of the world more accurately than orthographic projection.
+ * The version of perspective without parameters sets the default
+ * perspective and the version with four parameters allows the programmer
+ * to set the area precisely.
+ */
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+}
+
+void draw() {
+ lights();
+ background(204);
+ float cameraY = height/2.0;
+ float fov = mouseX/float(width) * PI/2;
+ float cameraZ = cameraY / tan(fov / 2.0);
+ float aspect = float(width)/float(height);
+ if (mousePressed) {
+ aspect = aspect / 2.0;
+ }
+ perspective(fov, aspect, cameraZ/10.0, cameraZ*10.0);
+
+ translate(width/2+30, height/2, 0);
+ rotateX(-PI/6);
+ rotateY(PI/3 + mouseY/float(height) * PI);
+ box(45);
+ translate(0, 0, -50);
+ box(30);
+}
+
diff --git a/android/examples/OpenGL/Form/BrickTower/AndroidManifest.xml b/android/examples/OpenGL/Form/BrickTower/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/BrickTower/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/BrickTower/BrickTower.pde b/android/examples/OpenGL/Form/BrickTower/BrickTower.pde
new file mode 100644
index 000000000..88f25d63e
--- /dev/null
+++ b/android/examples/OpenGL/Form/BrickTower/BrickTower.pde
@@ -0,0 +1,59 @@
+/**
+ * Brick Tower
+ * by Ira Greenberg.
+ *
+ * 3D castle tower constructed out of individual bricks.
+ * Uses the PVector and Cube classes.
+ */
+
+float bricksPerLayer = 16.0;
+float brickLayers = 18.0;
+Cube brick;
+float brickWidth = 60, brickHeight = 25, brickDepth = 25;
+float radius = 175.0;
+float angle = 0;
+
+void setup(){
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ brick = new Cube(brickWidth, brickHeight, brickDepth);
+}
+
+void draw(){
+ background(0);
+ float tempX = 0, tempY = 0, tempZ = 0;
+ fill(182, 62, 29);
+ noStroke();
+ // Add basic light setup
+ lights();
+ translate(width/2, height*1.2, -380);
+ // Tip tower to see inside
+ rotateX(radians(-45));
+ // Slowly rotate tower
+ rotateY(frameCount * PI/600);
+ for (int i = 0; i < brickLayers; i++){
+ // Increment rows
+ tempY-=brickHeight;
+ // Alternate brick seams
+ angle = 360.0 / bricksPerLayer * i/2;
+ for (int j = 0; j < bricksPerLayer; j++){
+ tempZ = cos(radians(angle))*radius;
+ tempX = sin(radians(angle))*radius;
+ pushMatrix();
+ translate(tempX, tempY, tempZ);
+ rotateY(radians(angle));
+ // Add crenelation
+ if (i==brickLayers-1){
+ if (j%2 == 0){
+ brick.create();
+ }
+ }
+ // Create main tower
+ else {
+ brick.create();
+ }
+ popMatrix();
+ angle += 360.0/bricksPerLayer;
+ }
+ }
+}
diff --git a/android/examples/OpenGL/Form/BrickTower/Cube.pde b/android/examples/OpenGL/Form/BrickTower/Cube.pde
new file mode 100755
index 000000000..df772c0cf
--- /dev/null
+++ b/android/examples/OpenGL/Form/BrickTower/Cube.pde
@@ -0,0 +1,68 @@
+class Cube {
+
+ PVector[] vertices = new PVector[24];
+ PVector[] normals = new PVector[6];
+ float w, h, d;
+
+ Cube(){ }
+
+ Cube(float w, float h, float d){
+ this.w = w;
+ this.h = h;
+ this.d = d;
+
+ // Cube composed of 6 quads
+ // Front
+ normals[0] = new PVector(0, 0, 1);
+ vertices[0] = new PVector(-w/2, -h/2, d/2);
+ vertices[1] = new PVector(w/2, -h/2, d/2);
+ vertices[2] = new PVector(w/2, h/2, d/2);
+ vertices[3] = new PVector(-w/2, h/2, d/2);
+
+ // Left
+ normals[1] = new PVector(-1, 0, 0);
+ vertices[4] = new PVector(-w/2, -h/2, d/2);
+ vertices[5] = new PVector(-w/2, -h/2, -d/2);
+ vertices[6] = new PVector(-w/2, h/2, -d/2);
+ vertices[7] = new PVector(-w/2, h/2, d/2);
+
+ // Right
+ normals[2] = new PVector(1, 0, 0);
+ vertices[8] = new PVector(w/2, -h/2, d/2);
+ vertices[9] = new PVector(w/2, -h/2, -d/2);
+ vertices[10] = new PVector(w/2, h/2, -d/2);
+ vertices[11] = new PVector(w/2, h/2, d/2);
+
+ // Back
+ normals[3] = new PVector(0, 0, -1);
+ vertices[12] = new PVector(-w/2, -h/2, -d/2);
+ vertices[13] = new PVector(w/2, -h/2, -d/2);
+ vertices[14] = new PVector(w/2, h/2, -d/2);
+ vertices[15] = new PVector(-w/2, h/2, -d/2);
+
+ // Top
+ normals[4] = new PVector(0, 1, 0);
+ vertices[16] = new PVector(-w/2, -h/2, d/2);
+ vertices[17] = new PVector(-w/2, -h/2, -d/2);
+ vertices[18] = new PVector(w/2, -h/2, -d/2);
+ vertices[19] = new PVector(w/2, -h/2, d/2);
+
+ // Bottom
+ normals[5] = new PVector(0, 1, 0);
+ vertices[20] = new PVector(-w/2, h/2, d/2);
+ vertices[21] = new PVector(-w/2, h/2, -d/2);
+ vertices[22] = new PVector(w/2, h/2, -d/2);
+ vertices[23] = new PVector(w/2, h/2, d/2);
+ }
+
+ void create(){
+ for (int i=0; i<6; i++){
+ beginShape(QUADS);
+ normal(normals[i].x, normals[i].y, normals[i].z);
+ for (int j = 0; j < 4; j++){
+ vertex(vertices[j+4*i].x, vertices[j+4*i].y, vertices[j+4*i].z);
+ }
+ endShape();
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/examples/OpenGL/Form/CubicGrid/AndroidManifest.xml b/android/examples/OpenGL/Form/CubicGrid/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/CubicGrid/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/CubicGrid/CubicGrid.pde b/android/examples/OpenGL/Form/CubicGrid/CubicGrid.pde
new file mode 100644
index 000000000..069550266
--- /dev/null
+++ b/android/examples/OpenGL/Form/CubicGrid/CubicGrid.pde
@@ -0,0 +1,49 @@
+/**
+ * Cubic Grid
+ * by Ira Greenberg.
+ *
+ * 3D translucent colored grid uses nested pushMatrix()
+ * and popMatrix() functions.
+ */
+
+float boxSize = 80;
+float margin = boxSize*2;
+float depth = 400;
+color boxFill;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ hint(DISABLE_DEPTH_TEST);
+}
+
+void draw() {
+ background(255);
+
+ // Center and spin grid
+ translate(width/2, height/2, -depth);
+ rotateY(frameCount * 0.01);
+ rotateX(frameCount * 0.01);
+
+ // Build grid using multiple translations
+ for (float i =- depth/2+margin; i <= depth/2-margin; i += boxSize){
+ pushMatrix();
+ for (float j =- height+margin; j <= height-margin; j += boxSize){
+ pushMatrix();
+ for (float k =- width+margin; k <= width-margin; k += boxSize){
+ // Base fill color on counter values, abs function
+ // ensures values stay within legal range
+ boxFill = color(abs(i), abs(j), abs(k), 50);
+ pushMatrix();
+ translate(k, j, i);
+ fill(boxFill);
+ box(boxSize, boxSize, boxSize);
+ popMatrix();
+ }
+ popMatrix();
+ }
+ popMatrix();
+ }
+}
+
diff --git a/android/examples/OpenGL/Form/CubicGrid/sketch.properties b/android/examples/OpenGL/Form/CubicGrid/sketch.properties
new file mode 100644
index 000000000..2e0e580dd
--- /dev/null
+++ b/android/examples/OpenGL/Form/CubicGrid/sketch.properties
@@ -0,0 +1 @@
+mode=Android
diff --git a/android/examples/OpenGL/Form/Geometry/AndroidManifest.xml b/android/examples/OpenGL/Form/Geometry/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/Geometry/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/Geometry/Geometry.pde b/android/examples/OpenGL/Form/Geometry/Geometry.pde
new file mode 100644
index 000000000..ea2bcee57
--- /dev/null
+++ b/android/examples/OpenGL/Form/Geometry/Geometry.pde
@@ -0,0 +1,162 @@
+/**
+ * Geometry
+ * by Marius Watz.
+ *
+ * Using sin/cos lookup tables, blends colors, and draws a series of
+ * rotating arcs on the screen.
+*/
+
+// Trig lookup tables borrowed from Toxi; cryptic but effective.
+float sinLUT[];
+float cosLUT[];
+float SINCOS_PRECISION=1.0;
+int SINCOS_LENGTH= int((360.0/SINCOS_PRECISION));
+
+// System data
+boolean dosave=false;
+int num;
+float pt[];
+int style[];
+
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ background(255);
+
+ // Fill the tables
+ 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);
+ }
+
+ num = 40;
+ pt = new float[6*num]; // rotx, roty, deg, rad, w, speed
+ style = new int[2*num]; // color, render style
+
+ // Set up arc shapes
+ int index=0;
+ float prob;
+ for (int i=0; i90) pt[index]=(int)random(8,27)*10;
+
+ pt[index++] = int(random(2,50)*5); // Radius. Space them out nicely
+
+ pt[index++] = random(4,32); // Width of band
+ if(random(100)>90) pt[index]=random(40,60); // Width of band
+
+ pt[index++] = radians(random(5,30))/5; // Speed of rotation
+
+ // get colors
+ prob = random(100);
+ if(prob<30) style[i*2]=colorBlended(random(1), 255,0,100, 255,0,0, 210);
+ else if(prob<70) style[i*2]=colorBlended(random(1), 0,153,255, 170,225,255, 210);
+ else if(prob<90) style[i*2]=colorBlended(random(1), 200,255,0, 150,255,0, 210);
+ else style[i*2]=color(255,255,255, 220);
+
+ if(prob<50) style[i*2]=colorBlended(random(1), 200,255,0, 50,120,0, 210);
+ else if(prob<90) style[i*2]=colorBlended(random(1), 255,100,0, 255,255,0, 210);
+ else style[i*2]=color(255,255,255, 220);
+
+ style[i*2+1]=(int)(random(100))%3;
+ }
+}
+
+void draw() {
+
+ background(0);
+
+ int index=0;
+ translate(width/2, height/2, 0);
+ rotateX(PI/6);
+ rotateY(PI/6);
+
+ for (int i = 0; i < num; i++) {
+ pushMatrix();
+
+ rotateX(pt[index++]);
+ rotateY(pt[index++]);
+
+ if(style[i*2+1]==0) {
+ stroke(style[i*2]);
+ noFill();
+ strokeWeight(1);
+ arcLine(0,0, pt[index++],pt[index++],pt[index++]);
+ }
+ else if(style[i*2+1]==1) {
+ fill(style[i*2]);
+ noStroke();
+ arcLineBars(0,0, pt[index++],pt[index++],pt[index++]);
+ }
+ else {
+ fill(style[i*2]);
+ noStroke();
+ arc(0,0, pt[index++],pt[index++],pt[index++]);
+ }
+
+ // increase rotation
+ pt[index-5]+=pt[index]/10;
+ pt[index-4]+=pt[index++]/20;
+
+ popMatrix();
+ }
+}
+
+
+// Get blend of two colors
+int colorBlended(float fract,
+float r, float g, float b,
+float r2, float g2, float b2, float a) {
+
+ r2 = (r2 - r);
+ g2 = (g2 - g);
+ b2 = (b2 - b);
+ return color(r + r2 * fract, g + g2 * fract, b + b2 * fract, a);
+}
+
+
+// Draw arc line
+void arcLine(float x,float y,float deg,float rad,float w) {
+ int a=(int)(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
+ int numlines=(int)(w/2);
+
+ for (int j=0; j
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/Icosahedra/Dimension3D.pde b/android/examples/OpenGL/Form/Icosahedra/Dimension3D.pde
new file mode 100755
index 000000000..90c949967
--- /dev/null
+++ b/android/examples/OpenGL/Form/Icosahedra/Dimension3D.pde
@@ -0,0 +1,10 @@
+class Dimension3D{
+ float w, h, d;
+
+ Dimension3D(float w, float h, float d){
+ this.w=w;
+ this.h=h;
+ this.d=d;
+ }
+}
+
diff --git a/android/examples/OpenGL/Form/Icosahedra/Icosahedra.pde b/android/examples/OpenGL/Form/Icosahedra/Icosahedra.pde
new file mode 100644
index 000000000..f070dd451
--- /dev/null
+++ b/android/examples/OpenGL/Form/Icosahedra/Icosahedra.pde
@@ -0,0 +1,55 @@
+// ISSUES: normals are not properly set
+
+/**
+ * I Like Icosahedra
+ * by Ira Greenberg.
+ *
+ * This example plots icosahedra. The Icosahdron is a regular
+ * polyhedron composed of twenty equalateral triangles.
+ */
+
+Icosahedron ico1;
+Icosahedron ico2;
+Icosahedron ico3;
+
+void setup(){
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ ico1 = new Icosahedron(75);
+ ico2 = new Icosahedron(75);
+ ico3 = new Icosahedron(75);
+}
+
+void draw(){
+ background(0);
+ lights();
+ translate(width/2, height/2);
+
+ pushMatrix();
+ translate(-width/3.5, 0);
+ rotateX(frameCount*PI/185);
+ rotateY(frameCount*PI/-200);
+ stroke(170, 0, 0);
+ noFill();
+ ico1.create();
+ popMatrix();
+
+ pushMatrix();
+ rotateX(frameCount*PI/200);
+ rotateY(frameCount*PI/300);
+ stroke(150, 0, 180);
+ fill(170, 170, 0);
+ ico2.create();
+ popMatrix();
+
+ pushMatrix();
+ translate(width/3.5, 0);
+ rotateX(frameCount*PI/-200);
+ rotateY(frameCount*PI/200);
+ noStroke();
+ fill(0, 0, 185);
+ ico3.create();
+ popMatrix();
+}
+
+
diff --git a/android/examples/OpenGL/Form/Icosahedra/Icosahedron.pde b/android/examples/OpenGL/Form/Icosahedra/Icosahedron.pde
new file mode 100644
index 000000000..20c49fceb
--- /dev/null
+++ b/android/examples/OpenGL/Form/Icosahedra/Icosahedron.pde
@@ -0,0 +1,159 @@
+class Icosahedron extends Shape3D{
+
+ // icosahedron
+ PVector topPoint;
+ PVector[] topPent = new PVector[5];
+ PVector bottomPoint;
+ PVector[] bottomPent = new PVector[5];
+ float angle = 0, radius = 150;
+ float triDist;
+ float triHt;
+ float a, b, c;
+
+ // constructor
+ Icosahedron(float radius){
+ this.radius = radius;
+ init();
+ }
+
+ Icosahedron(PVector v, float radius){
+ super(v);
+ this.radius = radius;
+ init();
+ }
+
+ // calculate geometry
+ void init(){
+ c = dist(cos(0)*radius, sin(0)*radius, cos(radians(72))*radius, sin(radians(72))*radius);
+ b = radius;
+ a = (float)(Math.sqrt(((c*c)-(b*b))));
+
+ triHt = (float)(Math.sqrt((c*c)-((c/2)*(c/2))));
+
+ for (int i=0; i
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/Primitives3D/Primitives3D.pde b/android/examples/OpenGL/Form/Primitives3D/Primitives3D.pde
new file mode 100644
index 000000000..cd49fec15
--- /dev/null
+++ b/android/examples/OpenGL/Form/Primitives3D/Primitives3D.pde
@@ -0,0 +1,32 @@
+// ISSUES: non-interactive sketches don't show on the screen
+/**
+ * Primitives 3D.
+ *
+ * Placing mathematically 3D objects in synthetic space.
+ * The lights() method reveals their imagined dimension.
+ * The box() and sphere() functions each have one parameter
+ * which is used to specify their size. These shapes are
+ * positioned using the translate() function.
+ */
+
+size(640, 360, P3D);
+orientation(LANDSCAPE);
+background(0);
+lights();
+
+noStroke();
+pushMatrix();
+translate(130, height/2, 0);
+rotateY(1.25);
+rotateX(-0.4);
+box(100);
+popMatrix();
+
+noFill();
+stroke(255);
+pushMatrix();
+translate(500, height*0.35, -200);
+sphere(280);
+popMatrix();
+
+
diff --git a/android/examples/OpenGL/Form/RGBCube/AndroidManifest.xml b/android/examples/OpenGL/Form/RGBCube/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/RGBCube/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/RGBCube/RGBCube.pde b/android/examples/OpenGL/Form/RGBCube/RGBCube.pde
new file mode 100644
index 000000000..a7f7e3105
--- /dev/null
+++ b/android/examples/OpenGL/Form/RGBCube/RGBCube.pde
@@ -0,0 +1,75 @@
+/**
+ * RGB Cube.
+ *
+ * The three primary colors of the additive color model are red, green, and blue.
+ * This RGB color cube displays smooth transitions between these colors.
+ */
+
+float xmag, ymag = 0;
+float newXmag, newYmag = 0;
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ colorMode(RGB, 1);
+}
+
+void draw()
+{
+ background(0.5);
+
+ pushMatrix();
+
+ translate(width/2, height/2, -30);
+
+ newXmag = mouseX/float(width) * TWO_PI;
+ newYmag = mouseY/float(height) * TWO_PI;
+
+ float diff = xmag-newXmag;
+ if (abs(diff) > 0.01) { xmag -= diff/4.0; }
+
+ diff = ymag-newYmag;
+ if (abs(diff) > 0.01) { ymag -= diff/4.0; }
+
+ rotateX(-ymag);
+ rotateY(-xmag);
+
+ scale(90);
+ beginShape(QUADS);
+
+ fill(0, 1, 1); vertex(-1, 1, 1);
+ fill(1, 1, 1); vertex( 1, 1, 1);
+ fill(1, 0, 1); vertex( 1, -1, 1);
+ fill(0, 0, 1); vertex(-1, -1, 1);
+
+ fill(1, 1, 1); vertex( 1, 1, 1);
+ fill(1, 1, 0); vertex( 1, 1, -1);
+ fill(1, 0, 0); vertex( 1, -1, -1);
+ fill(1, 0, 1); vertex( 1, -1, 1);
+
+ fill(1, 1, 0); vertex( 1, 1, -1);
+ fill(0, 1, 0); vertex(-1, 1, -1);
+ fill(0, 0, 0); vertex(-1, -1, -1);
+ fill(1, 0, 0); vertex( 1, -1, -1);
+
+ fill(0, 1, 0); vertex(-1, 1, -1);
+ fill(0, 1, 1); vertex(-1, 1, 1);
+ fill(0, 0, 1); vertex(-1, -1, 1);
+ fill(0, 0, 0); vertex(-1, -1, -1);
+
+ fill(0, 1, 0); vertex(-1, 1, -1);
+ fill(1, 1, 0); vertex( 1, 1, -1);
+ fill(1, 1, 1); vertex( 1, 1, 1);
+ fill(0, 1, 1); vertex(-1, 1, 1);
+
+ fill(0, 0, 0); vertex(-1, -1, -1);
+ fill(1, 0, 0); vertex( 1, -1, -1);
+ fill(1, 0, 1); vertex( 1, -1, 1);
+ fill(0, 0, 1); vertex(-1, -1, 1);
+
+ endShape();
+
+ popMatrix();
+}
diff --git a/android/examples/OpenGL/Form/RunAmuck/AndroidManifest.xml b/android/examples/OpenGL/Form/RunAmuck/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/RunAmuck/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/RunAmuck/Legs.pde b/android/examples/OpenGL/Form/RunAmuck/Legs.pde
new file mode 100755
index 000000000..eb74d7859
--- /dev/null
+++ b/android/examples/OpenGL/Form/RunAmuck/Legs.pde
@@ -0,0 +1,162 @@
+/**
+ * Legs class
+ * By Ira Greenberg
+ * Processing for Flash Developers,
+ * Friends of ED, 2009
+ */
+
+class Legs {
+ // Instance properties with default values
+ float x = 0, y = 0, z = 0, w = 150, ht = 125;
+ color col = #77AA22;
+ // Advanced properties
+ float detailW = w/6.0;
+ float detailHt = ht/8.0;
+ float shoeBulge = detailHt*2.0;
+ float legGap = w/7.0;
+
+ // Dynamics properties
+ float velocity = .02, stepL, stepR, stepRate = random(10, 50);
+ float speedX = 1.0, speedZ, spring, damping = .5, theta;
+
+ // Default constructor
+ Legs() {
+ }
+
+ // Standard constructor
+ Legs(float x, float z, float w, float ht, color col) {
+ this.x = x;
+ this.z = z;
+ this.w = w;
+ this.ht = ht;
+ this.col = col;
+ fill(col);
+ detailW = w/6.0;
+ detailHt = ht/8.0;
+ shoeBulge = detailHt*2.0;
+ legGap = w/7.0;
+ speedX = random(-speedX, speedX);
+ }
+
+ // Advanced constructor
+ Legs(float x, float z, float w, float ht, color col, float detailW,
+ float detailHt, float shoeBulge, float legGap) {
+ this.x = x;
+ this.z = z;
+ this.w = w;
+ this.ht = ht;
+ this.col = col;
+ this.detailW = detailW;
+ this.detailHt = detailHt;
+ this.shoeBulge = shoeBulge;
+ this.legGap = legGap;
+ speedX = random(-speedX, speedX);
+ }
+
+ // Draw legs
+ void create() {
+ fill(col);
+ float footWidth = (w - legGap)/2;
+ beginShape();
+ vertex(x - w/2, y - ht, z);
+ vertex(x - w/2, y - ht + detailHt, z);
+ vertex(x - w/2 + detailW, y - ht + detailHt, z);
+ // left foot
+ vertex(x - w/2 + detailW, y + stepL, z);
+ curveVertex(x - w/2 + detailW, y + stepL, z);
+ curveVertex(x - w/2 + detailW, y + stepL, z);
+ curveVertex(x - w/2 + detailW - shoeBulge, y + detailHt/2 + stepL, z);
+ curveVertex(x - w/2, y + detailHt + stepL, z);
+ curveVertex(x - w/2, y + detailHt + stepL, z);
+ vertex(x - w/2 + footWidth, y + detailHt + stepL*.9, z);
+ // end left foot
+ vertex(x - w/2 + footWidth + legGap/2, y - ht + detailHt, z);
+ vertex(x - w/2 + footWidth + legGap/2, y - ht + detailHt, z);
+ // right foot
+ vertex(x - w/2 + footWidth + legGap, y + detailHt + stepR*.9, z);
+ vertex(x + w/2, y + detailHt + stepR, z);
+ curveVertex(x + w/2, y + detailHt + stepR, z);
+ curveVertex(x + w/2, y + detailHt + stepR, z);
+ curveVertex(x + w/2 - detailW + shoeBulge, y + detailHt/2 + stepR, z);
+ curveVertex(x + w/2 - detailW, y + stepR, z);
+ vertex(x + w/2 - detailW, y + stepR, z);
+ // end right foot
+ vertex(x + w/2 - detailW, y - ht + detailHt, z);
+ vertex(x + w/2, y - ht + detailHt, z);
+ vertex(x + w/2, y - ht, z);
+ endShape(CLOSE);
+ }
+
+ // Set advanced property values
+ void setDetails(float detailW, float detailHt, float shoeBulge, float legGap) {
+ this.detailW = detailW;
+ this.detailHt = detailHt;
+ this.shoeBulge = shoeBulge;
+ this.legGap = legGap;
+ }
+
+ // Make the legs step
+ void step(float stepRate) {
+ this.stepRate = stepRate;
+ spring = ht/2.0;
+ stepL = sin(theta)*spring;
+ stepR = cos(theta)*spring;
+ theta += radians(stepRate);
+ }
+
+ // Alternative overloaded step method
+ void step() {
+ spring = ht/2.0;
+ stepL = sin(theta)*spring;
+ stepR = cos(theta)*spring;
+ theta += radians(stepRate);
+ }
+
+
+ // Moves legs along x, y, z axes
+ void move() {
+ // Move legs along y-axis
+ y = stepR*damping;
+
+ // Move legs along x-axis and
+ // check for collision against frame edge
+ x += speedX;
+ if (screenX(x, y, z) > width) {
+ speedX *= -1;
+ }
+ if (screenX(x, y, z) < 0) {
+ speedX *= -1;
+ }
+
+ // Move legs along z-axis based on speed of stepping
+ // and check for collision against extremes
+ speedZ = (stepRate*velocity);
+ z += speedZ;
+ if (z > 400) {
+ z = 400;
+ velocity *= -1;
+ }
+ if (z < -100) {
+ z = -100;
+ velocity *= -1;
+ }
+ }
+
+ void setDynamics(float speedX, float spring, float damping) {
+ this.speedX = speedX;
+ this.spring = spring;
+ this.damping = damping;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/RunAmuck/RunAmuck.pde b/android/examples/OpenGL/Form/RunAmuck/RunAmuck.pde
new file mode 100644
index 000000000..a5c977e40
--- /dev/null
+++ b/android/examples/OpenGL/Form/RunAmuck/RunAmuck.pde
@@ -0,0 +1,48 @@
+// ISSUES: shapes containing curve vertices don't render properly
+
+/**
+ * Run-Amuck
+ * By Ira Greenberg
+ * Processing for Flash Developers,
+ * Friends of ED, 2009
+ */
+
+int count = 250;
+Legs[] legs = new Legs[count];
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ for (int i = 0; i < legs.length; i++) {
+ legs[i] = new Legs(random(-10, 10), random(-50, 150), random(.5, 5),
+ random(.5, 5), color(random(255), random(255), random(255)));
+ }
+}
+
+void draw() {
+ background(0);
+ translate(width/2, height/2);
+ noStroke();
+ fill(35);
+
+ // Draw ground plane
+ beginShape(QUADS);
+ vertex(-width*2, 0, -1000);
+ vertex(width*2, 0, -1000);
+ vertex(width/2, height/2, 400);
+ vertex(-width/2, height/2, 400);
+ endShape(CLOSE);
+
+ // Update and draw the legs
+ for (int i = 0; i < legs.length; i++) {
+ legs[i].create();
+ // Set foot step rate
+ legs[i].step(random(10, 50));
+ // Move legs along x, y, z axes
+ // z-movement dependent upon step rate
+ legs[i].move();
+ }
+}
+
+
diff --git a/android/examples/OpenGL/Form/ShapeTransform/AndroidManifest.xml b/android/examples/OpenGL/Form/ShapeTransform/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/ShapeTransform/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/ShapeTransform/ShapeTransform.pde b/android/examples/OpenGL/Form/ShapeTransform/ShapeTransform.pde
new file mode 100644
index 000000000..e2b203744
--- /dev/null
+++ b/android/examples/OpenGL/Form/ShapeTransform/ShapeTransform.pde
@@ -0,0 +1,117 @@
+/**
+ * Shape Transform
+ * by Ira Greenberg.
+ *
+ * Illustrates the geometric relationship
+ * between Cube, Pyramid, Cone and
+ * Cylinder 3D primitives.
+ *
+ * Instructions:
+ * Up Arrow - increases points
+ * Down Arrow - decreases points
+ * 'p' key toggles between cube/pyramid
+ */
+
+int pts = 4;
+float angle = 0;
+float radius = 99;
+float cylinderLength = 95;
+
+//vertices
+PVector vertices[][];
+boolean isPyramid = false;
+
+float angleInc;
+
+void setup(){
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ angleInc = PI/300.0;
+}
+
+void draw(){
+ background(170, 95, 95);
+ lights();
+ fill(255, 200, 200);
+ translate(width/2, height/2);
+ rotateX(frameCount * angleInc);
+ rotateY(frameCount * angleInc);
+ rotateZ(frameCount * angleInc);
+
+ // initialize vertex arrays
+ vertices = new PVector[2][pts+1];
+
+ // fill arrays
+ for (int i = 0; i < 2; i++){
+ angle = 0;
+ for(int j = 0; j <= pts; j++){
+ vertices[i][j] = new PVector();
+ if (isPyramid){
+ if (i==1){
+ vertices[i][j].x = 0;
+ vertices[i][j].y = 0;
+ }
+ else {
+ vertices[i][j].x = cos(radians(angle)) * radius;
+ vertices[i][j].y = sin(radians(angle)) * radius;
+ }
+ }
+ else {
+ vertices[i][j].x = cos(radians(angle)) * radius;
+ vertices[i][j].y = sin(radians(angle)) * radius;
+ }
+ vertices[i][j].z = cylinderLength;
+ // the .0 after the 360 is critical
+ angle += 360.0/pts;
+ }
+ cylinderLength *= -1;
+ }
+
+ // draw cylinder tube
+ beginShape(QUAD_STRIP);
+ for(int j = 0; j <= pts; j++){
+ vertex(vertices[0][j].x, vertices[0][j].y, vertices[0][j].z);
+ vertex(vertices[1][j].x, vertices[1][j].y, vertices[1][j].z);
+ }
+ endShape();
+
+ //draw cylinder ends
+ for (int i = 0; i < 2; i++){
+ beginShape();
+ for(int j = 0; j < pts; j++){
+ vertex(vertices[i][j].x, vertices[i][j].y, vertices[i][j].z);
+ }
+ endShape(CLOSE);
+ }
+}
+
+
+/*
+ up/down arrow keys control
+ polygon detail.
+ */
+void keyPressed(){
+ if(key == CODED) {
+ // pts
+ if (keyCode == UP) {
+ if (pts < 90){
+ pts++;
+ }
+ }
+ else if (keyCode == DOWN) {
+ if (pts > 4){
+ pts--;
+ }
+ }
+ }
+ if (key =='p'){
+ if (isPyramid){
+ isPyramid = false;
+ }
+ else {
+ isPyramid = true;
+ }
+ }
+}
+
diff --git a/android/examples/OpenGL/Form/SpaceJunk/AndroidManifest.xml b/android/examples/OpenGL/Form/SpaceJunk/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/SpaceJunk/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/SpaceJunk/Cube.pde b/android/examples/OpenGL/Form/SpaceJunk/Cube.pde
new file mode 100755
index 000000000..168ceb5ca
--- /dev/null
+++ b/android/examples/OpenGL/Form/SpaceJunk/Cube.pde
@@ -0,0 +1,73 @@
+
+class Cube {
+
+ // Properties
+ int w, h, d;
+ int shiftX, shiftY, shiftZ;
+
+ // Constructor
+ Cube(int w, int h, int d, int shiftX, int shiftY, int shiftZ){
+ this.w = w;
+ this.h = h;
+ this.d = d;
+ this.shiftX = shiftX;
+ this.shiftY = shiftY;
+ this.shiftZ = shiftZ;
+ }
+
+ // Main cube drawing method, which looks
+ // more confusing than it really is. It's
+ // just a bunch of rectangles drawn for
+ // each cube face
+ void drawCube(){
+ beginShape(QUADS);
+ // Front face
+ normal(0, 0, 1);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
+
+ // Back face
+ normal(0, 0, -1);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(w + shiftX, h + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
+
+ // Left face
+ normal(1, 0, 0);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
+
+ // Right face
+ normal(-1, 0, 0);
+ vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(w + shiftX, h + shiftY, d + shiftZ);
+ vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
+
+ // Top face
+ normal(0, 1, 0);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
+
+ // Bottom face
+ normal(0, -1, 0);
+ vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, h + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
+
+ endShape();
+
+ // Add some rotation to each box for pizazz.
+ rotateY(radians(1));
+ rotateX(radians(1));
+ rotateZ(radians(1));
+ }
+}
diff --git a/android/examples/OpenGL/Form/SpaceJunk/SpaceJunk.pde b/android/examples/OpenGL/Form/SpaceJunk/SpaceJunk.pde
new file mode 100644
index 000000000..1e282df7e
--- /dev/null
+++ b/android/examples/OpenGL/Form/SpaceJunk/SpaceJunk.pde
@@ -0,0 +1,63 @@
+/**
+ * Space Junk
+ * by Ira Greenberg.
+ * Zoom suggestion
+ * by Danny Greenberg.
+ *
+ * Rotating cubes in space using a custom Cube class.
+ * Color controlled by light sources. Move the mouse left
+ * and right to zoom.
+ */
+
+// Used for oveall rotation
+float ang;
+
+// Cube count-lower/raise to test P3D/OPENGL performance
+int limit = 100;
+
+// Array for all cubes
+Cube[]cubes = new Cube[limit];
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ background(0);
+ noStroke();
+
+ // Instantiate cubes, passing in random vals for size and postion
+ for (int i = 0; i< cubes.length; i++){
+ cubes[i] = new Cube(int(random(-10, 10)), int(random(-10, 10)),
+ int(random(-10, 10)), int(random(-140, 140)), int(random(-140, 140)),
+ int(random(-140, 140)));
+ }
+}
+
+void draw(){
+ background(0);
+ fill(200);
+
+ // Set up some different colored lights
+ pointLight(51, 102, 255, 65, 60, 100);
+ pointLight(200, 40, 60, -65, -60, -150);
+
+ // Raise overall light in scene
+ ambientLight(70, 70, 10);
+
+ // Center geometry in display windwow.
+ // you can change 3rd argument ('0')
+ // to move block group closer(+)/further(-)
+ translate(width/2, height/2, -200 + mouseX * 0.65);
+
+ // Rotate around y and x axes
+ rotateY(radians(ang));
+ rotateX(radians(ang));
+
+ // Draw cubes
+ for (int i = 0; i < cubes.length; i++){
+ cubes[i].drawCube();
+ }
+
+ // Used in rotate function calls above
+ ang++;
+}
+
+
diff --git a/android/examples/OpenGL/Form/SpaceJunk/sketch.properties b/android/examples/OpenGL/Form/SpaceJunk/sketch.properties
new file mode 100644
index 000000000..2e0e580dd
--- /dev/null
+++ b/android/examples/OpenGL/Form/SpaceJunk/sketch.properties
@@ -0,0 +1 @@
+mode=Android
diff --git a/android/examples/OpenGL/Form/TexturedSphere/AndroidManifest.xml b/android/examples/OpenGL/Form/TexturedSphere/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/TexturedSphere/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/TexturedSphere/TexturedSphere.pde b/android/examples/OpenGL/Form/TexturedSphere/TexturedSphere.pde
new file mode 100644
index 000000000..a5e6c7df5
--- /dev/null
+++ b/android/examples/OpenGL/Form/TexturedSphere/TexturedSphere.pde
@@ -0,0 +1,174 @@
+// ISSUES: normals not correct at the poles, texture border visible
+
+/**
+ * Textured Sphere
+ * by Mike 'Flux' Chang (cleaned up by Aaron Koblin).
+ * Based on code by Toxi.
+ *
+ * A 3D textured sphere with simple rotation control.
+ * Note: Controls will be inverted when sphere is upside down.
+ * Use an "arc ball" to deal with this appropriately.
+ */
+
+PImage bg;
+PImage texmap;
+
+int sDetail = 35; // Sphere detail setting
+float rotationX = 0;
+float rotationY = 0;
+float velocityX = 0;
+float velocityY = 0;
+float globeRadius = 450;
+float pushBack = 0;
+
+float[] cx, cz, sphereX, sphereY, sphereZ;
+float sinLUT[];
+float cosLUT[];
+float SINCOS_PRECISION = 0.5;
+int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);
+
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ smooth();
+ texmap = loadImage("world32k.jpg");
+ initializeSphere(sDetail);
+}
+
+void draw() {
+ background(0);
+ renderGlobe();
+}
+
+void renderGlobe() {
+ pushMatrix();
+ translate(width/2.0, height/2.0, pushBack);
+ pushMatrix();
+ noFill();
+ stroke(255,200);
+ strokeWeight(2);
+ popMatrix();
+ lights();
+ pushMatrix();
+ rotateX( radians(-rotationX) );
+ rotateY( radians(270 - rotationY) );
+ fill(200);
+ noStroke();
+ textureMode(IMAGE);
+ texturedSphere(globeRadius, texmap);
+ popMatrix();
+ popMatrix();
+ rotationX += velocityX;
+ rotationY += velocityY;
+ velocityX *= 0.95;
+ velocityY *= 0.95;
+
+ // Implements mouse control (interaction will be inverse when sphere is upside down)
+ if(mousePressed){
+ velocityX += (mouseY-pmouseY) * 0.01;
+ velocityY -= (mouseX-pmouseX) * 0.01;
+ }
+}
+
+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++) {
+ vertex(0, -r, 0,u,0);
+ vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
+ u+=iu;
+ }
+ vertex(0, -r, 0,u,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++) {
+ vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
+ vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
+ u+=iu;
+ }
+
+ // Close each ring
+ v1=v11;
+ v2=voff;
+ vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
+ 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;
+ vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
+ vertex(0, r, 0,u,v+iv);
+ u+=iu;
+ }
+ vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
+ endShape();
+
+}
diff --git a/android/examples/OpenGL/Form/Toroid/AndroidManifest.xml b/android/examples/OpenGL/Form/Toroid/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/Toroid/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/Toroid/Toroid.pde b/android/examples/OpenGL/Form/Toroid/Toroid.pde
new file mode 100644
index 000000000..9d36ab2a5
--- /dev/null
+++ b/android/examples/OpenGL/Form/Toroid/Toroid.pde
@@ -0,0 +1,183 @@
+/**
+ * Interactive Toroid
+ * by Ira Greenberg.
+ *
+ * Illustrates the geometric relationship between Toroid, Sphere, and Helix
+ * 3D primitives, as well as lathing principal.
+ *
+ * Instructions:
+ * UP arrow key pts++
+ * DOWN arrow key pts--
+ * LEFT arrow key segments--
+ * RIGHT arrow key segments++
+ * 'a' key toroid radius--
+ * 's' key toroid radius++
+ * 'z' key initial polygon radius--
+ * 'x' key initial polygon radius++
+ * 'w' key toggle wireframe/solid shading
+ * 'h' key toggle sphere/helix
+ */
+
+int pts = 20;
+float angle = 0;
+float radius = 60.0;
+
+// lathe segments
+int segments = 30;
+float latheAngle = 0;
+float latheRadius = 100.0;
+
+//vertices
+PVector vertices[], vertices2[];
+
+// for shaded or wireframe rendering
+boolean isWireFrame = false;
+
+// for optional helix
+boolean isHelix = false;
+float helixOffset = 5.0;
+
+void setup(){
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+}
+
+void draw(){
+ background(50, 64, 42);
+ // basic lighting setup
+ lights();
+ // 2 rendering styles
+ // wireframe or solid
+ if (isWireFrame){
+ stroke(255, 255, 150);
+ noFill();
+ }
+ else {
+ noStroke();
+ fill(150, 195, 125);
+ }
+ //center and spin toroid
+ translate(width/2, height/2, -100);
+
+ rotateX(frameCount*PI/150);
+ rotateY(frameCount*PI/170);
+ rotateZ(frameCount*PI/90);
+
+ // initialize point arrays
+ vertices = new PVector[pts+1];
+ vertices2 = new PVector[pts+1];
+
+ // fill arrays
+ for(int i=0; i<=pts; i++){
+ vertices[i] = new PVector();
+ vertices2[i] = new PVector();
+ vertices[i].x = latheRadius + sin(radians(angle))*radius;
+ if (isHelix){
+ vertices[i].z = cos(radians(angle))*radius-(helixOffset*
+ segments)/2;
+ }
+ else{
+ vertices[i].z = cos(radians(angle))*radius;
+ }
+ angle+=360.0/pts;
+ }
+
+ // draw toroid
+ latheAngle = 0;
+ for(int i=0; i<=segments; i++){
+ beginShape(QUAD_STRIP);
+ for(int j=0; j<=pts; j++){
+ if (i>0){
+ vertex(vertices2[j].x, vertices2[j].y, vertices2[j].z);
+ }
+ vertices2[j].x = cos(radians(latheAngle))*vertices[j].x;
+ vertices2[j].y = sin(radians(latheAngle))*vertices[j].x;
+ vertices2[j].z = vertices[j].z;
+ // optional helix offset
+ if (isHelix){
+ vertices[j].z+=helixOffset;
+ }
+ vertex(vertices2[j].x, vertices2[j].y, vertices2[j].z);
+ }
+ // create extra rotation for helix
+ if (isHelix){
+ latheAngle+=720.0/segments;
+ }
+ else {
+ latheAngle+=360.0/segments;
+ }
+ endShape();
+ }
+}
+
+/*
+ left/right arrow keys control ellipse detail
+ up/down arrow keys control segment detail.
+ 'a','s' keys control lathe radius
+ 'z','x' keys control ellipse radius
+ 'w' key toggles between wireframe and solid
+ 'h' key toggles between toroid and helix
+ */
+void keyPressed(){
+ if(key == CODED) {
+ // pts
+ if (keyCode == UP) {
+ if (pts<40){
+ pts++;
+ }
+ }
+ else if (keyCode == DOWN) {
+ if (pts>3){
+ pts--;
+ }
+ }
+ // extrusion length
+ if (keyCode == LEFT) {
+ if (segments>3){
+ segments--;
+ }
+ }
+ else if (keyCode == RIGHT) {
+ if (segments<80){
+ segments++;
+ }
+ }
+ }
+ // lathe radius
+ if (key =='a'){
+ if (latheRadius>0){
+ latheRadius--;
+ }
+ }
+ else if (key == 's'){
+ latheRadius++;
+ }
+ // ellipse radius
+ if (key =='z'){
+ if (radius>10){
+ radius--;
+ }
+ }
+ else if (key == 'x'){
+ radius++;
+ }
+ // wireframe
+ if (key =='w'){
+ if (isWireFrame){
+ isWireFrame=false;
+ }
+ else {
+ isWireFrame=true;
+ }
+ }
+ // helix
+ if (key =='h'){
+ if (isHelix){
+ isHelix=false;
+ }
+ else {
+ isHelix=true;
+ }
+ }
+}
+
diff --git a/android/examples/OpenGL/Form/Vertices/AndroidManifest.xml b/android/examples/OpenGL/Form/Vertices/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Form/Vertices/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Form/Vertices/Vertices.pde b/android/examples/OpenGL/Form/Vertices/Vertices.pde
new file mode 100644
index 000000000..3d1fa1860
--- /dev/null
+++ b/android/examples/OpenGL/Form/Vertices/Vertices.pde
@@ -0,0 +1,68 @@
+/**
+ * Vertices
+ * by Simon Greenwold.
+ *
+ * Draw a cylinder centered on the y-axis, going down
+ * from y=0 to y=height. The radius at the top can be
+ * different from the radius at the bottom, and the
+ * number of sides drawn is variable.
+ */
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+}
+
+void draw() {
+ background(0);
+ lights();
+ translate(width / 2, height / 2);
+ rotateY(map(mouseX, 0, width, 0, PI));
+ rotateZ(map(mouseY, 0, height, 0, -PI));
+ noStroke();
+ fill(255, 255, 255);
+ translate(0, -40, 0);
+ drawCylinder(10, 180, 200, 16); // Draw a mix between a cylinder and a cone
+ //drawCylinder(70, 70, 120, 64); // Draw a cylinder
+ //drawCylinder(0, 180, 200, 4); // Draw a pyramid
+}
+
+void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
+ float angle = 0;
+ float angleIncrement = TWO_PI / sides;
+ beginShape(QUAD_STRIP);
+ for (int i = 0; i < sides + 1; ++i) {
+ vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
+ vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
+ angle += angleIncrement;
+ }
+ endShape();
+
+ // If it is not a cone, draw the circular top cap
+ if (topRadius != 0) {
+ angle = 0;
+ beginShape(TRIANGLE_FAN);
+
+ // Center point
+ vertex(0, 0, 0);
+ for (int i = 0; i < sides + 1; i++) {
+ vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
+ angle += angleIncrement;
+ }
+ endShape();
+ }
+
+ // If it is not a cone, draw the circular bottom cap
+ if (bottomRadius != 0) {
+ angle = 0;
+ beginShape(TRIANGLE_FAN);
+
+ // Center point
+ vertex(0, tall, 0);
+ for (int i = 0; i < sides + 1; i++) {
+ vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
+ angle += angleIncrement;
+ }
+ endShape();
+ }
+}
diff --git a/android/examples/OpenGL/Image/Blending/AndroidManifest.xml b/android/examples/OpenGL/Image/Blending/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Image/Blending/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Image/Blending/Blending.pde b/android/examples/OpenGL/Image/Blending/Blending.pde
new file mode 100644
index 000000000..6cc6d304b
--- /dev/null
+++ b/android/examples/OpenGL/Image/Blending/Blending.pde
@@ -0,0 +1,81 @@
+// Blending, by Andres Colubri
+// Images can be blended using one of the 10 blending modes
+// available in OPENGL2.
+// Images by Kevin Bjorke.
+
+PImage pic1, pic2;
+int selMode = REPLACE;
+String name = "replace";
+int picAlpha = 255;
+
+void setup() {
+ size(800, 480, P3D);
+ orientation(LANDSCAPE);
+
+ PFont font = createFont(PFont.list()[0], 20);
+ textFont(font, 20);
+
+ pic1 = loadImage("bjorke1.jpg");
+ pic2 = loadImage("bjorke2.jpg");
+}
+
+void draw() {
+ background(0);
+
+ tint(255, 255);
+ image(pic1, 0, 0, pic1.width, pic1.height);
+
+ blendMode(selMode);
+ tint(255, picAlpha);
+ image(pic2, 0, 0, pic2.width, pic2.height);
+
+ blendMode(REPLACE);
+ fill(200, 50, 50);
+ rect(0, height - 50, map(picAlpha, 0, 255, 0, width), 50);
+ fill(255);
+
+ text("Selected blend mode: " + name + ". Click to move to next", 10, pic1.height + 30);
+ text("Drag this bar to change alpha of image", 10, height - 18);
+}
+
+void mousePressed() {
+ if (height - 50 < mouseY) return;
+
+ if (selMode == REPLACE) {
+ selMode = BLEND;
+ name = "blend";
+ } else if (selMode == BLEND) {
+ selMode = ADD;
+ name = "add";
+ } else if (selMode == ADD) {
+ selMode = SUBTRACT;
+ name = "subtract";
+ } else if (selMode == SUBTRACT) {
+ selMode = LIGHTEST;
+ name = "lightest";
+ } else if (selMode == LIGHTEST) {
+ selMode = DARKEST;
+ name = "darkest";
+ } else if (selMode == DARKEST) {
+ selMode = DIFFERENCE;
+ name = "difference";
+ } else if (selMode == DIFFERENCE) {
+ selMode = EXCLUSION;
+ name = "exclusion";
+ } else if (selMode == EXCLUSION) {
+ selMode = MULTIPLY;
+ name = "multiply";
+ } else if (selMode == MULTIPLY) {
+ selMode = SCREEN;
+ name = "screen";
+ } else if (selMode == SCREEN) {
+ selMode = REPLACE;
+ name = "replace";
+ }
+}
+
+void mouseDragged() {
+ if (height - 50 < mouseY) {
+ picAlpha = int(map(mouseX, 0, width, 0, 255));
+ }
+}
diff --git a/android/examples/OpenGL/Image/Explode/AndroidManifest.xml b/android/examples/OpenGL/Image/Explode/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Image/Explode/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Image/Explode/Explode.pde b/android/examples/OpenGL/Image/Explode/Explode.pde
new file mode 100644
index 000000000..668d28743
--- /dev/null
+++ b/android/examples/OpenGL/Image/Explode/Explode.pde
@@ -0,0 +1,46 @@
+// ISSUES: It crashes
+
+/**
+ * Explode
+ * by Daniel Shiffman.
+ *
+ * Mouse horizontal location controls breaking apart of image and
+ * Maps pixels from a 2D image into 3D space. Pixel brightness controls
+ * translation along z axis.
+ */
+
+PImage img; // The source image
+int cellsize = 2; // Dimensions of each cell in the grid
+int columns, rows; // Number of columns and rows in our system
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ img = loadImage("eames.jpg"); // Load the image
+ columns = img.width / cellsize; // Calculate # of columns
+ rows = img.height / cellsize; // Calculate # of rows
+}
+
+void draw() {
+ background(0);
+ // Begin loop for columns
+ for ( int i = 0; i < columns; i++) {
+ // Begin loop for rows
+ for ( int j = 0; j < rows; j++) {
+ int x = i*cellsize + cellsize/2; // x position
+ int y = j*cellsize + cellsize/2; // y position
+ int loc = x + y*img.width; // Pixel array location
+ color c = img.pixels[loc]; // Grab the color
+ // Calculate a z position as a function of mouseX and pixel brightness
+ float z = (mouseX / float(width)) * brightness(img.pixels[loc]) - 20.0;
+ // Translate to the location, set fill and stroke, and draw the rect
+ pushMatrix();
+ translate(x + 200, y + 100, z);
+ fill(c, 204);
+ noStroke();
+ rectMode(CENTER);
+ rect(0, 0, cellsize, cellsize);
+ popMatrix();
+ }
+ }
+}
diff --git a/android/examples/OpenGL/Image/Explode/data/eames.jpg.tmp b/android/examples/OpenGL/Image/Explode/data/eames.jpg.tmp
new file mode 100755
index 000000000..c89377e40
Binary files /dev/null and b/android/examples/OpenGL/Image/Explode/data/eames.jpg.tmp differ
diff --git a/android/examples/OpenGL/Image/Extrusion/AndroidManifest.xml b/android/examples/OpenGL/Image/Extrusion/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Image/Extrusion/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Image/Extrusion/Extrusion.pde b/android/examples/OpenGL/Image/Extrusion/Extrusion.pde
new file mode 100644
index 000000000..2c5eacaa0
--- /dev/null
+++ b/android/examples/OpenGL/Image/Extrusion/Extrusion.pde
@@ -0,0 +1,47 @@
+/**
+ * Extrusion.
+ *
+ * Converts a flat image into spatial data points and rotates the points
+ * around the center.
+ */
+
+PImage extrude;
+int[][] values;
+float angle = 0;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+
+ // Load the image into a new array
+ extrude = loadImage("ystone08.jpg");
+ extrude.loadPixels();
+ values = new int[extrude.width][extrude.height];
+ for (int y = 0; y < extrude.height; y++) {
+ for (int x = 0; x < extrude.width; x++) {
+ color pixel = extrude.get(x, y);
+ values[x][y] = int(brightness(pixel));
+ }
+ }
+}
+
+void draw() {
+ background(0);
+
+ // Update the angle
+ angle += 0.005;
+
+ // Rotate around the center axis
+ translate(width/2, 0, +128);
+ rotateY(angle);
+ translate(-extrude.width/2, 100, +128);
+
+ // Display the image mass
+ for (int y = 0; y < extrude.height; y++) {
+ for (int x = 0; x < extrude.width; x++) {
+ stroke(values[x][y]);
+ point(x, y, -values[x][y]);
+ }
+ }
+
+}
diff --git a/android/examples/OpenGL/Image/ExtrusionGL/AndroidManifest.xml b/android/examples/OpenGL/Image/ExtrusionGL/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Image/ExtrusionGL/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Image/ExtrusionGL/ExtrusionGL.pde b/android/examples/OpenGL/Image/ExtrusionGL/ExtrusionGL.pde
new file mode 100644
index 000000000..a39007e65
--- /dev/null
+++ b/android/examples/OpenGL/Image/ExtrusionGL/ExtrusionGL.pde
@@ -0,0 +1,49 @@
+/**
+ * Extrusion.
+ *
+ * Converts a flat image into spatial data points and rotates the points
+ * around the center.
+ */
+
+PImage a;
+boolean onetime = true;
+int[][] aPixels;
+int[][] values;
+float angle;
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+
+ aPixels = new int[width][height];
+ values = new int[width][height];
+ noFill();
+
+ // Load the image into a new array
+ // Extract the values and store in an array
+ a = loadImage("ystone08.jpg");
+ a.loadPixels();
+ for (int i = 0; i < a.height; i++) {
+ for (int j = 0; j < a.width; j++) {
+ aPixels[j][i] = a.pixels[i*a.width + j];
+ values[j][i] = int(blue(aPixels[j][i]));
+ }
+ }
+}
+
+void draw() {
+ background(255);
+ translate(width/2, height/2, 0);
+ scale(2.0);
+
+ // Update and constrain the angle
+ angle += 0.005;
+ rotateY(angle);
+
+ // Display the image mass
+ for (int i = 0; i < a.height; i += 2) {
+ for (int j = 0; j < a.width; j += 2) {
+ stroke(values[j][i], 153);
+ line(j-a.width/2, i-a.height/2, -values[j][i], j-a.width/2, i-a.height/2, -values[j][i]-10);
+ }
+ }
+}
diff --git a/android/examples/OpenGL/Image/Zoom/AndroidManifest.xml b/android/examples/OpenGL/Image/Zoom/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Image/Zoom/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Image/Zoom/Zoom.pde b/android/examples/OpenGL/Image/Zoom/Zoom.pde
new file mode 100644
index 000000000..8c5c058b7
--- /dev/null
+++ b/android/examples/OpenGL/Image/Zoom/Zoom.pde
@@ -0,0 +1,90 @@
+/**
+ * Zoom.
+ *
+ * Move the cursor over the image to alter its position. Click and press
+ * the mouse to zoom and set the density of the matrix by typing numbers 1-5.
+ * This program displays a series of lines with their heights corresponding to
+ * a color value read from an image.
+ */
+
+PImage img;
+//boolean onetime = true;
+int[][] imgPixels;
+float sval = 1.0;
+float nmx, nmy;
+int res = 5;
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noFill();
+ stroke(255);
+ img = loadImage("ystone08.jpg");
+ imgPixels = new int[img.width][img.height];
+ for (int i = 0; i < img.height; i++) {
+ for (int j = 0; j < img.width; j++) {
+ imgPixels[j][i] = img.get(j, i);
+ }
+ }
+}
+
+void draw()
+{
+ background(0);
+
+ nmx = nmx + (mouseX-nmx)/20;
+ nmy += (mouseY-nmy)/20;
+
+ if(mousePressed) {
+ sval += 0.005;
+ }
+ else {
+ sval -= 0.01;
+ }
+
+ sval = constrain(sval, 1.0, 2.5);
+
+ translate(width/2 + nmx * sval-100, height/2 + nmy*sval - 200, -50);
+ scale(sval);
+ rotateZ(PI/9 - sval + 1.0);
+ rotateX(PI/sval/8 - 0.125);
+ rotateY(sval/8 - 0.125);
+
+ translate(-width/2, -height/2, 0);
+
+ for (int i = 0; i < img.height; i += res) {
+ for (int j = 0; j < img.width; j += res) {
+ float rr = red(imgPixels[j][i]);
+ float gg = green(imgPixels[j][i]);
+ float bb = blue(imgPixels[j][i]);
+ float tt = rr+gg+bb;
+ stroke(rr, gg, gg);
+ line(i, j, tt/10-20, i, j, tt/10 );
+ }
+ }
+}
+
+void keyPressed() {
+ if(key == '1') {
+ res = 1;
+ }
+ else if (key == '2') {
+ res = 2;
+ }
+ else if (key == '3') {
+ res = 3;
+ }
+ else if (key == '4') {
+ res = 4;
+ }
+ else if (key == '5') {
+ res = 5;
+ }
+}
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Immediate/Bezier/AndroidManifest.xml b/android/examples/OpenGL/Immediate/Bezier/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/Bezier/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Immediate/Bezier/Bezier.pde b/android/examples/OpenGL/Immediate/Bezier/Bezier.pde
new file mode 100644
index 000000000..f814feb52
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/Bezier/Bezier.pde
@@ -0,0 +1,23 @@
+/**
+ * Bezier.
+ *
+ * The first two parameters for the bezier() function specify the
+ * first point in the curve and the last two parameters specify
+ * the last point. The middle parameters set the control points
+ * that define the shape of the curve.
+ */
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ stroke(255);
+ noFill();
+}
+
+void draw() {
+ background(0);
+ for (int i = 0; i < 200; i += 20) {
+ bezier(mouseX-(i/2.0), 40+i, 410, 20, 440, 300, 240-(i/16.0), 300+(i/8.0));
+ }
+}
+
diff --git a/android/examples/OpenGL/Immediate/Robot1_Draw/AndroidManifest.xml b/android/examples/OpenGL/Immediate/Robot1_Draw/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/Robot1_Draw/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Immediate/Robot1_Draw/Robot1_Draw.pde b/android/examples/OpenGL/Immediate/Robot1_Draw/Robot1_Draw.pde
new file mode 100644
index 000000000..898b53322
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/Robot1_Draw/Robot1_Draw.pde
@@ -0,0 +1,44 @@
+// ISSUES: non-interactive sketches don't show anything on screen
+
+// Robot 1: Draw from "Getting Started with Processing"
+// by Reas & Fry. O'Reilly / Make 2010
+
+size(720, 480, P3D);
+orientation(LANDSCAPE);
+smooth();
+strokeWeight(2);
+background(204);
+ellipseMode(RADIUS);
+
+// Neck
+stroke(102); // Set stroke to gray
+line(266, 257, 266, 162); // Left
+line(276, 257, 276, 162); // Middle
+line(286, 257, 286, 162); // Right
+
+// Antennae
+line(276, 155, 246, 112); // Small
+line(276, 155, 306, 56); // Tall
+line(276, 155, 342, 170); // Medium
+
+// Body
+noStroke(); // Disable stroke
+fill(102); // Set fill to gray
+ellipse(264, 377, 33, 33); // Antigravity orb
+fill(0); // Set fill to black
+rect(219, 257, 90, 120); // Main body
+fill(102); // Set fill to gray
+rect(219, 274, 90, 6); // Gray stripe
+
+// Head
+fill(0); // Set fill to black
+ellipse(276, 155, 45, 45); // Head
+fill(255); // Set fill to white
+ellipse(288, 150, 14, 14); // Large eye
+fill(0); // Set fill to black
+ellipse(288, 150, 3, 3); // Pupil
+fill(153); // Set fill to light gray
+ellipse(263, 148, 5, 5); // Small eye 1
+ellipse(296, 130, 4, 4); // Small eye 2
+ellipse(305, 162, 3, 3); // Small eye 3
+
diff --git a/android/examples/OpenGL/Immediate/ShapePrimitives/AndroidManifest.xml b/android/examples/OpenGL/Immediate/ShapePrimitives/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/ShapePrimitives/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Immediate/ShapePrimitives/ShapePrimitives.pde b/android/examples/OpenGL/Immediate/ShapePrimitives/ShapePrimitives.pde
new file mode 100644
index 000000000..48006d505
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/ShapePrimitives/ShapePrimitives.pde
@@ -0,0 +1,35 @@
+// ISSUES: non-interactive sketches don't show anything on screen
+
+/**
+ * Shape Primitives.
+ *
+ * The basic shape primitive functions are triangle(),
+ * rect(), quad(), ellipse(), and arc(). Squares are made
+ * with rect() and circles are made with ellipse(). Each
+ * of these functions requires a number of parameters to
+ * determine the shape's position and size.
+ */
+
+size(640, 360, P3D);
+orientation(LANDSCAPE);
+background(0);
+noStroke();
+
+fill(204);
+triangle(18, 18, 18, 360, 81, 360);
+
+fill(102);
+rect(81, 81, 63, 63);
+
+fill(204);
+quad(189, 18, 216, 18, 216, 360, 144, 360);
+
+fill(255);
+ellipse(252, 144, 72, 72);
+
+fill(204);
+triangle(288, 18, 351, 360, 288, 360);
+
+fill(255);
+arc(479, 300, 280, 280, PI, TWO_PI);
+
diff --git a/android/examples/OpenGL/Immediate/TriangleStrip/AndroidManifest.xml b/android/examples/OpenGL/Immediate/TriangleStrip/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/TriangleStrip/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Immediate/TriangleStrip/TriangleStrip.pde b/android/examples/OpenGL/Immediate/TriangleStrip/TriangleStrip.pde
new file mode 100644
index 000000000..d0fdbabea
--- /dev/null
+++ b/android/examples/OpenGL/Immediate/TriangleStrip/TriangleStrip.pde
@@ -0,0 +1,45 @@
+/**
+ * TRIANGLE_STRIP Mode
+ * by Ira Greenberg.
+ *
+ * Generate a closed ring using the vertex() function and
+ * beginShape(TRIANGLE_STRIP) mode. The outerRad and innerRad
+ * variables control ring's radii respectively.
+ */
+
+int x;
+int y;
+float outerRad;
+float innerRad;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ background(204);
+ x = width/2;
+ y = height/2;
+ outerRad = min(width, height) * 0.4;
+ innerRad = outerRad * 0.6;
+}
+
+void draw() {
+ background(204);
+
+ int pts = int(map(mouseX, 0, width, 6, 60));
+ float rot = 180.0/pts;
+ float angle = 0;
+
+ beginShape(TRIANGLE_STRIP);
+ for (int i = 0; i <= pts; i++) {
+ float px = x + cos(radians(angle)) * outerRad;
+ float py = y + sin(radians(angle)) * outerRad;
+ angle += rot;
+ vertex(px, py);
+ px = x + cos(radians(angle)) * innerRad;
+ py = y + sin(radians(angle)) * innerRad;
+ vertex(px, py);
+ angle += rot;
+ }
+ endShape();
+}
+
diff --git a/android/examples/OpenGL/Lights/CameraLight/AndroidManifest.xml b/android/examples/OpenGL/Lights/CameraLight/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/CameraLight/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/CameraLight/CameraLight.pde b/android/examples/OpenGL/Lights/CameraLight/CameraLight.pde
new file mode 100644
index 000000000..551eb20b0
--- /dev/null
+++ b/android/examples/OpenGL/Lights/CameraLight/CameraLight.pde
@@ -0,0 +1,42 @@
+// CameraLight, by Andres Colubri
+// Simple example showing a lit rotating cube. The projection
+// is set to orthographic if the mouse is pressed.
+
+float spin = 0.0;
+
+void setup() {
+ size(400, 400, P3D);
+
+ noStroke();
+}
+
+void draw() {
+ background(51);
+
+ lights();
+
+ if (mousePressed) {
+ // The arguments of ortho are specified in screen coordinates, where (0,0)
+ // is the upper left corner of the screen
+ ortho(0, width, 0, height);
+ } else {
+
+ float fov = PI/3.0;
+ float cameraZ = (height/2.0) / tan(fov/2.0);
+ perspective(fov, float(width)/float(height),
+ cameraZ/2.0, cameraZ*2.0);
+ }
+
+ spin += 0.01;
+
+ pushMatrix();
+ translate(width/2, height/2, 0);
+ rotateX(PI/9);
+ rotateY(PI/5 + spin);
+ box(100);
+ popMatrix();
+}
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/Directional/AndroidManifest.xml b/android/examples/OpenGL/Lights/Directional/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Directional/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/Directional/Directional.pde b/android/examples/OpenGL/Lights/Directional/Directional.pde
new file mode 100644
index 000000000..8613d8ac8
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Directional/Directional.pde
@@ -0,0 +1,29 @@
+/**
+ * Directional.
+ *
+ * Move the mouse the change the direction of the light.
+ * Directional light comes from one direction and is stronger
+ * when hitting a surface squarely and weaker if it hits at a
+ * a gentle angle. After hitting a surface, a directional lights
+ * scatters in all directions.
+ */
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ fill(204);
+}
+
+void draw() {
+ noStroke();
+ background(0);
+ float dirY = (mouseY / float(height) - 0.5) * 2;
+ float dirX = (mouseX / float(width) - 0.5) * 2;
+ directionalLight(204, 204, 204, -dirX, -dirY, -1);
+ translate(width/2 - 100, height/2, 0);
+ sphere(80);
+ translate(200, 0, 0);
+ sphere(80);
+}
+
diff --git a/android/examples/OpenGL/Lights/Lights1/AndroidManifest.xml b/android/examples/OpenGL/Lights/Lights1/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Lights1/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/Lights1/Lights1.pde b/android/examples/OpenGL/Lights/Lights1/Lights1.pde
new file mode 100644
index 000000000..3a92fa736
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Lights1/Lights1.pde
@@ -0,0 +1,30 @@
+/**
+ * Lights 1.
+ *
+ * Uses the default lights to show a simple box. The lights() function
+ * is used to turn on the default lighting.
+ */
+
+float spin = 0.0;
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+}
+
+void draw()
+{
+ background(51);
+ lights();
+
+ spin += 0.01;
+
+ pushMatrix();
+ translate(width/2, height/2, 0);
+ rotateX(PI/9);
+ rotateY(PI/5 + spin);
+ box(150);
+ popMatrix();
+}
diff --git a/android/examples/OpenGL/Lights/Lights2/AndroidManifest.xml b/android/examples/OpenGL/Lights/Lights2/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Lights2/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/Lights2/Lights2.pde b/android/examples/OpenGL/Lights/Lights2/Lights2.pde
new file mode 100644
index 000000000..8567b0564
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Lights2/Lights2.pde
@@ -0,0 +1,37 @@
+/**
+ * Lights 2
+ * by Simon Greenwold.
+ *
+ * Display a box with three different kinds of lights.
+ */
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+}
+
+void draw()
+{
+ background(0);
+ translate(width / 2, height / 2);
+
+ // Orange point light on the right
+ pointLight(150, 100, 0, // Color
+ 200, -150, 0); // Position
+
+ // Blue directional light from the left
+ directionalLight(0, 102, 255, // Color
+ 1, 0, 0); // The x-, y-, z-axis direction
+
+ // Yellow spotlight from the front
+ spotLight(255, 255, 109, // Color
+ 0, 40, 200, // Position
+ 0, -0.5, -0.5, // Direction
+ PI / 2, 2); // Angle, concentration
+
+ rotateY(map(mouseX, 0, width, 0, PI));
+ rotateX(map(mouseY, 0, height, 0, PI));
+ box(150);
+}
diff --git a/android/examples/OpenGL/Lights/LightsGL/AndroidManifest.xml b/android/examples/OpenGL/Lights/LightsGL/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/LightsGL/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/LightsGL/LightsGL.pde b/android/examples/OpenGL/Lights/LightsGL/LightsGL.pde
new file mode 100644
index 000000000..6f07f43bc
--- /dev/null
+++ b/android/examples/OpenGL/Lights/LightsGL/LightsGL.pde
@@ -0,0 +1,45 @@
+/**
+ * LightsGL.
+ * Modified from an example by Simon Greenwold.
+ *
+ * Display a box with three different kinds of lights.
+ */
+
+void setup()
+{
+ size(screenWidth, screenHeight, P3D);
+ noStroke();
+}
+
+void draw()
+{
+ defineLights();
+ background(0);
+
+ for (int x = 0; x <= width; x += 100) {
+ for (int y = 0; y <= height; y += 100) {
+ pushMatrix();
+ translate(x, y);
+ rotateY(map(mouseX, 0, width, 0, PI));
+ rotateX(map(mouseY, 0, height, 0, PI));
+ box(90);
+ popMatrix();
+ }
+ }
+}
+
+void defineLights() {
+ // Orange point light on the right
+ pointLight(150, 100, 0, // Color
+ 200, -150, 0); // Position
+
+ // Blue directional light from the left
+ directionalLight(0, 102, 255, // Color
+ 1, 0, 0); // The x-, y-, z-axis direction
+
+ // Yellow spotlight from the front
+ spotLight(255, 255, 109, // Color
+ 0, 40, 200, // Position
+ 0, -0.5, -0.5, // Direction
+ PI / 2, 2); // Angle, concentration
+}
diff --git a/android/examples/OpenGL/Lights/Reflection/AndroidManifest.xml b/android/examples/OpenGL/Lights/Reflection/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Reflection/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/Reflection/Reflection.pde b/android/examples/OpenGL/Lights/Reflection/Reflection.pde
new file mode 100644
index 000000000..efcf4639e
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Reflection/Reflection.pde
@@ -0,0 +1,26 @@
+/**
+ * Reflection
+ * by Simon Greenwold.
+ *
+ * Vary the specular reflection component of a material
+ * with the horizontal position of the mouse.
+ */
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ colorMode(RGB, 1);
+ fill(0.4);
+}
+
+void draw() {
+ background(0);
+ translate(width / 2, height / 2);
+ // Set the specular color of lights that follow
+ lightSpecular(1, 1, 1);
+ directionalLight(0.8, 0.8, 0.8, 0, 0, -1);
+ float s = mouseX / float(width);
+ specular(s, s, s);
+ sphere(120);
+}
diff --git a/android/examples/OpenGL/Lights/Spot/AndroidManifest.xml b/android/examples/OpenGL/Lights/Spot/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Spot/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Lights/Spot/Spot.pde b/android/examples/OpenGL/Lights/Spot/Spot.pde
new file mode 100644
index 000000000..e64992afe
--- /dev/null
+++ b/android/examples/OpenGL/Lights/Spot/Spot.pde
@@ -0,0 +1,35 @@
+/**
+ * Spot.
+ *
+ * Move the mouse the change the position and concentation
+ * of a blue spot light.
+ */
+
+int concentration = 600; // Try values 1 -> 10000
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ fill(204);
+ sphereDetail(60);
+}
+
+void draw()
+{
+ background(0);
+
+ // Light the bottom of the sphere
+ directionalLight(51, 102, 126, 0, -1, 0);
+
+ // Orange light on the upper-right of the sphere
+ spotLight(204, 153, 0, 360, 160, 600, 0, 0, -1, PI/2, 600);
+
+ // Moving spotlight that follows the mouse
+ spotLight(102, 153, 204, 360, mouseY, 600, 0, 0, -1, PI/2, 600);
+
+ translate(width/2, height/2, 0);
+ sphere(120);
+}
+
diff --git a/android/examples/OpenGL/Performance/CubicGridImmediate/AndroidManifest.xml b/android/examples/OpenGL/Performance/CubicGridImmediate/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/CubicGridImmediate/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/CubicGridImmediate/CubicGridImmediate.pde b/android/examples/OpenGL/Performance/CubicGridImmediate/CubicGridImmediate.pde
new file mode 100644
index 000000000..18ac2bf62
--- /dev/null
+++ b/android/examples/OpenGL/Performance/CubicGridImmediate/CubicGridImmediate.pde
@@ -0,0 +1,63 @@
+/**
+ * Cubic Grid
+ * by Ira Greenberg.
+ *
+ * 3D translucent colored grid uses nested pushMatrix()
+ * and popMatrix() functions.
+ */
+
+float boxSize = 40;
+float margin = boxSize*2;
+float depth = 400;
+color boxFill;
+
+int fcount, lastm;
+float frate;
+int fint = 3;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ frameRate(60);
+ noStroke();
+}
+
+void draw() {
+ background(255);
+
+ hint(DISABLE_DEPTH_TEST);
+
+ // Center and spin grid
+ pushMatrix();
+ translate(width/2, height/2, -depth);
+ rotateY(frameCount * 0.01);
+ rotateX(frameCount * 0.01);
+
+ // Build grid using multiple translations
+ for (float i =- depth/2+margin; i <= depth/2-margin; i += boxSize){
+ for (float j =- height+margin; j <= height-margin; j += boxSize){
+ for (float k =- width+margin; k <= width-margin; k += boxSize){
+ // Base fill color on counter values, abs function
+ // ensures values stay within legal range
+ boxFill = color(abs(i), abs(j), abs(k), 50);
+ pushMatrix();
+ translate(k, j, i);
+ fill(boxFill);
+ box(boxSize, boxSize, boxSize);
+ popMatrix();
+ }
+ }
+ }
+ popMatrix();
+
+ fcount += 1;
+ int m = millis();
+ if (m - lastm > 1000 * fint) {
+ frate = float(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ println("fps: " + frate);
+ }
+ fill(0);
+ text("fps: " + frate, 10, 20);
+}
diff --git a/android/examples/OpenGL/Performance/CubicGridRetained/AndroidManifest.xml b/android/examples/OpenGL/Performance/CubicGridRetained/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/CubicGridRetained/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/CubicGridRetained/CubicGridRetained.pde b/android/examples/OpenGL/Performance/CubicGridRetained/CubicGridRetained.pde
new file mode 100644
index 000000000..63b54809e
--- /dev/null
+++ b/android/examples/OpenGL/Performance/CubicGridRetained/CubicGridRetained.pde
@@ -0,0 +1,112 @@
+float boxSize = 40;
+float margin = boxSize*2;
+float depth = 400;
+color boxFill;
+
+PShape grid;
+
+int fcount, lastm;
+float frate;
+int fint = 3;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ frameRate(60);
+ noStroke();
+
+ grid = createShape(PShape.GROUP);
+
+ // Build grid using multiple translations
+ for (float i =- depth/2+margin; i <= depth/2-margin; i += boxSize){
+ for (float j =- height+margin; j <= height-margin; j += boxSize){
+ for (float k =- width+margin; k <= width-margin; k += boxSize){
+ // Base fill color on counter values, abs function
+ // ensures values stay within legal range
+ boxFill = color(abs(i), abs(j), abs(k), 50);
+
+ PShape cube = createShape(QUADS);
+ cube.noStroke();
+ cube.fill(boxFill);
+
+ float w = boxSize;
+ float h = boxSize;
+ float d = boxSize;
+ float shiftX = k;
+ float shiftY = j;
+ float shiftZ = i;
+
+ // Front face
+ cube.normal(0, 0, 1);
+ cube.vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ);
+
+ // Back face
+ cube.normal(0, 0, -1);
+ cube.vertex(-w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ);
+
+ // Left face
+ cube.normal(1, 0, 0);
+ cube.vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ);
+
+ // Right face
+ cube.normal(-1, 0, 0);
+ cube.vertex(+w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ);
+
+ // Top face
+ cube.normal(0, 1, 0);
+ cube.vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ);
+
+ // Bottom face
+ cube.normal(0, -1, 0);
+ cube.vertex(-w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ);
+ cube.vertex(+w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ);
+ cube.vertex(-w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ);
+
+ cube.end();
+ grid.addChild(cube);
+ }
+ }
+ }
+}
+
+void draw() {
+ background(255);
+
+ hint(DISABLE_DEPTH_TEST);
+
+ // Center and spin grid
+ pushMatrix();
+ translate(width/2, height/2, -depth);
+ rotateY(frameCount * 0.01);
+ rotateX(frameCount * 0.01);
+
+ shape(grid);
+ popMatrix();
+
+ fcount += 1;
+ int m = millis();
+ if (m - lastm > 1000 * fint) {
+ frate = float(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ println("fps: " + frate);
+ }
+ fill(0);
+ text("fps: " + frate, 10, 20);
+}
diff --git a/android/examples/OpenGL/Performance/DynamicParticlesImmediate/AndroidManifest.xml b/android/examples/OpenGL/Performance/DynamicParticlesImmediate/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/DynamicParticlesImmediate/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/DynamicParticlesImmediate/DynamicParticlesImmediate.pde b/android/examples/OpenGL/Performance/DynamicParticlesImmediate/DynamicParticlesImmediate.pde
new file mode 100644
index 000000000..a5d3e630b
--- /dev/null
+++ b/android/examples/OpenGL/Performance/DynamicParticlesImmediate/DynamicParticlesImmediate.pde
@@ -0,0 +1,119 @@
+PImage sprite;
+
+int npartTotal = 1000;
+int npartPerFrame = 15;
+float speed = 1.0;
+float gravity = 0.05;
+float partSize = 20;
+
+int partLifetime;
+PVector positions[];
+PVector velocities[];
+int lifetimes[];
+
+int fcount, lastm;
+float frate;
+int fint = 3;
+
+void setup() {
+ size(640, 480, P3D);
+ orientation(LANDSCAPE);
+ frameRate(60);
+
+ sprite = loadImage("sprite.png");
+
+ partLifetime = npartTotal / npartPerFrame;
+ initPositions();
+ initVelocities();
+ initLifetimes();
+
+ // Writing to the depth buffer is disabled to avoid rendering
+ // artifacts due to the fact that the particles are semi-transparent
+ // but not z-sorted.
+ hint(DISABLE_DEPTH_MASK);
+
+ // Testing some hints
+ //hint(DISABLE_TRANSFORM_CACHE);
+ //hint(ENABLE_ACCURATE_2D);
+}
+
+void draw () {
+ background(0);
+
+ for (int n = 0; n < npartTotal; n++) {
+ lifetimes[n]++;
+ if (lifetimes[n] == partLifetime) {
+ lifetimes[n] = 0;
+ }
+
+ if (0 <= lifetimes[n]) {
+ float opacity = 1.0 - float(lifetimes[n]) / partLifetime;
+
+ if (lifetimes[n] == 0) {
+ // Re-spawn dead particle
+ positions[n].x = mouseX;
+ positions[n].y = mouseY;
+
+ float angle = random(0, TWO_PI);
+ float s = random(0.5 * speed, 0.5 * speed);
+ velocities[n].x = s * cos(angle);
+ velocities[n].y = s * sin(angle);
+ } else {
+ positions[n].x += velocities[n].x;
+ positions[n].y += velocities[n].y;
+
+ velocities[n].y += gravity;
+ }
+ drawParticle(positions[n], opacity);
+ }
+ }
+
+ fcount += 1;
+ int m = millis();
+ if (m - lastm > 1000 * fint) {
+ frate = float(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ println("fps: " + frate);
+ }
+}
+
+void drawParticle(PVector center, float opacity) {
+ beginShape(QUAD);
+ noStroke();
+ tint(255, opacity * 255);
+ texture(sprite);
+ normal(0, 0, 1);
+ vertex(center.x - partSize/2, center.y - partSize/2, 0, 0);
+ vertex(center.x + partSize/2, center.y - partSize/2, sprite.width, 0);
+ vertex(center.x + partSize/2, center.y + partSize/2, sprite.width, sprite.height);
+ vertex(center.x - partSize/2, center.y + partSize/2, 0, sprite.height);
+ endShape();
+}
+
+void initPositions() {
+ positions = new PVector[npartTotal];
+ for (int n = 0; n < positions.length; n++) {
+ positions[n] = new PVector();
+ }
+}
+
+void initVelocities() {
+ velocities = new PVector[npartTotal];
+ for (int n = 0; n < velocities.length; n++) {
+ velocities[n] = new PVector();
+ }
+}
+
+void initLifetimes() {
+ // Initializing particles with negative lifetimes so they are added
+ // progressively into the screen during the first frames of the sketch
+ lifetimes = new int[npartTotal];
+ int t = -1;
+ for (int n = 0; n < lifetimes.length; n++) {
+ if (n % npartPerFrame == 0) {
+ t++;
+ }
+ lifetimes[n] = -t;
+ }
+}
diff --git a/android/examples/OpenGL/Performance/DynamicParticlesRetained/AndroidManifest.xml b/android/examples/OpenGL/Performance/DynamicParticlesRetained/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/DynamicParticlesRetained/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/DynamicParticlesRetained/DynamicParticlesRetained.pde b/android/examples/OpenGL/Performance/DynamicParticlesRetained/DynamicParticlesRetained.pde
new file mode 100644
index 000000000..8a29d148b
--- /dev/null
+++ b/android/examples/OpenGL/Performance/DynamicParticlesRetained/DynamicParticlesRetained.pde
@@ -0,0 +1,110 @@
+PShape particles;
+PImage sprite;
+
+int npartTotal = 1000;
+int npartPerFrame = 15;
+float speed = 1.0;
+float gravity = 0.05;
+float partSize = 20;
+
+int partLifetime;
+PVector velocities[];
+int lifetimes[];
+
+int fcount, lastm;
+float frate;
+int fint = 3;
+
+void setup() {
+ size(640, 480, P3D);
+ orientation(LANDSCAPE);
+ frameRate(60);
+
+ particles = createShape(PShape.GROUP);
+ sprite = loadImage("sprite.png");
+
+ for (int n = 0; n < npartTotal; n++) {
+ PShape part = createShape(QUAD);
+ part.noStroke();
+ part.texture(sprite);
+ part.normal(0, 0, 1);
+ part.vertex(-partSize/2, -partSize/2, 0, 0);
+ part.vertex(+partSize/2, -partSize/2, sprite.width, 0);
+ part.vertex(+partSize/2, +partSize/2, sprite.width, sprite.height);
+ part.vertex(-partSize/2, +partSize/2, 0, sprite.height);
+ part.end();
+ particles.addChild(part);
+ }
+
+ partLifetime = npartTotal / npartPerFrame;
+ initVelocities();
+ initLifetimes();
+
+ // Writing to the depth buffer is disabled to avoid rendering
+ // artifacts due to the fact that the particles are semi-transparent
+ // but not z-sorted.
+ hint(DISABLE_DEPTH_MASK);
+}
+
+void draw () {
+ background(0);
+
+ for (int n = 0; n < particles.getChildCount(); n++) {
+ PShape part = particles.getChild(n);
+
+ lifetimes[n]++;
+ if (lifetimes[n] == partLifetime) {
+ lifetimes[n] = 0;
+ }
+
+ if (0 <= lifetimes[n]) {
+ float opacity = 1.0 - float(lifetimes[n]) / partLifetime;
+ part.tint(255, opacity * 255);
+
+ if (lifetimes[n] == 0) {
+ // Re-spawn dead particle
+ part.center(mouseX, mouseY);
+ float angle = random(0, TWO_PI);
+ float s = random(0.5 * speed, 0.5 * speed);
+ velocities[n].x = s * cos(angle);
+ velocities[n].y = s * sin(angle);
+ } else {
+ part.translate(velocities[n].x, velocities[n].y);
+ velocities[n].y += gravity;
+ }
+ } else {
+ part.tint(0, 0);
+ }
+ }
+
+ shape(particles);
+
+ fcount += 1;
+ int m = millis();
+ if (m - lastm > 1000 * fint) {
+ frate = float(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ println("fps: " + frate);
+ }
+}
+
+void initVelocities() {
+ velocities = new PVector[npartTotal];
+ for (int n = 0; n < velocities.length; n++) {
+ velocities[n] = new PVector();
+ }
+}
+
+void initLifetimes() {
+ // Initializing particles with negative lifetimes so they are added
+ // progressively into the screen during the first frames of the sketch
+ lifetimes = new int[npartTotal];
+ int t = -1;
+ for (int n = 0; n < lifetimes.length; n++) {
+ if (n % npartPerFrame == 0) {
+ t++;
+ }
+ lifetimes[n] = -t;
+ }
+}
diff --git a/android/examples/OpenGL/Performance/DynamicParticlesRetained/sketch.properties b/android/examples/OpenGL/Performance/DynamicParticlesRetained/sketch.properties
new file mode 100644
index 000000000..2e0e580dd
--- /dev/null
+++ b/android/examples/OpenGL/Performance/DynamicParticlesRetained/sketch.properties
@@ -0,0 +1 @@
+mode=Android
diff --git a/android/examples/OpenGL/Performance/Esfera/AndroidManifest.xml b/android/examples/OpenGL/Performance/Esfera/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/Esfera/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/Esfera/Esfera.pde b/android/examples/OpenGL/Performance/Esfera/Esfera.pde
new file mode 100644
index 000000000..b64685116
--- /dev/null
+++ b/android/examples/OpenGL/Performance/Esfera/Esfera.pde
@@ -0,0 +1,89 @@
+/**
+ * Esfera
+ * by David Pena.
+ *
+ * Distribucion aleatoria uniforme sobre la superficie de una esfera.
+ */
+
+int cuantos = 1600;
+pelo[] lista ;
+float[] z = new float[cuantos];
+float[] phi = new float[cuantos];
+float[] largos = new float[cuantos];
+float radio = 200;
+float rx = 0;
+float ry =0;
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ radio = height/3.5;
+
+ lista = new pelo[cuantos];
+ for (int i=0; i
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/LineRendering/LineRendering.pde b/android/examples/OpenGL/Performance/LineRendering/LineRendering.pde
new file mode 100644
index 000000000..fca0ffbbb
--- /dev/null
+++ b/android/examples/OpenGL/Performance/LineRendering/LineRendering.pde
@@ -0,0 +1,19 @@
+public void setup() {
+ size(400, 400, P3D);
+}
+
+public void draw() {
+ background(255);
+ stroke(0, 10);
+ for (int i = 0; i < 5000; i++) {
+ float x0 = random(width);
+ float y0 = random(height);
+ float z0 = random(-100, 100);
+ float x1 = random(width);
+ float y1 = random(height);
+ float z1 = random(-100, 100);
+
+ line(x0, y0, z0, x1, y1, z1);
+ }
+ if (frameCount % 10 == 0) println(frameRate);
+}
diff --git a/android/examples/OpenGL/Performance/QuadRendering/AndroidManifest.xml b/android/examples/OpenGL/Performance/QuadRendering/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/QuadRendering/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/QuadRendering/QuadRendering.pde b/android/examples/OpenGL/Performance/QuadRendering/QuadRendering.pde
new file mode 100644
index 000000000..6f90c88c6
--- /dev/null
+++ b/android/examples/OpenGL/Performance/QuadRendering/QuadRendering.pde
@@ -0,0 +1,18 @@
+// ISSUES: nothing is visible on the screen
+
+public void setup() {
+ size(400, 400, P3D);
+
+ noStroke();
+ fill(0, 1);
+}
+
+public void draw() {
+ background(255);
+ for (int i = 0; i < 5000; i++) {
+ float x = random(width);
+ float y = random(height);
+ rect(x, y, 30, 30);
+ }
+ if (frameCount % 10 == 0) println(frameRate);
+}
diff --git a/android/examples/OpenGL/Performance/StaticParticlesImmediate/AndroidManifest.xml b/android/examples/OpenGL/Performance/StaticParticlesImmediate/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/StaticParticlesImmediate/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/StaticParticlesImmediate/StaticParticlesImmediate.pde b/android/examples/OpenGL/Performance/StaticParticlesImmediate/StaticParticlesImmediate.pde
new file mode 100644
index 000000000..47542be8e
--- /dev/null
+++ b/android/examples/OpenGL/Performance/StaticParticlesImmediate/StaticParticlesImmediate.pde
@@ -0,0 +1,65 @@
+PImage sprite;
+
+int npartTotal = 5000;
+float partSize = 20;
+
+PVector positions[];
+
+int fcount, lastm;
+float frate;
+int fint = 3;
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ frameRate(60);
+
+ sprite = loadImage("sprite.png");
+
+ initPositions();
+
+ // Writing to the depth buffer is disabled to avoid rendering
+ // artifacts due to the fact that the particles are semi-transparent
+ // but not z-sorted.
+ hint(DISABLE_DEPTH_MASK);
+}
+
+void draw () {
+ background(0);
+
+ translate(width/2, height/2);
+ rotateY(frameCount * 0.01);
+
+ for (int n = 0; n < npartTotal; n++) {
+ drawParticle(positions[n]);
+ }
+
+ fcount += 1;
+ int m = millis();
+ if (m - lastm > 1000 * fint) {
+ frate = float(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ println("fps: " + frate);
+ }
+}
+
+void drawParticle(PVector center) {
+ beginShape(QUAD);
+ noStroke();
+ tint(255);
+ texture(sprite);
+ normal(0, 0, 1);
+ vertex(center.x - partSize/2, center.y - partSize/2, center.z, 0, 0);
+ vertex(center.x + partSize/2, center.y - partSize/2, center.z, sprite.width, 0);
+ vertex(center.x + partSize/2, center.y + partSize/2, center.z, sprite.width, sprite.height);
+ vertex(center.x - partSize/2, center.y + partSize/2, center.z, 0, sprite.height);
+ endShape();
+}
+
+void initPositions() {
+ positions = new PVector[npartTotal];
+ for (int n = 0; n < positions.length; n++) {
+ positions[n] = new PVector(random(-500, +500), random(-500, +500), random(-500, +500));
+ }
+}
+
diff --git a/android/examples/OpenGL/Performance/StaticParticlesRetained/AndroidManifest.xml b/android/examples/OpenGL/Performance/StaticParticlesRetained/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/StaticParticlesRetained/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/StaticParticlesRetained/StaticParticlesRetained.pde b/android/examples/OpenGL/Performance/StaticParticlesRetained/StaticParticlesRetained.pde
new file mode 100644
index 000000000..ea48e9297
--- /dev/null
+++ b/android/examples/OpenGL/Performance/StaticParticlesRetained/StaticParticlesRetained.pde
@@ -0,0 +1,59 @@
+PShape particles;
+PImage sprite;
+
+int npartTotal = 5000;
+float partSize = 20;
+
+int fcount, lastm;
+float frate;
+int fint = 3;
+
+void setup() {
+ size(screenWidth, screenHeight, P3D);
+ frameRate(60);
+
+ particles = createShape(PShape.GROUP);
+ sprite = loadImage("sprite.png");
+
+ for (int n = 0; n < npartTotal; n++) {
+ float cx = random(-500, +500);
+ float cy = random(-500, +500);
+ float cz = random(-500, +500);
+
+ PShape part = createShape(QUAD);
+ part.noStroke();
+ part.tint(255);
+ part.texture(sprite);
+ part.normal(0, 0, 1);
+ part.vertex(cx - partSize/2, cy - partSize/2, cz, 0, 0);
+ part.vertex(cx + partSize/2, cy - partSize/2, cz, sprite.width, 0);
+ part.vertex(cx + partSize/2, cy + partSize/2, cz, sprite.width, sprite.height);
+ part.vertex(cx - partSize/2, cy + partSize/2, cz, 0, sprite.height);
+ part.end();
+ particles.addChild(part);
+ }
+
+ // Writing to the depth buffer is disabled to avoid rendering
+ // artifacts due to the fact that the particles are semi-transparent
+ // but not z-sorted.
+ hint(DISABLE_DEPTH_MASK);
+}
+
+void draw () {
+ background(0);
+
+ translate(width/2, height/2);
+ rotateY(frameCount * 0.01);
+
+ shape(particles);
+
+ fcount += 1;
+ int m = millis();
+ if (m - lastm > 1000 * fint) {
+ frate = float(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ println("fps: " + frate);
+ }
+}
+
diff --git a/android/examples/OpenGL/Performance/StaticParticlesRetained/sketch.properties b/android/examples/OpenGL/Performance/StaticParticlesRetained/sketch.properties
new file mode 100644
index 000000000..2e0e580dd
--- /dev/null
+++ b/android/examples/OpenGL/Performance/StaticParticlesRetained/sketch.properties
@@ -0,0 +1 @@
+mode=Android
diff --git a/android/examples/OpenGL/Performance/TextRendering/AndroidManifest.xml b/android/examples/OpenGL/Performance/TextRendering/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Performance/TextRendering/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Performance/TextRendering/TextRendering.pde b/android/examples/OpenGL/Performance/TextRendering/TextRendering.pde
new file mode 100644
index 000000000..b97d3350b
--- /dev/null
+++ b/android/examples/OpenGL/Performance/TextRendering/TextRendering.pde
@@ -0,0 +1,14 @@
+public void setup() {
+ size(400, 400, P3D);
+ fill(0);
+}
+
+public void draw() {
+ background(255);
+ for (int i = 0; i < 1000; i++) {
+ float x = random(width);
+ float y = random(height);
+ text("HELLO", x, y);
+ }
+ if (frameCount % 10 == 0) println(frameRate);
+}
diff --git a/android/examples/OpenGL/Retained/PolyImmediate/AndroidManifest.xml b/android/examples/OpenGL/Retained/PolyImmediate/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Retained/PolyImmediate/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Retained/PolyImmediate/PolyImmediate.pde b/android/examples/OpenGL/Retained/PolyImmediate/PolyImmediate.pde
new file mode 100644
index 000000000..f8c225d8c
--- /dev/null
+++ b/android/examples/OpenGL/Retained/PolyImmediate/PolyImmediate.pde
@@ -0,0 +1,24 @@
+// ISSUES: non-interactive sketches don't show anything on screen,
+// and polygon tessellation still not implemented.
+
+size(100, 100, P3D);
+
+beginShape(POLYGON);
+fill(0, 255, 0, 255);
+stroke(0, 0, 255, 255);
+strokeWeight(5);
+strokeJoin(ROUND);
+beginContour();
+vertex(10, 10);
+vertex(10, 90);
+vertex(90, 90);
+vertex(90, 10);
+endContour();
+beginContour();
+vertex(40, 40);
+vertex(70, 40);
+vertex(70, 70);
+vertex(40, 70);
+endContour();
+endShape(CLOSE);
+
diff --git a/android/examples/OpenGL/Retained/PolyRetain/AndroidManifest.xml b/android/examples/OpenGL/Retained/PolyRetain/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Retained/PolyRetain/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Retained/PolyRetain/PolyRetain.pde b/android/examples/OpenGL/Retained/PolyRetain/PolyRetain.pde
new file mode 100644
index 000000000..c639039f2
--- /dev/null
+++ b/android/examples/OpenGL/Retained/PolyRetain/PolyRetain.pde
@@ -0,0 +1,25 @@
+// ISSUES: non-interactive sketches don't show anything on screen,
+// and polygon tessellation still not implemented.
+
+size(100, 100, P3D);
+
+PShape obj = createShape(POLYGON);
+obj.fill(0, 255, 0, 255);
+obj.stroke(0, 0, 255, 255);
+obj.strokeWeight(5);
+obj.strokeJoin(ROUND);
+obj.beginContour();
+obj.vertex(10, 10);
+obj.vertex(10, 90);
+obj.vertex(90, 90);
+obj.vertex(90, 10);
+obj.endContour();
+obj.beginContour();
+obj.vertex(40, 40);
+obj.vertex(70, 40);
+obj.vertex(70, 70);
+obj.vertex(40, 70);
+obj.endContour();
+obj.end(CLOSE);
+
+shape(obj);
diff --git a/android/examples/OpenGL/Retained/Primitive/AndroidManifest.xml b/android/examples/OpenGL/Retained/Primitive/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Retained/Primitive/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Retained/Primitive/Primitive.pde b/android/examples/OpenGL/Retained/Primitive/Primitive.pde
new file mode 100644
index 000000000..e216a9ff6
--- /dev/null
+++ b/android/examples/OpenGL/Retained/Primitive/Primitive.pde
@@ -0,0 +1,43 @@
+PShape circle;
+boolean filled = true;
+boolean stroked = true;
+
+public void setup() {
+ size(400, 400, P3D);
+ frameRate(60);
+
+ fill(255, 0, 0);
+ stroke(0, 0, 255);
+ strokeWeight(3);
+ circle = createShape(ELLIPSE, 0, 0, 100, 100);
+}
+
+public void draw () {
+ background(0);
+
+ if (5000 < millis()) {
+ if (filled) circle.fill(map(mouseX, 0, width, 255, 0), 0, 0);
+ if (stroked) circle.stroke(0, 0, map(mouseY, 0, height, 255, 0));
+ }
+
+ translate(mouseX, mouseY);
+ shape(circle);
+}
+
+void keyPressed() {
+ if (key == 's') {
+ if (stroked) {
+ circle.noStroke();
+ stroked = false;
+ } else {
+ stroked = true;
+ }
+ } else if (key == 'f') {
+ if (filled) {
+ circle.noFill();
+ filled = false;
+ } else {
+ filled = true;
+ }
+ }
+}
diff --git a/android/examples/OpenGL/Retained/Shape2_18/AndroidManifest.xml b/android/examples/OpenGL/Retained/Shape2_18/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Retained/Shape2_18/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Retained/Shape2_18/Shape2_18.pde b/android/examples/OpenGL/Retained/Shape2_18/Shape2_18.pde
new file mode 100644
index 000000000..6a195183e
--- /dev/null
+++ b/android/examples/OpenGL/Retained/Shape2_18/Shape2_18.pde
@@ -0,0 +1,18 @@
+// ISSUES: non-interactive sketches don't show anything on screen,
+// and polygon tessellation still not implemented.
+
+size(100, 100, P3D);
+smooth();
+
+PShape obj = createShape();
+obj.noFill();
+obj.stroke(0);
+obj.strokeWeight(1);
+obj.vertex(15, 40); // V1 (see p.76)
+obj.bezierVertex(5, 0, 80, 0, 50, 55); // C1, C2, V2
+obj.vertex(30, 45); // V3
+obj.vertex(25, 75); // V4
+obj.bezierVertex(50, 70, 75, 90, 80, 70); // C3, C4, V5
+obj.end();
+
+shape(obj);
diff --git a/android/examples/OpenGL/Textures/Texture1/AndroidManifest.xml b/android/examples/OpenGL/Textures/Texture1/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Textures/Texture1/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Textures/Texture1/Texture1.pde b/android/examples/OpenGL/Textures/Texture1/Texture1.pde
new file mode 100644
index 000000000..463a7ac86
--- /dev/null
+++ b/android/examples/OpenGL/Textures/Texture1/Texture1.pde
@@ -0,0 +1,32 @@
+// ISSUES: beginShape() need to be called with QUADS because generic polygon
+// tesselation still not implemented
+
+/**
+ * Texture 1.
+ *
+ * Load an image and draw it onto a quad. The texture() function sets
+ * the texture image. The vertex() function maps the image to the geometry.
+ */
+
+PImage img;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ img = loadImage("berlin-1.jpg");
+ noStroke();
+}
+
+void draw() {
+ background(0);
+ translate(width / 2, height / 2);
+ rotateY(map(mouseX, 0, width, -PI, PI));
+ rotateZ(PI/6);
+ beginShape(QUADS);
+ texture(img);
+ vertex(-100, -100, 0, 0, 0);
+ vertex(100, -100, 0, 400, 0);
+ vertex(100, 100, 0, 400, 400);
+ vertex(-100, 100, 0, 0, 400);
+ endShape();
+}
diff --git a/android/examples/OpenGL/Textures/Texture2/AndroidManifest.xml b/android/examples/OpenGL/Textures/Texture2/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Textures/Texture2/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Textures/Texture2/Texture2.pde b/android/examples/OpenGL/Textures/Texture2/Texture2.pde
new file mode 100644
index 000000000..5a510fce1
--- /dev/null
+++ b/android/examples/OpenGL/Textures/Texture2/Texture2.pde
@@ -0,0 +1,29 @@
+// ISSUES: beginShape() need to be called with TRIANGLES because generic polygon
+// tesselation still not implemented
+
+/**
+ * Texture 2.
+ *
+ * Using a rectangular image to map a texture onto a triangle.
+ */
+
+PImage img;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ img = loadImage("berlin-1.jpg");
+ noStroke();
+}
+
+void draw() {
+ background(0);
+ translate(width / 2, height / 2);
+ rotateY(map(mouseX, 0, width, -PI, PI));
+ beginShape(TRIANGLES);
+ texture(img);
+ vertex(-100, -100, 0, 0, 0);
+ vertex(100, -40, 0, 400, 120);
+ vertex(0, 100, 0, 200, 400);
+ endShape();
+}
diff --git a/android/examples/OpenGL/Textures/Texture3/AndroidManifest.xml b/android/examples/OpenGL/Textures/Texture3/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Textures/Texture3/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Textures/Texture3/Texture3.pde b/android/examples/OpenGL/Textures/Texture3/Texture3.pde
new file mode 100644
index 000000000..7735271e2
--- /dev/null
+++ b/android/examples/OpenGL/Textures/Texture3/Texture3.pde
@@ -0,0 +1,47 @@
+/**
+ * Texture 3.
+ *
+ * Load an image and draw it onto a cylinder and a quad.
+ */
+
+
+int tubeRes = 32;
+float[] tubeX = new float[tubeRes];
+float[] tubeY = new float[tubeRes];
+PImage img;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ img = loadImage("berlin-1.jpg");
+ float angle = 270.0 / tubeRes;
+ for (int i = 0; i < tubeRes; i++) {
+ tubeX[i] = cos(radians(i * angle));
+ tubeY[i] = sin(radians(i * angle));
+ }
+ noStroke();
+}
+
+void draw() {
+ background(0);
+ translate(width / 2, height / 2);
+ rotateX(map(mouseY, 0, height, -PI, PI));
+ rotateY(map(mouseX, 0, width, -PI, PI));
+ beginShape(QUAD_STRIP);
+ texture(img);
+ for (int i = 0; i < tubeRes; i++) {
+ float x = tubeX[i] * 100;
+ float z = tubeY[i] * 100;
+ float u = img.width / tubeRes * i;
+ vertex(x, -100, z, u, 0);
+ vertex(x, 100, z, u, img.height);
+ }
+ endShape();
+ beginShape(QUADS);
+ texture(img);
+ vertex(0, -100, 0, 0, 0);
+ vertex(100, -100, 0, 100, 0);
+ vertex(100, 100, 0, 100, 100);
+ vertex(0, 100, 0, 0, 100);
+ endShape();
+}
diff --git a/android/examples/OpenGL/Textures/TextureCube/AndroidManifest.xml b/android/examples/OpenGL/Textures/TextureCube/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Textures/TextureCube/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Textures/TextureCube/TextureCube.pde b/android/examples/OpenGL/Textures/TextureCube/TextureCube.pde
new file mode 100644
index 000000000..2b52ac06d
--- /dev/null
+++ b/android/examples/OpenGL/Textures/TextureCube/TextureCube.pde
@@ -0,0 +1,91 @@
+/**
+ * TexturedCube
+ * by Dave Bollinger.
+ *
+ * Drag mouse to rotate cube. Demonstrates use of u/v coords in
+ * vertex() and effect on texture().
+ */
+
+
+PImage tex;
+float rotx = PI/4;
+float roty = PI/4;
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ tex = loadImage("berlin-1.jpg");
+ textureMode(NORMAL);
+ fill(255);
+ stroke(color(44,48,32));
+}
+
+void draw()
+{
+ background(0);
+ noStroke();
+ translate(width/2.0, height/2.0, -100);
+ rotateX(rotx);
+ rotateY(roty);
+ scale(90);
+ TexturedCube(tex);
+}
+
+void TexturedCube(PImage tex) {
+ beginShape(QUADS);
+ texture(tex);
+
+ // Given one texture and six faces, we can easily set up the uv coordinates
+ // such that four of the faces tile "perfectly" along either u or v, but the other
+ // two faces cannot be so aligned. This code tiles "along" u, "around" the X/Z faces
+ // and fudges the Y faces - the Y faces are arbitrarily aligned such that a
+ // rotation along the X axis will put the "top" of either texture at the "top"
+ // of the screen, but is not otherwised aligned with the X/Z faces. (This
+ // just affects what type of symmetry is required if you need seamless
+ // tiling all the way around the cube)
+
+ // +Z "front" face
+ vertex(-1, -1, 1, 0, 0);
+ vertex( 1, -1, 1, 1, 0);
+ vertex( 1, 1, 1, 1, 1);
+ vertex(-1, 1, 1, 0, 1);
+
+ // -Z "back" face
+ vertex( 1, -1, -1, 0, 0);
+ vertex(-1, -1, -1, 1, 0);
+ vertex(-1, 1, -1, 1, 1);
+ vertex( 1, 1, -1, 0, 1);
+
+ // +Y "bottom" face
+ vertex(-1, 1, 1, 0, 0);
+ vertex( 1, 1, 1, 1, 0);
+ vertex( 1, 1, -1, 1, 1);
+ vertex(-1, 1, -1, 0, 1);
+
+ // -Y "top" face
+ vertex(-1, -1, -1, 0, 0);
+ vertex( 1, -1, -1, 1, 0);
+ vertex( 1, -1, 1, 1, 1);
+ vertex(-1, -1, 1, 0, 1);
+
+ // +X "right" face
+ vertex( 1, -1, 1, 0, 0);
+ vertex( 1, -1, -1, 1, 0);
+ vertex( 1, 1, -1, 1, 1);
+ vertex( 1, 1, 1, 0, 1);
+
+ // -X "left" face
+ vertex(-1, -1, -1, 0, 0);
+ vertex(-1, -1, 1, 1, 0);
+ vertex(-1, 1, 1, 1, 1);
+ vertex(-1, 1, -1, 0, 1);
+
+ endShape();
+}
+
+void mouseDragged() {
+ float rate = 0.01;
+ rotx += (pmouseY-mouseY) * rate;
+ roty += (mouseX-pmouseX) * rate;
+}
diff --git a/android/examples/OpenGL/Transform/Bird/AndroidManifest.xml b/android/examples/OpenGL/Transform/Bird/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Bird/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Transform/Bird/Bird.pde b/android/examples/OpenGL/Transform/Bird/Bird.pde
new file mode 100644
index 000000000..a1150c87f
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Bird/Bird.pde
@@ -0,0 +1,64 @@
+/**
+ * Simple 3D Bird
+ * by Ira Greenberg.
+ *
+ * Using a box and 2 rects to simulate a flying bird.
+ * Trig functions handle the flapping and sinuous movement.
+ */
+
+float ang = 0, ang2 = 0, ang3 = 0, ang4 = 0;
+float px = 0, py = 0, pz = 0;
+float flapSpeed = 0.2;
+
+void setup(){
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+}
+
+void draw(){
+ background(0);
+ lights();
+
+ // Flight
+ px = sin(radians(ang3)) * 170;
+ py = cos(radians(ang3)) * 300;
+ pz = sin(radians(ang4)) * 500;
+ translate(width/2 + px, height/2 + py, -700+pz);
+ rotateX(sin(radians(ang2)) * 120);
+ rotateY(sin(radians(ang2)) * 50);
+ rotateZ(sin(radians(ang2)) * 65);
+
+ // Body
+ fill(153);
+ box(20, 100, 20);
+
+
+ // Left wing
+ fill(204);
+ pushMatrix();
+ rotateY(sin(radians(ang)) * -20);
+ rect(-75, -50, 75, 100);
+ popMatrix();
+
+ // Right wing
+ pushMatrix();
+ rotateY(sin(radians(ang)) * 20);
+ rect(0, -50, 75, 100);
+ popMatrix();
+
+ // Wing flap
+ ang += flapSpeed;
+ if (ang > 3) {
+ flapSpeed *= -1;
+ }
+ if (ang < -3) {
+ flapSpeed *= -1;
+ }
+
+ // Increment angles
+ ang2 += 0.01;
+ ang3 += 2.0;
+ ang4 += 0.75;
+}
+
diff --git a/android/examples/OpenGL/Transform/Bird/sketch.properties b/android/examples/OpenGL/Transform/Bird/sketch.properties
new file mode 100644
index 000000000..2e0e580dd
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Bird/sketch.properties
@@ -0,0 +1 @@
+mode=Android
diff --git a/android/examples/OpenGL/Transform/Birds/AndroidManifest.xml b/android/examples/OpenGL/Transform/Birds/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Birds/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Transform/Birds/Bird.pde b/android/examples/OpenGL/Transform/Birds/Bird.pde
new file mode 100755
index 000000000..84ada2603
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Birds/Bird.pde
@@ -0,0 +1,99 @@
+class Bird {
+
+ // Properties
+ float offsetX, offsetY, offsetZ;
+ float w, h;
+ int bodyFill;
+ int wingFill;
+ float ang = 0, ang2 = 0, ang3 = 0, ang4 = 0;
+ float radiusX = 120, radiusY = 200, radiusZ = 700;
+ float rotX = 15, rotY = 10, rotZ = 5;
+ float flapSpeed = 0.4;
+ float rotSpeed = 0.1;
+
+ // Constructors
+ Bird(){
+ this(0, 0, 0, 60, 80);
+ }
+
+ Bird(float offsetX, float offsetY, float offsetZ,
+ float w, float h){
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+ this.offsetZ = offsetZ;
+ this.h = h;
+ this.w = w;
+ bodyFill = color(153);
+ wingFill = color(204);
+ }
+
+ void setFlight(float radiusX, float radiusY, float radiusZ,
+ float rotX, float rotY, float rotZ){
+ this.radiusX = radiusX;
+ this.radiusY = radiusY;
+ this.radiusZ = radiusZ;
+
+ this.rotX = rotX;
+ this.rotY = rotY;
+ this.rotZ = rotZ;
+ }
+
+ void setWingSpeed(float flapSpeed){
+ this.flapSpeed = flapSpeed;
+ }
+
+ void setRotSpeed(float rotSpeed){
+ this.rotSpeed = rotSpeed;
+ }
+
+ void fly() {
+ pushMatrix();
+ float px, py, pz;
+
+ // Flight
+ px = sin(radians(ang3)) * radiusX;
+ py = cos(radians(ang3)) * radiusY;
+ pz = sin(radians(ang4)) * radiusZ;
+
+ translate(width/2 + offsetX + px, height/2 + offsetY+py, -700 + offsetZ+pz);
+
+ rotateX(sin(radians(ang2)) * rotX);
+ rotateY(sin(radians(ang2)) * rotY);
+ rotateZ(sin(radians(ang2)) * rotZ);
+
+ // Body
+ fill(bodyFill);
+ box(w/5, h, w/5);
+
+ // Left wing
+ fill(wingFill);
+ pushMatrix();
+ rotateY(sin(radians(ang)) * 20);
+ rect(0, -h/2, w, h);
+ popMatrix();
+
+ // Right wing
+ pushMatrix();
+ rotateY(sin(radians(ang)) * -20);
+ rect(-w, -h/2, w, h);
+ popMatrix();
+
+ // Wing flap
+ ang += flapSpeed;
+ if (ang > 3) {
+ flapSpeed*=-1;
+ }
+ if (ang < -3) {
+ flapSpeed*=-1;
+ }
+
+ // Ang's run trig functions
+ ang2 += rotSpeed;
+ ang3 += 1.25;
+ ang4 += 0.55;
+ popMatrix();
+ }
+}
+
+
+
diff --git a/android/examples/OpenGL/Transform/Birds/Birds.pde b/android/examples/OpenGL/Transform/Birds/Birds.pde
new file mode 100644
index 000000000..b964f744b
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Birds/Birds.pde
@@ -0,0 +1,54 @@
+/**
+ * Crazy Flocking 3D Birds
+ * by Ira Greenberg.
+ *
+ * Simulates a flock of birds using a Bird class and nested
+ * pushMatrix() / popMatrix() functions.
+ * Trigonometry functions handle the flapping and sinuous movement.
+ */
+
+// Flock array
+int birdCount = 200;
+Bird[]birds = new Bird[birdCount];
+float[]x = new float[birdCount];
+float[]y = new float[birdCount];
+float[]z = new float[birdCount];
+float[]rx = new float[birdCount];
+float[]ry = new float[birdCount];
+float[]rz = new float[birdCount];
+float[]spd = new float[birdCount];
+float[]rot = new float[birdCount];
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+
+ // Initialize arrays with random values
+ for (int i = 0; i < birdCount; i++){
+ birds[i] = new Bird(random(-300, 300), random(-300, 300),
+ random(-500, -2500), random(5, 30), random(5, 30));
+
+ x[i] = random(20, 340);
+ y[i] = random(30, 350);
+ z[i] = random(1000, 4800);
+ rx[i] = random(-160, 160);
+ ry[i] = random(-55, 55);
+ rz[i] = random(-20, 20);
+ spd[i] = random(.1, 3.75);
+ rot[i] = random(.025, .15);
+ }
+}
+
+void draw() {
+ background(0);
+ lights();
+ for (int i = 0; i < birdCount; i++){
+ birds[i].setFlight(x[i], y[i], z[i], rx[i], ry[i], rz[i]);
+ birds[i].setWingSpeed(spd[i]);
+ birds[i].setRotSpeed(rot[i]);
+ birds[i].fly();
+ }
+}
+
+
diff --git a/android/examples/OpenGL/Transform/CubesWithinCube/AndroidManifest.xml b/android/examples/OpenGL/Transform/CubesWithinCube/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Transform/CubesWithinCube/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Transform/CubesWithinCube/Cube.pde b/android/examples/OpenGL/Transform/CubesWithinCube/Cube.pde
new file mode 100755
index 000000000..271792623
--- /dev/null
+++ b/android/examples/OpenGL/Transform/CubesWithinCube/Cube.pde
@@ -0,0 +1,72 @@
+
+// Custom Cube Class
+
+class Cube{
+ PVector[] vertices = new PVector[24];
+ float w, h, d;
+
+ // Default constructor
+ Cube(){ }
+
+ // Constructor 2
+ Cube(float w, float h, float d) {
+ this.w = w;
+ this.h = h;
+ this.d = d;
+
+ // cube composed of 6 quads
+ //front
+ vertices[0] = new PVector(-w/2,-h/2,d/2);
+ vertices[1] = new PVector(w/2,-h/2,d/2);
+ vertices[2] = new PVector(w/2,h/2,d/2);
+ vertices[3] = new PVector(-w/2,h/2,d/2);
+ //left
+ vertices[4] = new PVector(-w/2,-h/2,d/2);
+ vertices[5] = new PVector(-w/2,-h/2,-d/2);
+ vertices[6] = new PVector(-w/2,h/2,-d/2);
+ vertices[7] = new PVector(-w/2,h/2,d/2);
+ //right
+ vertices[8] = new PVector(w/2,-h/2,d/2);
+ vertices[9] = new PVector(w/2,-h/2,-d/2);
+ vertices[10] = new PVector(w/2,h/2,-d/2);
+ vertices[11] = new PVector(w/2,h/2,d/2);
+ //back
+ vertices[12] = new PVector(-w/2,-h/2,-d/2);
+ vertices[13] = new PVector(w/2,-h/2,-d/2);
+ vertices[14] = new PVector(w/2,h/2,-d/2);
+ vertices[15] = new PVector(-w/2,h/2,-d/2);
+ //top
+ vertices[16] = new PVector(-w/2,-h/2,d/2);
+ vertices[17] = new PVector(-w/2,-h/2,-d/2);
+ vertices[18] = new PVector(w/2,-h/2,-d/2);
+ vertices[19] = new PVector(w/2,-h/2,d/2);
+ //bottom
+ vertices[20] = new PVector(-w/2,h/2,d/2);
+ vertices[21] = new PVector(-w/2,h/2,-d/2);
+ vertices[22] = new PVector(w/2,h/2,-d/2);
+ vertices[23] = new PVector(w/2,h/2,d/2);
+ }
+ void create(){
+ // Draw cube
+ for (int i=0; i<6; i++){
+ beginShape(QUADS);
+ for (int j=0; j<4; j++){
+ vertex(vertices[j+4*i].x, vertices[j+4*i].y, vertices[j+4*i].z);
+ }
+ endShape();
+ }
+ }
+ void create(color[]quadBG){
+ // Draw cube
+ for (int i=0; i<6; i++){
+ fill(quadBG[i]);
+ beginShape(QUADS);
+ for (int j=0; j<4; j++){
+ vertex(vertices[j+4*i].x, vertices[j+4*i].y, vertices[j+4*i].z);
+ }
+ endShape();
+ }
+ }
+}
+
+
diff --git a/android/examples/OpenGL/Transform/CubesWithinCube/CubesWithinCube.pde b/android/examples/OpenGL/Transform/CubesWithinCube/CubesWithinCube.pde
new file mode 100644
index 000000000..9a07dbc12
--- /dev/null
+++ b/android/examples/OpenGL/Transform/CubesWithinCube/CubesWithinCube.pde
@@ -0,0 +1,118 @@
+/**
+ * Cubes Contained Within a Cube
+ * by Ira Greenberg.
+ *
+ * Collision detection against all
+ * outer cube's surfaces.
+ * Uses the Point3D and Cube classes.
+ */
+
+Cube stage; // external large cube
+int cubies = 20;
+Cube[]c = new Cube[cubies]; // internal little cubes
+color[][]quadBG = new color[cubies][6];
+
+// Controls cubie's movement
+float[]x = new float[cubies];
+float[]y = new float[cubies];
+float[]z = new float[cubies];
+float[]xSpeed = new float[cubies];
+float[]ySpeed = new float[cubies];
+float[]zSpeed = new float[cubies];
+
+// Controls cubie's rotation
+float[]xRot = new float[cubies];
+float[]yRot = new float[cubies];
+float[]zRot = new float[cubies];
+
+// Size of external cube
+float bounds = 300;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+
+ for (int i = 0; i < cubies; i++){
+ // Each cube face has a random color component
+ float colorShift = random(-75, 75);
+ quadBG[i][0] = color(0);
+ quadBG[i][1] = color(51);
+ quadBG[i][2] = color(102);
+ quadBG[i][3] = color(153);
+ quadBG[i][4] = color(204);
+ quadBG[i][5] = color(255);
+
+ // Cubies are randomly sized
+ float cubieSize = random(5, 15);
+ c[i] = new Cube(cubieSize, cubieSize, cubieSize);
+
+ // Initialize cubie's position, speed and rotation
+ x[i] = 0;
+ y[i] = 0;
+ z[i] = 0;
+
+ xSpeed[i] = random(-1, 1);
+ ySpeed[i] = random(-1, 1);
+ zSpeed[i] = random(-1, 1);
+
+ xRot[i] = random(40, 100);
+ yRot[i] = random(40, 100);
+ zRot[i] = random(40, 100);
+ }
+
+ // Instantiate external large cube
+ stage = new Cube(bounds, bounds, bounds);
+}
+
+void draw(){
+ background(50);
+ lights();
+
+ // Center in display window
+ translate(width/2, height/2, -130);
+
+ // Outer transparent cube
+ noFill();
+
+ // Rotate everything, including external large cube
+ rotateX(frameCount * 0.001);
+ rotateY(frameCount * 0.002);
+ rotateZ(frameCount * 0.001);
+ stroke(255);
+
+ // Draw external large cube
+ stage.create();
+
+ // Move and rotate cubies
+ for (int i = 0; i < cubies; i++){
+ pushMatrix();
+ translate(x[i], y[i], z[i]);
+ rotateX(frameCount*PI/xRot[i]);
+ rotateY(frameCount*PI/yRot[i]);
+ rotateX(frameCount*PI/zRot[i]);
+ noStroke();
+ c[i].create(quadBG[i]);
+ x[i] += xSpeed[i];
+ y[i] += ySpeed[i];
+ z[i] += zSpeed[i];
+ popMatrix();
+
+ // Draw lines connecting cubbies
+ stroke(0);
+ if (i < cubies-1){
+ line(x[i], y[i], z[i], x[i+1], y[i+1], z[i+1]);
+ }
+
+ // Check wall collisions
+ if (x[i] > bounds/2 || x[i] < -bounds/2){
+ xSpeed[i]*=-1;
+ }
+ if (y[i] > bounds/2 || y[i] < -bounds/2){
+ ySpeed[i]*=-1;
+ }
+ if (z[i] > bounds/2 || z[i] < -bounds/2){
+ zSpeed[i]*=-1;
+ }
+ }
+}
+
diff --git a/android/examples/OpenGL/Transform/PushPopCubes/AndroidManifest.xml b/android/examples/OpenGL/Transform/PushPopCubes/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Transform/PushPopCubes/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Transform/PushPopCubes/PushPopCubes.pde b/android/examples/OpenGL/Transform/PushPopCubes/PushPopCubes.pde
new file mode 100644
index 000000000..bb6fdb1f1
--- /dev/null
+++ b/android/examples/OpenGL/Transform/PushPopCubes/PushPopCubes.pde
@@ -0,0 +1,150 @@
+/**
+ * PushPop Cubes
+ * by Ira Greenberg.
+ *
+ * Array of rotating cubes creates
+ * dynamic field patterns. Color
+ * controlled by light sources. Example
+ * of pushMatrix() and popMatrix().
+ */
+
+// Cube class required
+float ang;
+int rows = 21;
+int cols = 21;
+int cubeCount = rows*cols;
+int colSpan, rowSpan;
+float rotspd = 2.0;
+Cube[] cubes = new Cube[cubeCount];
+float[] angs = new float[cubeCount];
+float[] rotvals = new float[cubeCount];
+
+void setup(){
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+
+ colSpan = width/(cols-1);
+ rowSpan = height/(rows-1);
+ noStroke();
+
+ // instantiate cubes
+ for (int i = 0; i < cubeCount; i++){
+ cubes[i] = new Cube(12, 12, 6, 0, 0, 0);
+ /* 3 different rotation options
+ - 1st option: cubes each rotate uniformly
+ - 2nd option: cubes each rotate randomly
+ - 3rd option: cube columns rotate as waves
+ To try the different rotations, leave one
+ of the rotVals[i] lines uncommented below
+ and the other 2 commented out. */
+
+ //rotvals[i] = rotspd;
+ //rotvals[i] = random(-rotspd * 2, rotspd * 2);
+ rotvals[i] = rotspd += .01;
+ }
+}
+
+void draw(){
+ int cubeCounter = 0;
+ background(0);
+ fill(200);
+
+ // Set up some different colored lights
+ pointLight(51, 102, 255, width/3, height/2, 100);
+ pointLight(200, 40, 60, width/1.5, height/2, -150);
+
+ // Raise overall light in scene
+ ambientLight(170, 170, 100);
+
+ // Translate, rotate and draw cubes
+ for (int i = 0; i < cols; i++){
+ for (int j = 0; j < rows; j++){
+ pushMatrix();
+ /* Translate each block.
+ pushmatix and popmatrix add each cube
+ translation to matrix, but restore
+ original, so each cube rotates around its
+ owns center */
+ translate(i * colSpan, j * rowSpan, -20);
+ //rotate each cube around y and x axes
+ rotateY(radians(angs[cubeCounter]));
+ rotateX(radians(angs[cubeCounter]));
+ cubes[cubeCounter].drawCube();
+ popMatrix();
+ cubeCounter++;
+ }
+ }
+ // Angs used in rotate function calls above
+ for (int i = 0; i < cubeCount; i++){
+ angs[i] += rotvals[i];
+ }
+}
+
+// Simple Cube class, based on Quads
+class Cube {
+
+ // Properties
+ int w, h, d;
+ int shiftX, shiftY, shiftZ;
+
+ // Constructor
+ Cube(int w, int h, int d, int shiftX, int shiftY, int shiftZ){
+ this.w = w;
+ this.h = h;
+ this.d = d;
+ this.shiftX = shiftX;
+ this.shiftY = shiftY;
+ this.shiftZ = shiftZ;
+ }
+
+ /* Main cube drawing method, which looks
+ more confusing than it really is. It's
+ just a bunch of rectangles drawn for
+ each cube face */
+ void drawCube(){
+
+ // Front face
+ beginShape(QUADS);
+ normal(1, 0, 0);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
+
+ // Back face
+ normal(-1, 0, 0);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(w + shiftX, h + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
+
+ // Left face
+ normal(0, -1, 0);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
+
+ // Right face
+ normal(0, 1, 0);
+ vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(w + shiftX, h + shiftY, d + shiftZ);
+ vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
+
+ // Top face
+ normal(0, 0, 1);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
+
+ // Bottom face
+ normal(0, 0, -1);
+ vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
+ vertex(w + shiftX, h + shiftY, d + shiftZ);
+ vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
+ endShape();
+ }
+}
diff --git a/android/examples/OpenGL/Transform/Rotate1/AndroidManifest.xml b/android/examples/OpenGL/Transform/Rotate1/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Rotate1/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Transform/Rotate1/Rotate1.pde b/android/examples/OpenGL/Transform/Rotate1/Rotate1.pde
new file mode 100644
index 000000000..a497aa394
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Rotate1/Rotate1.pde
@@ -0,0 +1,39 @@
+/**
+ * Rotate 1.
+ *
+ * Rotating simultaneously in the X and Y axis.
+ * Transformation functions such as rotate() are additive.
+ * Successively calling rotate(1.0) and rotate(2.0)
+ * is equivalent to calling rotate(3.0).
+ */
+
+float a = 0.0;
+float rSize; // rectangle size
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ rSize = width / 6;
+ noStroke();
+ fill(204, 204);
+}
+
+void draw() {
+ background(0);
+
+ a += 0.005;
+ if(a > TWO_PI) {
+ a = 0.0;
+ }
+
+ translate(width/2, height/2);
+
+ rotateX(a);
+ rotateY(a * 2.0);
+ rect(-rSize, -rSize, rSize*2, rSize*2);
+
+ rotateX(a * 1.001);
+ rotateY(a * 2.002);
+ rect(-rSize, -rSize, rSize*2, rSize*2);
+
+}
diff --git a/android/examples/OpenGL/Transform/Rotate2/AndroidManifest.xml b/android/examples/OpenGL/Transform/Rotate2/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Rotate2/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Transform/Rotate2/Rotate2.pde b/android/examples/OpenGL/Transform/Rotate2/Rotate2.pde
new file mode 100644
index 000000000..a055564fa
--- /dev/null
+++ b/android/examples/OpenGL/Transform/Rotate2/Rotate2.pde
@@ -0,0 +1,43 @@
+/**
+ * Rotate 2.
+ *
+ * The push() and pop() functions allow for more control over transformations.
+ * The push function saves the current coordinate system to the stack
+ * and pop() restores the prior coordinate system.
+ */
+
+float a; // Angle of rotation
+float offset = PI/24.0; // Angle offset between boxes
+int num = 12; // Number of boxes
+color[] colors = new color[num]; // Colors of each box
+color safecolor;
+
+boolean pink = true;
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ for(int i=0; i
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Typography/KineticType/KineticType.pde b/android/examples/OpenGL/Typography/KineticType/KineticType.pde
new file mode 100644
index 000000000..714311af0
--- /dev/null
+++ b/android/examples/OpenGL/Typography/KineticType/KineticType.pde
@@ -0,0 +1,65 @@
+/**
+ * Kinetic Type
+ * by Zach Lieberman.
+ *
+ * Using push() and pop() to define the curves of the lines of type.
+ */
+
+Line ln;
+Line lns[];
+
+String words[] = {
+ "sometimes it's like", "the lines of text", "are so happy", "that they want to dance",
+ "or leave the page or jump", "can you blame them?", "living on the page like that",
+ "waiting to be read..."
+};
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+
+ // Array of line objects
+ lns = new Line[8];
+
+ // Load the font from the sketch's data directory
+ textFont(loadFont("Univers-66.vlw"), 1.0);
+
+ // White type
+ fill(255);
+
+ // Creating the line objects
+ for(int i = 0; i < 8; i++) {
+ // For every line in the array, create a Line object to animate
+ // i * 70 is the spacing
+ ln = new Line(words[i], 0, i * 70);
+ lns[i] = ln;
+ }
+}
+
+void draw() {
+ background(0);
+
+ translate(-200, -50, -450);
+ rotateY(0.3);
+
+ // Now animate every line object & draw it...
+ for(int i = 0; i < 8; i++) {
+ float f1 = sin((i + 1.0) * (millis() / 10000.0) * TWO_PI);
+ float f2 = sin((8.0 - i) * (millis() / 10000.0) * TWO_PI);
+ Line line = lns[i];
+ pushMatrix();
+ translate(0.0, line.yPosition, 0.0);
+ for(int j = 0; j < line.myLetters.length; j++) {
+ if(j != 0) {
+ translate(textWidth(line.myLetters[j - 1].myChar) * 75, 0.0, 0.0);
+ }
+ rotateY(f1 * 0.005 * f2);
+ pushMatrix();
+ scale(75.0);
+ text(line.myLetters[j].myChar, 0.0, 0.0);
+ popMatrix();
+ }
+ popMatrix();
+ }
+}
+
diff --git a/android/examples/OpenGL/Typography/KineticType/Letter.pde b/android/examples/OpenGL/Typography/KineticType/Letter.pde
new file mode 100755
index 000000000..d12a9a78d
--- /dev/null
+++ b/android/examples/OpenGL/Typography/KineticType/Letter.pde
@@ -0,0 +1,13 @@
+class Letter
+{
+ char myChar;
+ float x;
+ float y;
+
+ Letter(char c, float f, float f1)
+ {
+ myChar = c;
+ x = f;
+ y = f1;
+ }
+}
diff --git a/android/examples/OpenGL/Typography/KineticType/Line.pde b/android/examples/OpenGL/Typography/KineticType/Line.pde
new file mode 100755
index 000000000..f01b9cdc8
--- /dev/null
+++ b/android/examples/OpenGL/Typography/KineticType/Line.pde
@@ -0,0 +1,28 @@
+class Line
+{
+ String myString;
+ int xPosition;
+ int yPosition;
+ int highlightNum;
+ float speed;
+ float curlInX;
+ Letter myLetters[];
+
+ Line(String s, int i, int j)
+ {
+ myString = s;
+ xPosition = i;
+ yPosition = j;
+ myLetters = new Letter[s.length()];
+ float f1 = 0.0;
+ for(int k = 0; k < s.length(); k++)
+ {
+ char c = s.charAt(k);
+ f1 += textWidth(c);
+ Letter letter = new Letter(c, f1, 0.0);
+ myLetters[k] = letter;
+ }
+
+ curlInX = 0.1;
+ }
+}
diff --git a/android/examples/OpenGL/Typography/KineticType/Word.pde b/android/examples/OpenGL/Typography/KineticType/Word.pde
new file mode 100755
index 000000000..6bc2f2deb
--- /dev/null
+++ b/android/examples/OpenGL/Typography/KineticType/Word.pde
@@ -0,0 +1,10 @@
+class Word
+{
+ String myName;
+ int x;
+
+ Word(String s)
+ {
+ myName = s;
+ }
+}
diff --git a/android/examples/OpenGL/Typography/KineticType/data/Univers-66.vlw b/android/examples/OpenGL/Typography/KineticType/data/Univers-66.vlw
new file mode 100755
index 000000000..d2d08c247
Binary files /dev/null and b/android/examples/OpenGL/Typography/KineticType/data/Univers-66.vlw differ
diff --git a/android/examples/OpenGL/Typography/LetterK/AndroidManifest.xml b/android/examples/OpenGL/Typography/LetterK/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Typography/LetterK/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Typography/LetterK/LetterK.pde b/android/examples/OpenGL/Typography/LetterK/LetterK.pde
new file mode 100644
index 000000000..4bed80077
--- /dev/null
+++ b/android/examples/OpenGL/Typography/LetterK/LetterK.pde
@@ -0,0 +1,126 @@
+/**
+ * Letter K
+ * by Peter Cho.
+ *
+ * Move the mouse across the screen to fold the "K".
+ */
+
+color backgroundColor;
+color foregroundColor;
+color foregroundColor2;
+
+float px, py;
+float pfx, pfy;
+float pv2, pvx, pvy;
+float pa2, pax, pay;
+float pMass, pDrag;
+
+void setup() {
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ noStroke();
+ backgroundColor = color(134, 144, 154);
+ foregroundColor = color(235, 235, 30);
+ foregroundColor2 = color(240, 130, 20);
+ initParticle(0.6, 0.9, width/2, height/2);
+}
+
+void draw() {
+ background(backgroundColor);
+ pushMatrix();
+
+ iterateParticle(0.15*(-px+mouseX), 0.15*(-py+(height-mouseY)));
+
+ translate(width/2, height/2, 0);
+ fill(foregroundColor);
+ drawK();
+
+ pushMatrix();
+ translate(0, 0, 1);
+ translate(0.75 * (px-width/2), -0.75 * (py-height/2), 0);
+ translate(0.75 * (px-width/2), -0.75 * (py-height/2), 0);
+ rotateZ(atan2(-(py-height/2), (px-width/2)) + PI/2);
+ rotateX(PI);
+ rotateZ(-(atan2(-(py-height/2), (px-width/2)) + PI/2));
+
+ fill(foregroundColor2);
+ drawK();
+ popMatrix();
+
+ translate(0.75 * (px-width/2), -0.75 * (py-height/2), 2);
+ rotateZ(atan2(-(py-height/2), (px-width/2)) + PI/2);
+
+ fill(backgroundColor);
+ beginShape(QUADS);
+ vertex(-640, 0);
+ vertex( 640, 0);
+ vertex( 640, -360);
+ vertex(-640, -360);
+ endShape();
+
+ popMatrix();
+
+}
+
+void initParticle(float _mass, float _drag, float ox, float oy) {
+ px = ox;
+ py = oy;
+ pv2 = 0.0;
+ pvx = 0.0;
+ pvy = 0.0;
+ pa2 = 0.0;
+ pax = 0.0;
+ pay = 0.0;
+ pMass = _mass;
+ pDrag = _drag;
+}
+
+void iterateParticle(float fkx, float fky) {
+ // iterate for a single force acting on the particle
+ pfx = fkx;
+ pfy = fky;
+ pa2 = pfx*pfx + pfy*pfy;
+ if (pa2 < 0.0000001) {
+ return;
+ }
+ pax = pfx/pMass;
+ pay = pfy/pMass;
+ pvx += pax;
+ pvy += pay;
+ pv2 = pvx*pvx + pvy*pvy;
+ if (pv2 < 0.0000001) {
+ return;
+ }
+ pvx *= (1.0 - pDrag);
+ pvy *= (1.0 - pDrag);
+ px += pvx;
+ py += pvy;
+}
+
+void drawK() {
+ pushMatrix();
+
+ scale(1.5);
+ translate(-63, 71);
+ beginShape(QUADS);
+ vertex(0, 0, 0);
+ vertex(0, -142.7979, 0);
+ vertex(37.1992, -142.7979, 0);
+ vertex(37.1992, 0, 0);
+
+ vertex(37.1992, -87.9990, 0);
+ vertex(84.1987, -142.7979, 0);
+ vertex(130.3979, -142.7979, 0);
+ vertex(37.1992, -43.999, 0);
+
+ vertex(77.5986-.2, -86.5986-.3, 0);
+ vertex(136.998, 0, 0);
+ vertex(90.7988, 0, 0);
+ vertex(52.3994-.2, -59.999-.3, 0);
+ endShape();
+ //translate(63, -71);
+ popMatrix();
+}
+
+
+
diff --git a/android/examples/OpenGL/Typography/Typing/AndroidManifest.xml b/android/examples/OpenGL/Typography/Typing/AndroidManifest.xml
new file mode 100644
index 000000000..1d22da801
--- /dev/null
+++ b/android/examples/OpenGL/Typography/Typing/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/examples/OpenGL/Typography/Typing/Typing.pde b/android/examples/OpenGL/Typography/Typing/Typing.pde
new file mode 100644
index 000000000..446795abc
--- /dev/null
+++ b/android/examples/OpenGL/Typography/Typing/Typing.pde
@@ -0,0 +1,83 @@
+/**
+ * Typing (Excerpt from the piece Textension)
+ * by Josh Nimoy.
+ *
+ * Click in the window to give it focus.
+ * Type to add letters and press backspace or delete to remove them.
+ */
+
+
+int leftmargin = 10;
+int rightmargin = 20;
+String buff = "";
+boolean didntTypeYet = true;
+
+void setup()
+{
+ size(640, 360, P3D);
+ orientation(LANDSCAPE);
+ textFont(loadFont("Univers45.vlw"), 25);
+}
+
+void draw()
+{
+ background(176);
+
+ if((millis() % 500) < 250){ // Only fill cursor half the time
+ noFill();
+ }
+ else {
+ fill(255);
+ stroke(0);
+ }
+ float rPos;
+ // Store the cursor rectangle's position
+ rPos = textWidth(buff) + leftmargin;
+ rect(rPos+1, 19, 10, 21);
+
+ // Some instructions at first
+ if(didntTypeYet) {
+ fill(0);
+ //text("Use the keyboard.", 22, 40);
+ }
+
+ fill(0);
+ pushMatrix();
+ translate(rPos,10+25);
+ char k;
+ for(int i = 0;i < buff.length(); i++) {
+ k = buff.charAt(i);
+ translate(-textWidth(k),0);
+ rotateY(-textWidth(k)/70.0);
+ rotateX(textWidth(k)/70.0);
+ scale(1.1);
+ text(k,0,0);
+ }
+ popMatrix();
+}
+
+void keyPressed()
+{
+ char k;
+ k = (char)key;
+ switch(k){
+ case 8:
+ if(buff.length()>0){
+ buff = buff.substring(1);
+ }
+ break;
+ case 13: // Avoid special keys
+ case 10:
+ case 65535:
+ case 127:
+ case 27:
+ break;
+ default:
+ if(textWidth(buff+k)+leftmargin < width-rightmargin){
+ didntTypeYet = false;
+ buff=k+buff;
+ }
+ break;
+ }
+}
+
diff --git a/android/examples/OpenGL/Typography/Typing/data/Univers45.vlw b/android/examples/OpenGL/Typography/Typing/data/Univers45.vlw
new file mode 100755
index 000000000..040e02170
Binary files /dev/null and b/android/examples/OpenGL/Typography/Typing/data/Univers45.vlw differ