Merged-in the changes in the core needed for the new opengl renderer

This commit is contained in:
codeanticode
2011-02-01 07:51:22 +00:00
parent b26f75d270
commit 21d134a233
10 changed files with 1110 additions and 127 deletions
+380 -29
View File
@@ -162,7 +162,6 @@ import processing.xml.XMLElement;
* do by hand w/ some Java code.</P>
* @usage Web &amp; Application
*/
@SuppressWarnings("serial")
public class PApplet extends Applet
implements PConstants, Runnable,
MouseListener, MouseMotionListener, KeyListener, FocusListener
@@ -1380,6 +1379,14 @@ public class PApplet extends Applet
}
/**
* Creates a new PImage (the datatype for storing images). This provides a fresh buffer of pixels to play with. Set the size of the buffer with the <b>width</b> and <b>height</b> parameters. The <b>format</b> parameter defines how the pixels are stored. See the PImage reference for more information.
*/
public PImage createImage(int wide, int high, int format) {
return createImage(wide, high, format, null);
}
/**
* Creates a new PImage (the datatype for storing images). This provides a fresh buffer of pixels to play with. Set the size of the buffer with the <b>width</b> and <b>height</b> parameters. The <b>format</b> parameter defines how the pixels are stored. See the PImage reference for more information.
* <br><br>Be sure to include all three parameters, specifying only the width and height (but no format) will produce a strange error.
@@ -1397,8 +1404,11 @@ public class PApplet extends Applet
* @see processing.core.PImage
* @see processing.core.PGraphics
*/
public PImage createImage(int wide, int high, int format) {
public PImage createImage(int wide, int high, int format, PParameters params) {
PImage image = new PImage(wide, high, format);
if (params != null) {
image.setParams(g, params);
}
image.parent = this; // make save() work
return image;
}
@@ -3618,14 +3628,28 @@ public class PApplet extends Applet
* java.awt.Image to the PImage constructor that takes an AWT image.
*/
public PImage loadImage(String filename) {
return loadImage(filename, null);
return loadImage(filename, null, null);
}
/**
* Load an image from the data folder or a local directory...
*/
public PImage loadImage(String filename, String extension) {
return loadImage(filename, extension, null);
}
public PImage loadImage(String filename, PParameters params) {
return loadImage(filename, null, params);
}
/**
* Loads an image into a variable of type <b>PImage</b>. Four types of images ( <b>.gif</b>, <b>.jpg</b>, <b>.tga</b>, <b>.png</b>) images may be loaded. To load correctly, images must be located in the data directory of the current sketch. In most cases, load all images in <b>setup()</b> to preload them at the start of the program. Loading images inside <b>draw()</b> will reduce the speed of a program.
* <br><br>The <b>filename</b> parameter can also be a URL to a file found online. For security reasons, a Processing sketch found online can only download files from the same server from which it came. Getting around this restriction requires a <a href="http://processing.org/hacks/doku.php?id=hacks:signapplet">signed applet</a>.
* <br><br>The <b>extension</b> parameter is used to determine the image type in cases where the image filename does not end with a proper extension. Specify the extension as the second parameter to <b>loadImage()</b>, as shown in the third example on this page.
* <br><br>The <b>params</b> parameter is used to set an parameter object for the image, as might be used by specific renderers such as OPENGL2. Specify the extension as the third parameter to <b>loadImage()</b>, as shown in the fourth example on this page.
* <br><br>If an image is not loaded successfully, the <b>null</b> value is returned and an error message will be printed to the console. The error message does not halt the program, however the null value may cause a NullPointerException if your code does not check whether the value returned from <b>loadImage()</b> is null.<br><br>Depending on the type of error, a <b>PImage</b> object may still be returned, but the width and height of the image will be set to -1. This happens if bad image data is returned or cannot be decoded properly. Sometimes this happens with image URLs that produce a 403 error or that redirect to a password prompt, because <b>loadImage()</b> will attempt to interpret the HTML as image data.
*
* =advanced
@@ -3645,7 +3669,7 @@ public class PApplet extends Applet
* @see processing.core.PApplet#imageMode(int)
* @see processing.core.PApplet#background(float, float, float)
*/
public PImage loadImage(String filename, String extension) {
public PImage loadImage(String filename, String extension, PParameters params) {
if (extension == null) {
String lower = filename.toLowerCase();
int dot = filename.lastIndexOf('.');
@@ -3667,7 +3691,11 @@ public class PApplet extends Applet
if (extension.equals("tga")) {
try {
return loadImageTGA(filename);
PImage image = loadImageTGA(filename);
if (params != null) {
image.setParams(g, params);
}
return image;
} catch (IOException e) {
e.printStackTrace();
return null;
@@ -3676,7 +3704,11 @@ public class PApplet extends Applet
if (extension.equals("tif") || extension.equals("tiff")) {
byte bytes[] = loadBytes(filename);
return (bytes == null) ? null : PImage.loadTIFF(bytes);
PImage image = (bytes == null) ? null : PImage.loadTIFF(bytes);
if (params != null) {
image.setParams(g, params);
}
return image;
}
// For jpeg, gif, and png, load them using createImage(),
@@ -3700,6 +3732,10 @@ public class PApplet extends Applet
if (extension.equals("gif") || extension.equals("png")) {
image.checkAlpha();
}
if (params != null) {
image.setParams(g, params);
}
return image;
}
}
@@ -3714,7 +3750,12 @@ public class PApplet extends Applet
if (loadImageFormats != null) {
for (int i = 0; i < loadImageFormats.length; i++) {
if (extension.equals(loadImageFormats[i])) {
return loadImageIO(filename);
PImage image;
image = loadImageIO(filename);
if (params != null) {
image.setParams(g, params);
}
return image;
}
}
}
@@ -3725,10 +3766,15 @@ public class PApplet extends Applet
}
public PImage requestImage(String filename) {
return requestImage(filename, null);
return requestImage(filename, null, null);
}
public PImage requestImage(String filename, String extension) {
return requestImage(filename, extension, null);
}
/**
* This function load images on a separate thread so that your sketch does not freeze while images load during <b>setup()</b>. While the image is loading, its width and height will be 0. If an error occurs while loading the image, its width and height will be set to -1. You'll know when the image has loaded properly because its width and height will be greater than 0. Asynchronous image loading (particularly when downloading from a server) can dramatically improve performance.<br><br>
* The <b>extension</b> parameter is used to determine the image type in cases where the image filename does not end with a proper extension. Specify the extension as the second parameter to <b>requestImage()</b>.
@@ -3740,8 +3786,8 @@ public class PApplet extends Applet
* @see processing.core.PApplet#loadImage(String, String)
* @see processing.core.PImage
*/
public PImage requestImage(String filename, String extension) {
PImage vessel = createImage(0, 0, ARGB);
public PImage requestImage(String filename, String extension, PParameters params) {
PImage vessel = createImage(0, 0, ARGB, params);
AsyncImageLoader ail =
new AsyncImageLoader(filename, extension, vessel);
ail.start();
@@ -3765,7 +3811,7 @@ public class PApplet extends Applet
String filename;
String extension;
PImage vessel;
public AsyncImageLoader(String filename, String extension, PImage vessel) {
this.filename = filename;
this.extension = extension;
@@ -4055,7 +4101,14 @@ public class PApplet extends Applet
// SHAPE I/O
protected String[] loadShapeFormats;
public PShape loadShape(String filename) {
return loadShape(filename, null);
}
/**
* Loads vector shapes into a variable of type <b>PShape</b>. Currently, only SVG files may be loaded.
* To load correctly, the file must be located in the data directory of the current sketch.
@@ -4073,11 +4126,27 @@ public class PApplet extends Applet
* @see PApplet#shape(PShape)
* @see PApplet#shapeMode(int)
*/
public PShape loadShape(String filename) {
if (filename.toLowerCase().endsWith(".svg")) {
public PShape loadShape(String filename, PParameters params) {
String extension;
String lower = filename.toLowerCase();
int dot = filename.lastIndexOf('.');
if (dot == -1) {
extension = "unknown"; // no extension found
}
extension = lower.substring(dot + 1);
// check for, and strip any parameters on the url, i.e.
// filename.jpg?blah=blah&something=that
int question = extension.indexOf('?');
if (question != -1) {
extension = extension.substring(0, question);
}
if (extension.equals("svg")) {
return new PShapeSVG(this, filename);
} else if (filename.toLowerCase().endsWith(".svgz")) {
} else if (extension.equals("svgz")) {
try {
InputStream input = new GZIPInputStream(createInput(filename));
XMLElement xml = new XMLElement(createReader(input));
@@ -4085,12 +4154,33 @@ public class PApplet extends Applet
} catch (IOException e) {
e.printStackTrace();
}
} else {
// Loading the formats supported by the renderer.
loadShapeFormats = g.getSupportedShapeFormats();
if (loadShapeFormats != null) {
for (int i = 0; i < loadShapeFormats.length; i++) {
if (extension.equals(loadShapeFormats[i])) {
return g.loadShape(filename, params);
}
}
}
}
return null;
}
/**
* Creates an empty shape, with the specified size and parameters.
*/
public PShape createShape(int size, PParameters params) {
return g.createShape(size, params);
}
//////////////////////////////////////////////////////////////
// FONT I/O
@@ -7534,6 +7624,9 @@ public class PApplet extends Applet
recorder.dispose();
recorder = null;
}
if (g.isRecording()) {
g.endRecord();
}
}
@@ -7576,8 +7669,16 @@ public class PApplet extends Applet
}
/**
* Starts shape recording and returns the PShape object that will
* contain the geometry.
*/
public PShape beginRecord() {
return g.beginRecord();
}
//////////////////////////////////////////////////////////////
/**
* Loads the pixel data for the display window into the <b>pixels[]</b> array. This function must always be called before reading from or writing to <b>pixels[]</b>.
@@ -7656,6 +7757,11 @@ public class PApplet extends Applet
}
public boolean hintEnabled(int which) {
return g.hintEnabled(which);
}
/**
* Start a new shape of type POLYGON
*/
@@ -7703,6 +7809,15 @@ public class PApplet extends Applet
}
/**
* Sets the automatic normal calculation mode.
*/
public void autoNormal(boolean auto) {
if (recorder != null) recorder.autoNormal(auto);
g.autoNormal(auto);
}
/**
* Sets the current normal vector. Only applies with 3D rendering
* and inside a beginShape/endShape block.
@@ -7746,6 +7861,17 @@ public class PApplet extends Applet
}
/**
* Removes texture image for current shape.
* Needs to be called between @see beginShape and @see endShape
*
*/
public void noTexture() {
if (recorder != null) recorder.noTexture();
g.noTexture();
}
public void vertex(float x, float y) {
if (recorder != null) recorder.vertex(x, y);
g.vertex(x, y);
@@ -8733,6 +8859,18 @@ public class PApplet extends Applet
}
public void beginText() {
if (recorder != null) recorder.beginText();
g.beginText();
}
public void endText() {
if (recorder != null) recorder.endText();
g.endText();
}
public float textWidth(char c) {
return g.textWidth(c);
}
@@ -9136,6 +9274,18 @@ public class PApplet extends Applet
}
public void beginProjection() {
if (recorder != null) recorder.beginProjection();
g.beginProjection();
}
public void endProjection() {
if (recorder != null) recorder.endProjection();
g.endProjection();
}
public void beginCamera() {
if (recorder != null) recorder.beginCamera();
g.beginCamera();
@@ -10002,6 +10152,53 @@ public class PApplet extends Applet
}
/**
* Display a warning that the specified method is only available with 3D.
* @param method The method name (no parentheses)
*/
static public void showDepthWarning(String method) {
PGraphics.showDepthWarning(method);
}
/**
* Display a warning that the specified method that takes x, y, z parameters
* can only be used with x and y parameters in this renderer.
* @param method The method name (no parentheses)
*/
static public void showDepthWarningXYZ(String method) {
PGraphics.showDepthWarningXYZ(method);
}
/**
* Display a warning that the specified method is simply unavailable.
*/
static public void showMethodWarning(String method) {
PGraphics.showMethodWarning(method);
}
/**
* Error that a particular variation of a method is unavailable (even though
* other variations are). For instance, if vertex(x, y, u, v) is not
* available, but vertex(x, y) is just fine.
*/
static public void showVariationWarning(String str) {
PGraphics.showVariationWarning(str);
}
/**
* Display a warning that the specified method is not implemented, meaning
* that it could be either a completely missing function, although other
* variations of it may still work properly.
*/
static public void showMissingWarning(String method) {
PGraphics.showMissingWarning(method);
}
/**
* Return true if this renderer should be drawn to the screen. Defaults to
* returning true, since nearly all renderers are on-screen beasts. But can
@@ -10015,16 +10212,138 @@ public class PApplet extends Applet
}
public void blend(int mode) {
if (recorder != null) recorder.blend(mode);
g.blend(mode);
}
public void noBlend() {
if (recorder != null) recorder.noBlend();
g.noBlend();
}
public void textureBlend(int mode) {
if (recorder != null) recorder.textureBlend(mode);
g.textureBlend(mode);
}
public void noTextureBlend() {
if (recorder != null) recorder.noTextureBlend();
g.noTextureBlend();
}
public void mergeRecord() {
if (recorder != null) recorder.mergeRecord();
g.mergeRecord();
}
public void noMergeRecord() {
if (recorder != null) recorder.noMergeRecord();
g.noMergeRecord();
}
public void shapeName(String name) {
if (recorder != null) recorder.shapeName(name);
g.shapeName(name);
}
public void texture(PImage image0, PImage image1) {
if (recorder != null) recorder.texture(image0, image1);
g.texture(image0, image1);
}
public void texture(PImage image0, PImage image1, PImage image2) {
if (recorder != null) recorder.texture(image0, image1, image2);
g.texture(image0, image1, image2);
}
public void texture(PImage image0, PImage image1, PImage image2, PImage image3) {
if (recorder != null) recorder.texture(image0, image1, image2, image3);
g.texture(image0, image1, image2, image3);
}
public void texture(PImage[] images) {
if (recorder != null) recorder.texture(images);
g.texture(images);
}
public void vertex(float x, float y, float u0, float v0, float u1, float v1) {
if (recorder != null) recorder.vertex(x, y, u0, v0, u1, v1);
g.vertex(x, y, u0, v0, u1, v1);
}
public void vertex(float x, float y, float u0, float v0, float u1, float v1, float u2, float v2) {
if (recorder != null) recorder.vertex(x, y, u0, v0, u1, v1, u2, v2);
g.vertex(x, y, u0, v0, u1, v1, u2, v2);
}
public void vertex(float x, float y, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3) {
if (recorder != null) recorder.vertex(x, y, u0, v0, u1, v1, u2, v2, u3, v3);
g.vertex(x, y, u0, v0, u1, v1, u2, v2, u3, v3);
}
public void vertex(float x, float y, float[] u, float[] v) {
if (recorder != null) recorder.vertex(x, y, u, v);
g.vertex(x, y, u, v);
}
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1) {
if (recorder != null) recorder.vertex(x, y, z, u0, v0, u1, v1);
g.vertex(x, y, z, u0, v0, u1, v1);
}
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1, float u2, float v2) {
if (recorder != null) recorder.vertex(x, y, z, u0, v0, u1, v1, u2, v2);
g.vertex(x, y, z, u0, v0, u1, v1, u2, v2);
}
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3) {
if (recorder != null) recorder.vertex(x, y, z, u0, v0, u1, v1, u2, v2, u3, v3);
g.vertex(x, y, z, u0, v0, u1, v1, u2, v2, u3, v3);
}
public void vertex(float x, float y, float z, float[] u, float[] v) {
if (recorder != null) recorder.vertex(x, y, z, u, v);
g.vertex(x, y, z, u, v);
}
public void delete() {
if (recorder != null) recorder.delete();
g.delete();
}
/**
* Store data of some kind for a renderer that requires extra metadata of
* some kind. Usually this is a renderer-specific representation of the
* image data, for instance a BufferedImage with tint() settings applied for
* PGraphicsJava2D, or resized image data and OpenGL texture indices for
* PGraphicsOpenGL.
* @param renderer The PGraphics renderer associated to the image
* @param storage The metadata required by the renderer
*/
public void setCache(Object parent, Object storage) {
if (recorder != null) recorder.setCache(parent, storage);
g.setCache(parent, storage);
public void setCache(PGraphics renderer, PMetadata storage) {
if (recorder != null) recorder.setCache(renderer, storage);
g.setCache(renderer, storage);
}
@@ -10033,21 +10352,53 @@ public class PApplet extends Applet
* will cache data in different formats, it's necessary to store cache data
* keyed by the renderer object. Otherwise, attempting to draw the same
* image to both a PGraphicsJava2D and a PGraphicsOpenGL will cause errors.
* @param parent The PGraphics object (or any object, really) associated
* @return data stored for the specified parent
* @param renderer The PGraphics renderer associated to the image
* @return metadata stored for the specified renderer
*/
public Object getCache(Object parent) {
return g.getCache(parent);
public PMetadata getCache(PGraphics renderer) {
return g.getCache(renderer);
}
/**
* Remove information associated with this renderer from the cache, if any.
* @param parent The PGraphics object whose cache data should be removed
* @param renderer The PGraphics renderer whose cache data should be removed
*/
public void removeCache(Object parent) {
if (recorder != null) recorder.removeCache(parent);
g.removeCache(parent);
public void removeCache(PGraphics renderer) {
if (recorder != null) recorder.removeCache(renderer);
g.removeCache(renderer);
}
/**
* Store parameters for a renderer that requires extra metadata of
* some kind.
* @param renderer The PGraphics renderer associated to the image
* @param storage The parameters required by the renderer
*/
public void setParams(PGraphics renderer, PParameters params) {
if (recorder != null) recorder.setParams(renderer, params);
g.setParams(renderer, params);
}
/**
* Get the parameters for the specified renderer.
* @param renderer The PGraphics renderer associated to the image
* @return parameters stored for the specified renderer
*/
public PParameters getParams(PGraphics renderer) {
return g.getParams(renderer);
}
/**
* Remove information associated with this renderer from the cache, if any.
* @param renderer The PGraphics renderer whose parameters should be removed
*/
public void removeParams(PGraphics renderer) {
if (recorder != null) recorder.removeParams(renderer);
g.removeParams(renderer);
}
+55 -9
View File
@@ -111,17 +111,20 @@ public interface PConstants {
// has this vertex been lit yet
static public final int BEEN_LIT = 35;
static public final int VERTEX_FIELD_COUNT = 36;
// has this vertex been assigned a normal yet
static public final int HAS_NORMAL = 36;
static public final int VERTEX_FIELD_COUNT = 37;
// renderers known to processing.core
static final String P2D = "processing.core.PGraphics2D";
static final String P3D = "processing.core.PGraphics3D";
static final String JAVA2D = "processing.core.PGraphicsJava2D";
static final String OPENGL = "processing.opengl.PGraphicsOpenGL";
static final String PDF = "processing.pdf.PGraphicsPDF";
static final String DXF = "processing.dxf.RawDXF";
static final String P2D = "processing.core.PGraphics2D";
static final String P3D = "processing.core.PGraphics3D";
static final String JAVA2D = "processing.core.PGraphicsJava2D";
static final String OPENGL = "processing.opengl.PGraphicsOpenGL";
static final String OPENGL2 = "processing.opengl2.PGraphicsOpenGL2";
static final String PDF = "processing.pdf.PGraphicsPDF";
static final String DXF = "processing.dxf.RawDXF";
// platform IDs for PApplet.platform
@@ -326,7 +329,11 @@ public interface PConstants {
static final int SPHERE = 40;
static final int BOX = 41;
static public final int LINE_STRIP = 50;
static public final int LINE_LOOP = 51;
static public final int POINT_SPRITES = 52;
// shape closing modes
static final int OPEN = 1;
@@ -403,7 +410,37 @@ 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 TEXTURE2D = 0;
/** This constant identifies the nearest texture filter (point sampling) */
//public static final int POINT = 2; // shared with shape feature
/** This constant identifies the linear texture filter, usually called bilinear sampling */
public static final int BILINEAR = 3;
/** This constant identifies the linear/linear function to build mipmaps */
public static final int TRILINEAR = 4;
/** This constant identifies the clamp-to-edge wrapping mode */
public static final int CLAMP = 0;
/** This constant identifies the repeat wrapping mode */
public static final int REPEAT = 1;
/** Point sprite distance attenuation functions */
public static final int LINEAR = 0;
public static final int QUADRATIC = 1;
// 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;
/** Dynamic usage mode for PShape3D (vertices will be updated at every frame). */
public static final int STREAM = 2;
// stroke modes
static final int SQUARE = 1 << 0; // called 'butt' in the svg spec
@@ -485,9 +522,18 @@ public interface PConstants {
static final int ENABLE_ACCURATE_TEXTURES = 7;
static final int DISABLE_ACCURATE_TEXTURES = -7;
static final int DISABLE_DEPTH_MASK = 8;
static final int ENABLE_DEPTH_MASK = -8;
static final int HINT_COUNT = 10;
// Rendering pipeline modes
static final int FIXED = 0;
static final int PROG_GL2 = 1;
static final int PROG_GL3 = 2;
static final int PROG_GL4 = 3;
// error messages
static final String ERROR_BACKGROUND_IMAGE_SIZE =
+95 -9
View File
@@ -28,6 +28,7 @@ import java.awt.image.*;
import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
/**
@@ -154,7 +155,11 @@ public class PFont implements PConstants {
protected FontMetrics lazyMetrics;
protected int[] lazySamples;
/** for subclasses that need to store metadata about the font */
protected HashMap<PGraphics, PMetadata> cacheMap;
public PFont() { } // for subclasses
@@ -239,7 +244,8 @@ public class PFont implements PConstants {
if (glyf.value < 128) {
ascii[glyf.value] = glyphCount;
}
glyphs[glyphCount++] = glyf;
glyf.index = glyphCount;
glyphs[glyphCount++] = glyf;
}
}
@@ -340,6 +346,7 @@ public class PFont implements PConstants {
if (glyph.value < 128) {
ascii[glyph.value] = i;
}
glyph.index = i;
glyphs[i] = glyph;
}
@@ -366,6 +373,19 @@ public class PFont implements PConstants {
findFont();
}
void delete() {
if (cacheMap != null) {
Set<PGraphics> keySet = cacheMap.keySet();
if (!keySet.isEmpty()) {
Object[] keys = keySet.toArray();
for (int i = 0; i < keys.length; i++) {
PMetadata data = getCache((PGraphics)keys[i]);
data.delete();
}
}
}
}
/**
* Write this PFont to an OutputStream.
@@ -420,6 +440,7 @@ public class PFont implements PConstants {
glyphs = (Glyph[]) PApplet.expand(glyphs);
}
if (glyphCount == 0) {
glyph.index = 0;
glyphs[glyphCount] = glyph;
if (glyph.value < 128) {
ascii[glyph.value] = 0;
@@ -440,6 +461,7 @@ public class PFont implements PConstants {
ascii[glyphs[j].value] = j;
}
}
glyph.index = i;
glyphs[i] = glyph;
// cache locations of the ascii charset
if (c < 128) ascii[c] = i;
@@ -481,6 +503,14 @@ public class PFont implements PConstants {
return font;
}
/**
* Return size of this font.
*/
public int getSize() {
return size;
}
public boolean isStream() {
return stream;
@@ -625,6 +655,59 @@ public class PFont implements PConstants {
}
//////////////////////////////////////////////////////////////
// METADATA REQUIRED BY THE RENDERERS
/**
* Store data of some kind for a renderer that requires extra metadata of
* some kind. Usually this is a renderer-specific representation of the
* font data, for instance a custom OpenGL texture for PGraphicsOpenGL2.
* @param renderer The PGraphics renderer associated to the font
* @param storage The metadata required by the renderer
*/
public void setCache(PGraphics renderer, PMetadata storage) {
if (cacheMap == null) cacheMap = new HashMap<PGraphics, PMetadata>();
cacheMap.put(renderer, storage);
}
/**
* Get cache storage data for the specified renderer. Because each renderer
* will cache data in different formats, it's necessary to store cache data
* keyed by the renderer object. Otherwise, attempting to draw the same
* image to both a PGraphicsJava2D and a PGraphicsOpenGL2 will cause errors.
* @param renderer The PGraphics renderer associated to the font
* @return metadata stored for the specified renderer
*/
public PMetadata getCache(PGraphics renderer) {
if (cacheMap == null) return null;
return cacheMap.get(renderer);
}
/**
* Remove information associated with this renderer from the cache, if any.
* @param parent The PGraphics renderer whose cache data should be removed
*/
public void removeCache(PGraphics renderer) {
if (cacheMap != null) {
cacheMap.remove(renderer);
}
}
//////////////////////////////////////////////////////////////
public int getGlyphCount() {
return glyphCount;
}
public Glyph getGlyph(int i) {
return glyphs[i];
}
//////////////////////////////////////////////////////////////
@@ -757,21 +840,24 @@ public class PFont implements PConstants {
* A single character, and its visage.
*/
public class Glyph {
PImage image;
int value;
int height;
int width;
int setWidth;
int topExtent;
int leftExtent;
public PImage image;
public int value;
public int height;
public int width;
public int index;
public int setWidth;
public int topExtent;
public int leftExtent;
protected Glyph() {
index = -1;
// used when reading from a stream or for subclasses
}
protected Glyph(DataInputStream is) throws IOException {
index = -1;
readHeader(is);
}
+247 -24
View File
@@ -406,7 +406,7 @@ public class PGraphics extends PImage implements PConstants {
protected int shape;
// vertices
static final int DEFAULT_VERTICES = 512;
public static final int DEFAULT_VERTICES = 512;
protected float vertices[][] =
new float[DEFAULT_VERTICES][VERTEX_FIELD_COUNT];
protected int vertexCount; // total number of vertices
@@ -509,6 +509,8 @@ public class PGraphics extends PImage implements PConstants {
/// Keep track of how many calls to normal, to determine the mode.
//protected int normalCount;
protected boolean autoNormal;
/** Current normal vector. */
public float normalX, normalY, normalZ;
@@ -712,6 +714,8 @@ public class PGraphics extends PImage implements PConstants {
rectMode(CORNER);
ellipseMode(DIAMETER);
autoNormal = true;
// no current font
textFont = null;
@@ -836,6 +840,13 @@ public class PGraphics extends PImage implements PConstants {
}
}
public boolean hintEnabled(int which) {
if (which > 0) {
return hints[which];
} else {
return hints[-which];
}
}
//////////////////////////////////////////////////////////////
@@ -885,6 +896,14 @@ public class PGraphics extends PImage implements PConstants {
this.edge = edge;
}
/**
* Sets the automatic normal calculation mode.
*/
public void autoNormal(boolean auto) {
this.autoNormal = auto;
}
/**
* Sets the current normal vector. Only applies with 3D rendering
@@ -946,7 +965,17 @@ public class PGraphics extends PImage implements PConstants {
textureImage = image;
}
/**
* Removes texture image for current shape.
* Needs to be called between @see beginShape and @see endShape
*
*/
public void noTexture() {
textureImage = null;
}
protected void vertexCheck() {
if (vertexCount == vertices.length) {
float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT];
@@ -973,7 +1002,8 @@ public class PGraphics extends PImage implements PConstants {
// vertex[B] = fillB;
// vertex[A] = fillA;
// }
if (fill || textureImage != null) {
boolean textured = textureImage != null;
if (fill || textured) {
if (textureImage == null) {
vertex[R] = fillR;
vertex[G] = fillG;
@@ -1002,11 +1032,29 @@ public class PGraphics extends PImage implements PConstants {
vertex[SW] = strokeWeight;
}
if (textureImage != null) {
if (textured) {
vertex[U] = textureU;
vertex[V] = textureV;
}
if (autoNormal) {
float norm2 = normalX * normalX + normalY * normalY + normalZ * normalZ;
if (norm2 < EPSILON) {
vertex[HAS_NORMAL] = 0;
} else {
if (Math.abs(norm2 - 1) > EPSILON) {
// The normal vector is not normalized.
float norm = PApplet.sqrt(norm2);
normalX /= norm;
normalY /= norm;
normalZ /= norm;
}
vertex[HAS_NORMAL] = 1;
}
} else {
vertex[HAS_NORMAL] = 1;
}
vertexCount++;
}
@@ -1043,7 +1091,8 @@ public class PGraphics extends PImage implements PConstants {
vertex[EDGE] = edge ? 1 : 0;
if (fill || textureImage != null) {
boolean textured = textureImage != null;
if (fill || textured) {
if (textureImage == null) {
vertex[R] = fillR;
vertex[G] = fillG;
@@ -1087,10 +1136,28 @@ public class PGraphics extends PImage implements PConstants {
vertex[SW] = strokeWeight;
}
if (textureImage != null) {
if (textured) {
vertex[U] = textureU;
vertex[V] = textureV;
}
if (autoNormal) {
float norm2 = normalX * normalX + normalY * normalY + normalZ * normalZ;
if (norm2 < EPSILON) {
vertex[HAS_NORMAL] = 0;
} else {
if (Math.abs(norm2 - 1) > EPSILON) {
// The normal vector is not normalized.
float norm = PApplet.sqrt(norm2);
normalX /= norm;
normalY /= norm;
normalZ /= norm;
}
vertex[HAS_NORMAL] = 1;
}
} else {
vertex[HAS_NORMAL] = 1;
}
vertex[NX] = normalX;
vertex[NY] = normalY;
@@ -2110,22 +2177,20 @@ public class PGraphics extends PImage implements PConstants {
sphereDetail(30);
}
pushMatrix();
scale(r);
edge(false);
// 1st ring from south pole
beginShape(TRIANGLE_STRIP);
for (int i = 0; i < sphereDetailU; i++) {
normal(0, -1, 0);
vertex(0, -1, 0);
vertex(0, -r, 0);
normal(sphereX[i], sphereY[i], sphereZ[i]);
vertex(sphereX[i], sphereY[i], sphereZ[i]);
vertex(r * sphereX[i], r *sphereY[i], r * sphereZ[i]);
}
//normal(0, -1, 0);
vertex(0, -1, 0);
normal(sphereX[0], sphereY[0], sphereZ[0]);
vertex(sphereX[0], sphereY[0], sphereZ[0]);
vertex(r * sphereX[0], r * sphereY[0], r * sphereZ[0]);
endShape();
int v1,v11,v2;
@@ -2139,17 +2204,17 @@ public class PGraphics extends PImage implements PConstants {
beginShape(TRIANGLE_STRIP);
for (int j = 0; j < sphereDetailU; j++) {
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
vertex(sphereX[v1], sphereY[v1], sphereZ[v1++]);
vertex(r * sphereX[v1], r * sphereY[v1], r * sphereZ[v1++]);
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(sphereX[v2], sphereY[v2], sphereZ[v2++]);
vertex(r * sphereX[v2], r * sphereY[v2], r * sphereZ[v2++]);
}
// close each ring
v1 = v11;
v2 = voff;
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
vertex(sphereX[v1], sphereY[v1], sphereZ[v1]);
vertex(r * sphereX[v1], r * sphereY[v1], sphereZ[v1]);
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(r * sphereX[v2], r * sphereY[v2], r * sphereZ[v2]);
endShape();
}
@@ -2158,18 +2223,17 @@ public class PGraphics extends PImage implements PConstants {
for (int i = 0; i < sphereDetailU; i++) {
v2 = voff + i;
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(sphereX[v2], sphereY[v2], sphereZ[v2]);
vertex(r * sphereX[v2], r * sphereY[v2], r * sphereZ[v2]);
normal(0, 1, 0);
vertex(0, 1, 0);
vertex(0, r, 0);
}
normal(sphereX[voff], sphereY[voff], sphereZ[voff]);
vertex(sphereX[voff], sphereY[voff], sphereZ[voff]);
vertex(r * sphereX[voff], r * sphereY[voff], r * sphereZ[voff]);
normal(0, 1, 0);
vertex(0, 1, 0);
vertex(0, r, 0);
endShape();
edge(true);
popMatrix();
}
@@ -3151,7 +3215,14 @@ public class PGraphics extends PImage implements PConstants {
textLeading = (textAscent() + textDescent()) * 1.275f;
}
public void beginText() {
showMissingWarning("beginText");
}
public void endText() {
showMissingWarning("endText");
}
// ........................................................
@@ -4046,6 +4117,19 @@ public class PGraphics extends PImage implements PConstants {
}
//////////////////////////////////////////////////////////////
// PROJECTION
public void beginProjection() {
showMethodWarning("beginProjection");
}
public void endProjection() {
showMethodWarning("endProjection");
}
//////////////////////////////////////////////////////////////
@@ -5750,7 +5834,7 @@ public class PGraphics extends PImage implements PConstants {
* Display a warning that the specified method is only available with 3D.
* @param method The method name (no parentheses)
*/
static protected void showDepthWarning(String method) {
static public void showDepthWarning(String method) {
showWarning(method + "() can only be used with a renderer that " +
"supports 3D, such as P3D or OPENGL.");
}
@@ -5761,7 +5845,7 @@ public class PGraphics extends PImage implements PConstants {
* can only be used with x and y parameters in this renderer.
* @param method The method name (no parentheses)
*/
static protected void showDepthWarningXYZ(String method) {
static public void showDepthWarningXYZ(String method) {
showWarning(method + "() with x, y, and z coordinates " +
"can only be used with a renderer that " +
"supports 3D, such as P3D or OPENGL. " +
@@ -5772,7 +5856,7 @@ public class PGraphics extends PImage implements PConstants {
/**
* Display a warning that the specified method is simply unavailable.
*/
static protected void showMethodWarning(String method) {
static public void showMethodWarning(String method) {
showWarning(method + "() is not available with this renderer.");
}
@@ -5782,7 +5866,7 @@ public class PGraphics extends PImage implements PConstants {
* other variations are). For instance, if vertex(x, y, u, v) is not
* available, but vertex(x, y) is just fine.
*/
static protected void showVariationWarning(String str) {
static public void showVariationWarning(String str) {
showWarning(str + " is not available with this renderer.");
}
@@ -5792,7 +5876,7 @@ public class PGraphics extends PImage implements PConstants {
* that it could be either a completely missing function, although other
* variations of it may still work properly.
*/
static protected void showMissingWarning(String method) {
static public void showMissingWarning(String method) {
showWarning(method + "(), or this particular variation of it, " +
"is not available with this renderer.");
}
@@ -5863,4 +5947,143 @@ public class PGraphics extends PImage implements PConstants {
public boolean is3D() {
return false;
}
//////////////////////////////////////////////////////////////
// New API:
protected String[] getSupportedShapeFormats() {
return null;
}
protected PShape loadShape(String filename, PParameters params) {
return null;
}
protected PShape createShape(int size, PParameters params) {
return null;
}
public void blend(int mode) {
if (!is3D()) {
showMissingWarning("blend");
}
}
public void noBlend() {
if (!is3D()) {
showMissingWarning("noBlend");
}
}
public void textureBlend(int mode) {
if (!is3D()) {
showMissingWarning("blend");
}
}
public void noTextureBlend() {
if (!is3D()) {
showMissingWarning("noBlend");
}
}
public PShape beginRecord() { // ignore
if (!is3D()) {
showMissingWarning("beginRecord");
}
return null;
}
public void endRecord() { // ignore
if (!is3D()) {
showMissingWarning("endShapeRecord");
}
}
public boolean isRecording() { // ignore
return false;
}
public void mergeRecord() {
if (!is3D()) {
showMissingWarning("mergeRecord");
}
}
public void noMergeRecord() {
if (!is3D()) {
showMissingWarning("noMergeRecord");
}
}
public void shapeName(String name) {
if (!is3D()) {
showMissingWarning("shapeName");
}
}
public void texture(PImage image0, PImage image1) {
showMissingWarning("multitexturing requires OPENGL2");
}
public void texture(PImage image0, PImage image1, PImage image2) {
showMissingWarning("multitexturing requires OPENGL2");
}
public void texture(PImage image0, PImage image1, PImage image2, PImage image3) {
showMissingWarning("multitexturing requires OPENGL2");
}
public void texture(PImage[] images) {
showMissingWarning("multitexturing requires OPENGL2");
}
public void vertex(float x, float y, float u0, float v0, float u1, float v1) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float u0, float v0, float u1, float v1, float u2, float v2) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float[] u, float[] v) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1, float u2, float v2) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
public void vertex(float x, float y, float z, float[] u, float[] v) {
showMissingWarning("multitextured vertex requires OPENGL2");
}
}
+109 -36
View File
@@ -28,7 +28,6 @@ import java.awt.Toolkit;
import java.awt.image.*;
import java.util.*;
/**
* Subclass of PGraphics that handles 3D rendering.
* It can render 3D inside a browser window and requires no plug-ins.
@@ -175,11 +174,15 @@ public class PGraphics3D extends PGraphics {
* If we wanted to, this variable would have to become a stack.
*/
protected boolean manipulatingCamera;
float[][] matrixStack = new float[MATRIX_STACK_DEPTH][16];
float[][] matrixInvStack = new float[MATRIX_STACK_DEPTH][16];
int matrixStackDepth;
protected boolean projectionMode = false;
float[][] pmatrixStack = new float[MATRIX_STACK_DEPTH][16];
int pmatrixStackDepth;
// These two matrices always point to either the modelview
// or the modelviewInv, but they are swapped during
// when in camera manipulation mode. That way camera transforms
@@ -2991,26 +2994,41 @@ public class PGraphics3D extends PGraphics {
public void pushMatrix() {
if (matrixStackDepth == MATRIX_STACK_DEPTH) {
throw new RuntimeException(ERROR_PUSHMATRIX_OVERFLOW);
if (projectionMode) {
if (pmatrixStackDepth == MATRIX_STACK_DEPTH) {
throw new RuntimeException(ERROR_PUSHMATRIX_OVERFLOW);
}
projection.get(pmatrixStack[pmatrixStackDepth]);
pmatrixStackDepth++;
} else {
if (matrixStackDepth == MATRIX_STACK_DEPTH) {
throw new RuntimeException(ERROR_PUSHMATRIX_OVERFLOW);
}
modelview.get(matrixStack[matrixStackDepth]);
modelviewInv.get(matrixInvStack[matrixStackDepth]);
matrixStackDepth++;
}
modelview.get(matrixStack[matrixStackDepth]);
modelviewInv.get(matrixInvStack[matrixStackDepth]);
matrixStackDepth++;
}
public void popMatrix() {
if (matrixStackDepth == 0) {
throw new RuntimeException(ERROR_PUSHMATRIX_UNDERFLOW);
if (projectionMode) {
if (pmatrixStackDepth == 0) {
throw new RuntimeException(ERROR_PUSHMATRIX_UNDERFLOW);
}
pmatrixStackDepth--;
projection.set(pmatrixStack[pmatrixStackDepth]);
} else {
if (matrixStackDepth == 0) {
throw new RuntimeException(ERROR_PUSHMATRIX_UNDERFLOW);
}
matrixStackDepth--;
modelview.set(matrixStack[matrixStackDepth]);
modelviewInv.set(matrixInvStack[matrixStackDepth]);
}
matrixStackDepth--;
modelview.set(matrixStack[matrixStackDepth]);
modelviewInv.set(matrixInvStack[matrixStackDepth]);
}
//////////////////////////////////////////////////////////////
// MATRIX TRANSFORMATIONS
@@ -3022,8 +3040,12 @@ public class PGraphics3D extends PGraphics {
public void translate(float tx, float ty, float tz) {
forwardTransform.translate(tx, ty, tz);
reverseTransform.invTranslate(tx, ty, tz);
if (projectionMode) {
projection.translate(tx, ty, tz);
} else {
forwardTransform.translate(tx, ty, tz);
reverseTransform.invTranslate(tx, ty, tz);
}
}
@@ -3039,20 +3061,32 @@ public class PGraphics3D extends PGraphics {
public void rotateX(float angle) {
forwardTransform.rotateX(angle);
reverseTransform.invRotateX(angle);
if (projectionMode) {
projection.rotateX(angle);
} else {
forwardTransform.rotateX(angle);
reverseTransform.invRotateX(angle);
}
}
public void rotateY(float angle) {
forwardTransform.rotateY(angle);
reverseTransform.invRotateY(angle);
if (projectionMode) {
projection.rotateY(angle);
} else {
forwardTransform.rotateY(angle);
reverseTransform.invRotateY(angle);
}
}
public void rotateZ(float angle) {
forwardTransform.rotateZ(angle);
reverseTransform.invRotateZ(angle);
if (projectionMode) {
projection.rotateZ(angle);
} else {
forwardTransform.rotateZ(angle);
reverseTransform.invRotateZ(angle);
}
}
@@ -3061,8 +3095,12 @@ public class PGraphics3D extends PGraphics {
* except that it takes radians (instead of degrees).
*/
public void rotate(float angle, float v0, float v1, float v2) {
forwardTransform.rotate(angle, v0, v1, v2);
reverseTransform.invRotate(angle, v0, v1, v2);
if (projectionMode) {
projection.rotate(angle, v0, v1, v2);
} else {
forwardTransform.rotate(angle, v0, v1, v2);
reverseTransform.invRotate(angle, v0, v1, v2);
}
}
@@ -3086,8 +3124,12 @@ public class PGraphics3D extends PGraphics {
* Scale in three dimensions.
*/
public void scale(float x, float y, float z) {
forwardTransform.scale(x, y, z);
reverseTransform.invScale(x, y, z);
if (projectionMode) {
projection.scale(x, y, z);
} else {
forwardTransform.scale(x, y, z);
reverseTransform.invScale(x, y, z);
}
}
@@ -3116,8 +3158,12 @@ public class PGraphics3D extends PGraphics {
public void resetMatrix() {
forwardTransform.reset();
reverseTransform.reset();
if (projectionMode) {
projection.reset();
} else {
forwardTransform.reset();
reverseTransform.reset();
}
}
@@ -3153,16 +3199,22 @@ public class PGraphics3D extends PGraphics {
float n10, float n11, float n12, float n13,
float n20, float n21, float n22, float n23,
float n30, float n31, float n32, float n33) {
if (projectionMode) {
projection.apply(n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23,
n30, n31, n32, n33);
} else {
forwardTransform.apply(n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23,
n30, n31, n32, n33);
forwardTransform.apply(n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23,
n30, n31, n32, n33);
reverseTransform.invApply(n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23,
n30, n31, n32, n33);
reverseTransform.invApply(n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23,
n30, n31, n32, n33);
}
}
@@ -3636,7 +3688,28 @@ public class PGraphics3D extends PGraphics {
projection.print();
}
public PMatrix getProjection() {
return projection.get();
}
/**
* Enables projection mode. The geometric transformations and
* push/pop matrix operations are applied to the projection matrix
* instead to the modelview.
*/
public void beginProjection() {
projectionMode = true;
}
/**
* Disables projection mode.
*/
public void endProjection() {
projectionMode = false;
}
//////////////////////////////////////////////////////////////
@@ -816,7 +816,7 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
}
class ImageCache {
class ImageCache extends PMetadata {
PImage source;
boolean tinted;
int tintedColor;
@@ -832,6 +832,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
// image = new BufferedImage(source.width, source.height, type);
}
public void delete() {
}
/**
* Update the pixels of the cache image. Already determined that the tint
* has changed, or the pixels have changed, so should just go through
+87 -16
View File
@@ -27,6 +27,7 @@ package processing.core;
import java.awt.image.*;
import java.io.*;
import java.util.HashMap;
import java.util.Set;
import javax.imageio.ImageIO;
@@ -102,10 +103,11 @@ public class PImage implements PConstants, Cloneable {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/** for subclasses that need to store info about the image */
protected HashMap<Object,Object> cacheMap;
/** for renderers that need to store info about the image */
protected HashMap<PGraphics, PMetadata> cacheMap;
/** for renderers that need to store parameters about the image */
protected HashMap<PGraphics, PParameters> paramMap;
/** modified portion of the image */
protected boolean modified;
@@ -261,20 +263,36 @@ public class PImage implements PConstants, Cloneable {
return image;
}
public void delete() {
if (cacheMap != null) {
Set<PGraphics> keySet = cacheMap.keySet();
if (!keySet.isEmpty()) {
Object[] keys = keySet.toArray();
for (int i = 0; i < keys.length; i++) {
PMetadata data = getCache((PGraphics)keys[i]);
data.delete();
}
}
}
}
//////////////////////////////////////////////////////////////
// METADATA/PARAMETERS REQUIRED BY RENDERERS
/**
* Store data of some kind for a renderer that requires extra metadata of
* some kind. Usually this is a renderer-specific representation of the
* image data, for instance a BufferedImage with tint() settings applied for
* PGraphicsJava2D, or resized image data and OpenGL texture indices for
* PGraphicsOpenGL.
* @param renderer The PGraphics renderer associated to the image
* @param storage The metadata required by the renderer
*/
public void setCache(Object parent, Object storage) {
if (cacheMap == null) cacheMap = new HashMap<Object, Object>();
cacheMap.put(parent, storage);
public void setCache(PGraphics renderer, PMetadata storage) {
if (cacheMap == null) cacheMap = new HashMap<PGraphics, PMetadata>();
cacheMap.put(renderer, storage);
}
@@ -283,27 +301,60 @@ public class PImage implements PConstants, Cloneable {
* will cache data in different formats, it's necessary to store cache data
* keyed by the renderer object. Otherwise, attempting to draw the same
* image to both a PGraphicsJava2D and a PGraphicsOpenGL will cause errors.
* @param parent The PGraphics object (or any object, really) associated
* @return data stored for the specified parent
* @param renderer The PGraphics renderer associated to the image
* @return metadata stored for the specified renderer
*/
public Object getCache(Object parent) {
public PMetadata getCache(PGraphics renderer) {
if (cacheMap == null) return null;
return cacheMap.get(parent);
return cacheMap.get(renderer);
}
/**
* Remove information associated with this renderer from the cache, if any.
* @param parent The PGraphics object whose cache data should be removed
* @param renderer The PGraphics renderer whose cache data should be removed
*/
public void removeCache(Object parent) {
public void removeCache(PGraphics renderer) {
if (cacheMap != null) {
cacheMap.remove(parent);
cacheMap.remove(renderer);
}
}
/**
* Store parameters for a renderer that requires extra metadata of
* some kind.
* @param renderer The PGraphics renderer associated to the image
* @param storage The parameters required by the renderer
*/
public void setParams(PGraphics renderer, PParameters params) {
if (paramMap == null) paramMap = new HashMap<PGraphics, PParameters>();
paramMap.put(renderer, params);
}
/**
* Get the parameters for the specified renderer.
* @param renderer The PGraphics renderer associated to the image
* @return parameters stored for the specified renderer
*/
public PParameters getParams(PGraphics renderer) {
if (paramMap == null) return null;
return paramMap.get(renderer);
}
/**
* Remove information associated with this renderer from the cache, if any.
* @param renderer The PGraphics renderer whose parameters should be removed
*/
public void removeParams(PGraphics renderer) {
if (paramMap != null) {
paramMap.remove(renderer);
}
}
//////////////////////////////////////////////////////////////
// MARKING IMAGE AS MODIFIED / FOR USE w/ GET/SET
@@ -323,7 +374,27 @@ public class PImage implements PConstants, Cloneable {
modified = m;
}
public int getModifiedX1() {
return mx1;
}
public int getModifiedX2() {
return mx2;
}
public int getModifiedY1() {
return my1;
}
public int getModifiedY2() {
return my2;
}
/**
* Loads the pixel data for the image into its <b>pixels[]</b> array. This function must always be called before reading from or writing to <b>pixels[]</b>.
* <br><br>Certain renderers may or may not seem to require <b>loadPixels()</b> or <b>updatePixels()</b>. However, the rule is that any time you want to manipulate the <b>pixels[]</b> array, you must first call <b>loadPixels()</b>, and after changes have been made, call <b>updatePixels()</b>. Even if the renderer may not seem to use this function in the current Processing release, this will always be subject to change.
+41
View File
@@ -0,0 +1,41 @@
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Processing project - http://processing.org
Copyright (c) 2004-08 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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;
/**
* Abstract class to store metadata of some kind associated to a
* specific renderer.
*
*/
abstract public class PMetadata {
public PMetadata() {}
/**
* To allow for manual resource release.
*
*/
abstract public void delete();
}
+11
View File
@@ -0,0 +1,11 @@
package processing.core;
/**
* Abstract class to store the parameters for a metadata object.
*
*/
abstract public class PParameters implements PConstants {
public PParameters() {}
}
+81 -3
View File
@@ -108,6 +108,7 @@ public class PShape implements PConstants {
* @brief Shape document height
*/
public float height;
public float depth;
// set to false if the object is hidden in the layers palette
protected boolean visible = true;
@@ -289,7 +290,22 @@ public class PShape implements PConstants {
return height;
}
/**
* 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;
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -632,6 +648,10 @@ public class PShape implements PConstants {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public PShape getParent() {
return parent;
}
public int getChildCount() {
return childCount;
}
@@ -697,11 +717,55 @@ public class PShape implements PConstants {
}
}
// adds child who exactly at position idx in the array of children.
public void addChild(PShape who, int idx) {
if (idx < childCount) {
if (childCount == children.length) {
children = (PShape[]) PApplet.expand(children);
}
// Copy [idx, childCount - 1] to [idx + 1, childCount]
for (int i = childCount - 1; i >= idx; i--) {
children[i + 1] = children[i];
}
childCount++;
children[idx] = who;
who.parent = this;
if (who.getName() != null) {
addName(who.getName(), who);
}
}
}
/**
* Remove the child shape with index idx.
*/
public void removeChild(int idx) {
if (idx < childCount) {
PShape child = children[idx];
// Copy [idx + 1, childCount - 1] to [idx, childCount - 2]
for (int i = idx; i < childCount - 1; i++) {
children[i] = children[i + 1];
}
childCount--;
if (child.getName() != null && nameTable != null) {
nameTable.remove(child.getName());
}
}
}
/**
* Add a shape to the name lookup table.
*/
protected void addName(String nom, PShape shape) {
public void addName(String nom, PShape shape) {
if (parent != null) {
parent.addName(nom, shape);
} else {
@@ -712,6 +776,20 @@ public class PShape implements PConstants {
}
}
/**
* Returns the index of child who.
*/
public int getChildIndex(PShape who) {
for (int i = 0; i < childCount; i++) {
if (children[i] == who) {
return i;
}
}
return -1;
}
// public PShape createGroup() {
// PShape group = new PShape();