Shape drawing methods updated to incorporate 3D

This commit is contained in:
codeanticode
2010-04-08 07:18:36 +00:00
parent 602c7b373e
commit f6706b067b
8 changed files with 158 additions and 491 deletions
@@ -23,53 +23,6 @@
package processing.core;
public interface GLConstants {
/**
* This constant identifies the texture target GL_TEXTURE_2D,
* that is, textures with normalized coordinates.
*/
public static final int NORMAL_TEXTURE = 0;
/**
* This constant identifies the nearest texture filter .
*/
public static final int NEAREST = 0;
/**
* This constant identifies the linear texture filter .
*/
public static final int LINEAR = 1;
/**
* This constant identifies the nearest/nearest function to build mipmaps .
*/
public static final int NEAREST_MIPMAP_NEAREST = 2;
/**
* This constant identifies the linear/nearest function to build mipmaps .
*/
public static final int LINEAR_MIPMAP_NEAREST = 3;
/**
* This constant identifies the nearest/linear function to build mipmaps .
*/
public static final int NEAREST_MIPMAP_LINEAR = 4;
/**
* This constant identifies the linear/linear function to build mipmaps .
*/
public static final int LINEAR_MIPMAP_LINEAR = 5;
/**
* Static usage mode for GLModels (vertices won't be updated after creation).
*/
public static final int STATIC = 0;
/**
* Dynamic usage mode for GLModels (vertices will be updated after creation).
*/
public static final int DYNAMIC = 1;
/**
* Used in GLModels..
*/
public static final int VERTICES = 0;
public static final int NORMALS = 1;
public static final int COLORS = 2;
public static final int TEXTURES = 3;
public static final int GROUPS = 4;
}
@@ -1,356 +0,0 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
Copyright (c) 2010 Ben Fry and Casey Reas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
//package processing.core;
//
//import java.io.*;
//import java.util.Arrays;
//import android.graphics.Bitmap;
//import android.graphics.Canvas;
//import android.graphics.Color;
//import android.graphics.Paint;
//import android.graphics.Typeface;
//import android.graphics.Bitmap.Config;
//
//
///**
// * Font class using GLTextures to store the individual glyphs.
// * By Andres Colubri
// *
// */
//public class GLFont extends PFont {
// public GLFont(PApplet parent, InputStream input) throws IOException {
// DataInputStream is = new DataInputStream(input);
//
// // number of character images stored in this font
// charCount = is.readInt();
//
// // bit count is ignored since this is always 8
// //int numBits = is.readInt();
// // used to be the bitCount, but now used for version number.
// // version 8 is any font before 69, so 9 is anything from 83+
// // 9 was buggy so gonna increment to 10.
// int version = is.readInt();
//
// // this was formerly ignored, now it's the actual font size
// //mbox = is.readInt();
// size = is.readInt();
// // this was formerly mboxY, the one that was used
// // this will make new fonts downward compatible
// //mbox2 = is.readInt();
// mbox2 = is.readInt();
//
// fwidth = size; //mbox;
// fheight = size; //mbox;
//
// // size for image ("texture") is next power of 2
// // over the font size. for most vlw fonts, the size is 48
// // so the next power of 2 is 64.
// // double-check to make sure that mbox2 is a power of 2
// // there was a bug in the old font generator that broke this
// //mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2)));
// mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2)));
// // size for the texture is stored in the font
// twidth = theight = mbox2; //mbox2;
//
// ascent = is.readInt(); // formerly baseHt (zero/ignored)
// descent = is.readInt(); // formerly ignored struct padding
//
// // allocate enough space for the character info
// value = new int[charCount];
// height = new int[charCount];
// width = new int[charCount];
// setWidth = new int[charCount];
// topExtent = new int[charCount];
// leftExtent = new int[charCount];
//
// ascii = new int[128];
// for (int i = 0; i < 128; i++) ascii[i] = -1;
//
// // read the information about the individual characters
// for (int i = 0; i < charCount; i++) {
// value[i] = is.readInt();
// height[i] = is.readInt();
// width[i] = is.readInt();
// setWidth[i] = is.readInt();
// topExtent[i] = is.readInt();
// leftExtent[i] = is.readInt();
//
// // pointer in the c version, ignored
// is.readInt();
//
// // cache locations of the ascii charset
// if (value[i] < 128) ascii[value[i]] = i;
//
// // the values for getAscent() and getDescent() from FontMetrics
// // seem to be way too large.. perhaps they're the max?
// // as such, use a more traditional marker for ascent/descent
// if (value[i] == 'd') {
// if (ascent == 0) ascent = topExtent[i];
// }
// if (value[i] == 'p') {
// if (descent == 0) descent = -topExtent[i] + height[i];
// }
// }
//
// // not a roman font, so throw an error and ask to re-build.
// // that way can avoid a bunch of error checking hacks in here.
// if ((ascent == 0) && (descent == 0)) {
// throw new RuntimeException("Please use \"Create Font\" to " +
// "re-create this font.");
// }
//
// images = new GLTexture[charCount];
// GLTexture tex;
// GLTexture.Parameters params = GLTexture.newParameters(ARGB);
// for (int i = 0; i < charCount; i++) {
// tex = new GLTexture(parent, twidth, theight, params);
// tex.loadPixels();
// int bitmapSize = height[i] * width[i];
//
// byte temp[] = new byte[bitmapSize];
// is.readFully(temp);
//
// // convert the bitmap to an alpha channel
// int w = width[i];
// int h = height[i];
// for (int y = 0; y < h; y++) {
// for (int x = 0; x < w; x++) {
// int valu = temp[y*w + x] & 0xff;
// tex.pixels[y * twidth + x] = valu << 24 | 255 << 16 | 255 << 8 | 255;
// //(valu << 24) | 0xFFFFFF; // windows
// //0xFFFFFF00 | valu; // macosx
//
// //System.out.print((images[i].pixels[y*64+x] > 128) ? "*" : ".");
// }
// //System.out.println();
// }
// tex.update(); // Copies pixels array to texture in video memory
// images[i] = tex;
// //System.out.println();
// }
//
// if (version >= 10) { // includes the font name at the end of the file
// name = is.readUTF();
// psname = is.readUTF();
// }
// if (version == 11) {
// smooth = is.readBoolean();
// }
// }
//
// /**
// * Create a new image-based font on the fly.
// *
// * @param font the font object to create from
// * @param charset array of all unicode chars that should be included
// * @param smooth true to enable smoothing/anti-aliasing
// */
// public GLFont(PApplet parent, Typeface font, int size, boolean smooth, char charset[]) {
// // save this so that we can use the native version
// this.typeface = font;
// this.smooth = smooth;
//
//// name = font.getName();
//// psname = font.getPSName();
//
// // fix regression from sorting (bug #564)
// if (charset != null) {
// // charset needs to be sorted to make index lookup run more quickly
// // http://dev.processing.org/bugs/show_bug.cgi?id=494
// Arrays.sort(charset);
// }
//
// // the count gets reset later based on how many of
// // the chars are actually found inside the font.
// this.charCount = (charset == null) ? 65536 : charset.length;
// this.size = size;
//
// fwidth = fheight = size;
//
// PImage bitmaps[] = new PImage[charCount];
//
// // allocate enough space for the character info
// value = new int[charCount];
// height = new int[charCount];
// width = new int[charCount];
// setWidth = new int[charCount];
// topExtent = new int[charCount];
// leftExtent = new int[charCount];
//
// ascii = new int[128];
// for (int i = 0; i < 128; i++) ascii[i] = -1;
//
// int mbox3 = size * 3;
//
//// BufferedImage playground =
//// new BufferedImage(mbox3, mbox3, BufferedImage.TYPE_INT_RGB);
// Bitmap playground = Bitmap.createBitmap(mbox3, mbox3, Config.ARGB_8888);
//// Graphics2D g = (Graphics2D) playground.getGraphics();
// Canvas canvas = new Canvas(playground);
//// g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
//// smooth ?
//// RenderingHints.VALUE_ANTIALIAS_ON :
//// RenderingHints.VALUE_ANTIALIAS_OFF);
// Paint paint = new Paint();
// paint.setAntiAlias(smooth);
//
//// g.setFont(font);
//// FontMetrics metrics = g.getFontMetrics();
// paint.setTypeface(font);
// paint.setTextSize(size);
//
// int samples[] = new int[mbox3 * mbox3];
//
// int maxWidthHeight = 0;
// int index = 0;
// for (int i = 0; i < charCount; i++) {
// char c = (charset == null) ? (char)i : charset[i];
//
//// if (!font.canDisplay(c)) { // skip chars not in the font
//// continue;
//// }
//
//// g.setColor(Color.white);
//// g.fillRect(0, 0, mbox3, mbox3);
// canvas.drawColor(Color.WHITE);
//// g.setColor(Color.black);
// paint.setColor(Color.BLACK);
//// g.drawString(String.valueOf(c), size, size * 2);
// canvas.drawText(String.valueOf(c), size, size * 2, paint);
//
// // grabs copy of the current data.. so no updates (do each time)
//// Raster raster = playground.getData();
//// raster.getSamples(0, 0, mbox3, mbox3, 0, samples);
// playground.getPixels(samples, 0, mbox3, 0, 0, mbox3, mbox3);
//
// int minX = 1000, maxX = 0;
// int minY = 1000, maxY = 0;
// boolean pixelFound = false;
//
// for (int y = 0; y < mbox3; y++) {
// for (int x = 0; x < mbox3; x++) {
// //int sample = raster.getSample(x, y, 0); // maybe?
// int sample = samples[y * mbox3 + x] & 0xff;
// // or int samples[] = raster.getPixel(x, y, null);
//
// //if (sample == 0) { // or just not white? hmm
// if (sample != 255) {
// if (x < minX) minX = x;
// if (y < minY) minY = y;
// if (x > maxX) maxX = x;
// if (y > maxY) maxY = y;
// pixelFound = true;
// }
// }
// }
//
// if (!pixelFound) {
// minX = minY = 0;
// maxX = maxY = 0;
// // this will create a 1 pixel white (clear) character..
// // maybe better to set one to -1 so nothing is added?
// }
//
// value[index] = c;
// height[index] = (maxY - minY) + 1;
// width[index] = (maxX - minX) + 1;
//// setWidth[index] = metrics.charWidth(c);
// setWidth[index] = (int) paint.measureText(String.valueOf(c));
// //System.out.println((char)c + " " + setWidth[index]);
//
// // cache locations of the ascii charset
// //if (value[i] < 128) ascii[value[i]] = i;
// if (c < 128) ascii[c] = index;
//
// // offset from vertical location of baseline
// // of where the char was drawn (size*2)
// topExtent[index] = size*2 - minY;
//
// // offset from left of where coord was drawn
// leftExtent[index] = minX - size;
//
// if (c == 'd') {
// ascent = topExtent[index];
// }
// if (c == 'p') {
// descent = -topExtent[index] + height[index];
// }
//
// if (width[index] > maxWidthHeight) maxWidthHeight = width[index];
// if (height[index] > maxWidthHeight) maxWidthHeight = height[index];
//
// bitmaps[index] = new PImage(width[index], height[index], ARGB);
//
// for (int y = minY; y <= maxY; y++) {
// for (int x = minX; x <= maxX; x++) {
// int val = 255 - (samples[y * mbox3 + x] & 0xff);
// int pindex = (y - minY) * width[index] + (x - minX);
// bitmaps[index].pixels[pindex] = val << 24 | 255 << 16 | 255 << 8 | 255;
// }
// }
// index++;
// }
// charCount = index;
//
// // foreign font, so just make ascent the max topExtent
// if ((ascent == 0) && (descent == 0)) {
// for (int i = 0; i < charCount; i++) {
// char cc = (char) value[i];
// if (Character.isWhitespace(cc) ||
// (cc == '\u00A0') || (cc == '\u2007') || (cc == '\u202F')) {
// continue;
// }
// if (topExtent[i] > ascent) {
// ascent = topExtent[i];
// }
// int d = -topExtent[i] + height[i];
// if (d > descent) {
// descent = d;
// }
// }
// }
// // size for image/texture is next power of 2 over largest char
// mbox2 = (int)
// Math.pow(2, Math.ceil(Math.log(maxWidthHeight) / Math.log(2)));
// twidth = theight = mbox2;
//
// // shove the smaller PImage data into textures of next-power-of-2 size,
// // so that this font can be used immediately by p5.
// images = new GLTexture[charCount];
// GLTexture tex;
// GLTexture.Parameters params = GLTexture.newParameters(ARGB);
// for (int i = 0; i < charCount; i++) {
// tex = new GLTexture(parent, mbox2, mbox2, params);
// tex.loadPixels();
// for (int y = 0; y < height[i]; y++) {
// System.arraycopy(bitmaps[i].pixels, y*width[i],
// tex.pixels, y*mbox2,
// width[i]);
// }
// tex.update(); // Copies pixels array to texture in video memory
// images[i] = tex;
// bitmaps[i] = null;
// }
// }
//
//}
+5 -10
View File
@@ -36,7 +36,7 @@ import java.lang.reflect.Method;
* By Andres Colubri
*
*/
public class GLModel extends PShape implements GLConstants, PConstants {
public class GLModel extends PShape implements PConstants {
protected PApplet parent;
protected GL11 gl;
protected PGraphicsAndroid3D a3d;
@@ -75,7 +75,6 @@ public class GLModel extends PShape implements GLConstants, PConstants {
protected int recreateResourceIdx;
public float depth;
protected float xmin, xmax;
protected float ymin, ymax;
protected float zmin, zmax;
@@ -1323,17 +1322,13 @@ public class GLModel extends PShape implements GLConstants, PConstants {
///////////////////////////////////////////////////////////
// Methods inherited from PShape.
public float getDepth() {
return depth;
public boolean is3D() {
return true;
}
public boolean isVisible() {
return visible;
}
///////////////////////////////////////////////////////////
// Drawing methods
+15 -66
View File
@@ -3021,14 +3021,14 @@ public class PApplet extends Activity implements PConstants, Runnable {
}
public PShape createShape(int nvert, int kind) {
return this.createShape(nvert, kind, GLConstants.STATIC);
public GLModel createShape(int nvert, int kind) {
return this.createShape(nvert, kind, STATIC);
}
public PShape createShape(int nvert, int kind, int mode) {
public GLModel createShape(int nvert, int kind, int mode) {
if (g instanceof PGraphicsAndroid3D) {
GLModel.Parameters params = GLModel.newParameters(kind, GLConstants.STATIC);
GLModel.Parameters params = GLModel.newParameters(kind, STATIC);
GLModel model = new GLModel(this, nvert, params);
return model;
} else {
@@ -3037,7 +3037,7 @@ public class PApplet extends Activity implements PConstants, Runnable {
}
public PShape createShape(PShape shape) {
public GLModel createShape(PShape shape) {
if (g instanceof PGraphicsAndroid3D) {
PGraphicsAndroid3D a3d = (PGraphicsAndroid3D)g;
a3d.beginShapeRecorderImpl();
@@ -3107,67 +3107,6 @@ public class PApplet extends Activity implements PConstants, Runnable {
}
return new PFont(baseFont, round(size), smooth, charset);
}
//////////////////////////////////////////////////////////////
// GL-methods
// public GLFont loadGLFont(String filename) {
// try {
// InputStream input = createInput(filename);
// return new GLFont(this, input);
//
// } catch (Exception e) {
// die("Could not load font " + filename + ". " +
// "Make sure that the font has been copied " +
// "to the data folder of your sketch.", e);
// }
// return null;
// }
//
//
// public GLFont createGLFont(String name, float size) {
// return createGLFont(name, size, true, GLFont.DEFAULT_CHARSET);
// }
//
//
// public GLFont createGLFont(String name, float size, boolean smooth) {
// return createGLFont(name, size, smooth, GLFont.DEFAULT_CHARSET);
// }
//
//
// public GLFont createGLFont(String name, float size,
// boolean smooth, char charset[]) {
// String lowerName = name.toLowerCase();
// Typeface baseFont = null;
//
// if (lowerName.endsWith(".otf") || lowerName.endsWith(".ttf")) {
// AssetManager assets = getBaseContext().getAssets();
// baseFont = Typeface.createFromAsset(assets, "data/" + name);
//
// } else {
// baseFont = PFont.findTypeface(name);
// }
// return new GLFont(this, baseFont, round(size), smooth, charset);
// }
// public GLTexture loadGLTexture(String filename) {
// return new GLTexture(this, filename);
// }
public GLModel loadGLModel(String filename) {
return new GLModel(this, filename);
}
public void model(GLModel model, float x, float y, float z) {
g.model(model, x, y, z);
}
//////////////////////////////////////////////////////////////
@@ -6759,11 +6698,21 @@ public class PApplet extends Activity implements PConstants, Runnable {
}
public void shape(PShape shape, float x, float y, float z) {
g.shape(shape, x, y, z);
}
public void shape(PShape shape, float x, float y, float c, float d) {
g.shape(shape, x, y, c, d);
}
public void shape(PShape shape, float x, float y, float z, float c, float d, float e) {
g.shape(shape, x, y, z, c, d, e);
}
public void textAlign(int align) {
g.textAlign(align);
}
@@ -369,6 +369,42 @@ public interface PConstants {
// text alignment modes
// are inherited from LEFT, CENTER, RIGHT
// PTexture
/** This constant identifies the texture target GL_TEXTURE_2D, that is, textures with normalized coordinates */
public static final int NORMAL_TEXTURE = 0;
/** This constant identifies the nearest texture filter */
public static final int NEAREST = 0;
/** This constant identifies the linear texture filter */
public static final int LINEAR = 1;
/** This constant identifies the nearest/nearest function to build mipmaps */
public static final int NEAREST_MIPMAP_NEAREST = 2;
/** This constant identifies the linear/nearest function to build mipmaps */
public static final int LINEAR_MIPMAP_NEAREST = 3;
/** This constant identifies the nearest/linear function to build mipmaps */
public static final int NEAREST_MIPMAP_LINEAR = 4;
/** This constant identifies the linear/linear function to build mipmaps */
public static final int LINEAR_MIPMAP_LINEAR = 5;
// PShape3D
/** Static usage mode for PShape3D (vertices won't be updated after creation). */
public static final int STATIC = 0;
/** Dynamic usage mode for PShape3D (vertices will be updated after creation). */
public static final int DYNAMIC = 1;
/**
* Elements handled by PShape3D (vertices, normals, color, texture coordinates and groups).
*/
public static final int VERTICES = 0;
public static final int NORMALS = 1;
public static final int COLORS = 2;
public static final int TEXTURES = 3;
public static final int GROUPS = 4;
// stroke modes
@@ -2335,7 +2335,12 @@ public class PGraphics extends PImage implements PConstants {
popMatrix();
}
}
public void shape(PShape shape, float x, float y, float z) {
showMissingWarning("shape");
}
public void shape(PShape shape, float x, float y, float c, float d) {
if (shape.isVisible()) { // don't do expensive matrix ops if invisible
@@ -2364,7 +2369,11 @@ public class PGraphics extends PImage implements PConstants {
}
}
public void shape(PShape shape, float x, float y, float z, float c, float d, float e) {
showMissingWarning("shape");
}
//////////////////////////////////////////////////////////////
@@ -5045,13 +5054,10 @@ public class PGraphics extends PImage implements PConstants {
/**
* Return true if this renderer supports 2D drawing. Defaults to true.
* Return true if this renderer supports 2D drawing. Defaults to false.
*/
public boolean is3D() {
return false;
}
public void model(GLModel model, float x, float y, float z) {
showMethodWarning("model");
}
}
@@ -413,7 +413,7 @@ public class PGraphicsAndroid3D extends PGraphics {
// The screen texture must have NEAREST filtering, otherwise it degrades after consecutive
// renderings.
screenTex = parent.createImage(width, height, ARGB, GLConstants.NEAREST);
screenTex = parent.createImage(width, height, ARGB, NEAREST);
screenTex.getTexture().set(pix);
}
@@ -973,19 +973,19 @@ public class PGraphicsAndroid3D extends PGraphics {
if (0 < recordedVertices.size()) {
GLModel model = new GLModel(parent, recordedVertices.size());
model.beginUpdate(GLConstants.VERTICES);
model.beginUpdate(VERTICES);
model.setVertex(recordedVertices);
model.endUpdate();
model.beginUpdate(GLConstants.COLORS);
model.beginUpdate(COLORS);
model.setColor(recordedColors);
model.endUpdate();
model.beginUpdate(GLConstants.NORMALS);
model.beginUpdate(NORMALS);
model.setNormal(recordedNormals);
model.endUpdate();
model.beginUpdate(GLConstants.TEXTURES);
model.beginUpdate(TEXTURES);
model.setTexCoord(recordedTexCoords);
model.endUpdate();
@@ -996,6 +996,57 @@ public class PGraphicsAndroid3D extends PGraphics {
}
//////////////////////////////////////////////////////////////
// PSHAPE RENDERING IN 3D
public void shape(PShape shape, float x, float y, float z) {
if (shape.isVisible()) { // don't do expensive matrix ops if invisible
pushMatrix();
if (shapeMode == CENTER) {
translate(x - shape.getWidth()/2, y - shape.getHeight()/2, z - shape.getDepth()/2);
} else if ((shapeMode == CORNER) || (shapeMode == CORNERS)) {
translate(x, y, z);
}
shape.draw(this);
popMatrix();
}
}
public void shape(PShape shape, float x, float y, float z, float c, float d, float e) {
if (shape.isVisible()) { // don't do expensive matrix ops if invisible
pushMatrix();
if (shapeMode == CENTER) {
// x, y and z are center, c, d and e refer to a diameter
translate(x - c/2f, y - d/2f, z - e/2f);
scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth());
} else if (shapeMode == CORNER) {
translate(x, y, z);
scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth());
} else if (shapeMode == CORNERS) {
// c, d, e are x2/y2/z2, make them into width/height/depth
c -= x;
d -= y;
e -= z;
// then same as above
translate(x, y, z);
scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth());
}
shape.draw(this);
popMatrix();
}
}
//////////////////////////////////////////////////////////////
// BEZIER CURVE VERTICES
@@ -4700,4 +4751,19 @@ class BufferUtil {
buffer.rewind();
return buffer;
}
/**
* Return true if this renderer supports 2D drawing. Defaults to true.
*/
public boolean is2D() {
return true;
}
/**
* Return true if this renderer supports 2D drawing. Defaults to false.
*/
public boolean is3D() {
return true;
}
}
@@ -82,6 +82,7 @@ public class PShape implements PConstants {
//protected float height;
public float width;
public float height;
public float depth;
// set to false if the object is hidden in the layers palette
protected boolean visible = true;
@@ -244,6 +245,23 @@ public class PShape implements PConstants {
}
/**
* Get the depth of the shape area (not necessarily the shape boundary). Only makes sense for 3D PShape subclasses,
* such as PShape3D.
*/
public float getDepth() {
//checkBounds();
return depth;
}
/**
* Return true if this shape is 3D. Defaults to false.
*/
public boolean is3D() {
return false;
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .