more work on the java2d engine

This commit is contained in:
benfry
2005-02-14 16:32:19 +00:00
parent 02b08c67c1
commit a0c207f09e
3 changed files with 233 additions and 53 deletions

View File

@@ -1373,6 +1373,15 @@ public class PGraphics extends PImage implements PConstants {
// this probably needs to be broken into affine/non-affine versions
// since affine w/ smoothing is a fairly easy case to handle and
// with better quality and speed than using the full texture mapping.
/**
* u, v coordinates are always of the form x1, y1, x2, y2, or the
* same as imageMode(CORNERS), even if the imageMode is something else.
*
* when drawing without depth(), the coordinates for u, v are
* always done in IMAGE_SPACE, because the textureMode() option
* is not available in 2D.
*/
public void image(PImage image,
float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2) {

View File

@@ -44,6 +44,10 @@ public class PGraphics2 extends PGraphics {
new AffineTransform[MATRIX_STACK_DEPTH];
double transform[] = new double[6];
Elipse2D.Float ellipse = new Ellipse2D.Float();
Rectangle2D.Float rect = new Rectangle2D.Float();
Arc2D.Float arc = new Arc2D.Float();
//////////////////////////////////////////////////////////////
@@ -142,6 +146,10 @@ public class PGraphics2 extends PGraphics {
case POINTS:
{
for (int i = 0; i < vertexCount; i++) {
point(vertices[i][VX], vertices[i][VY]);
}
stop = vertex_end;
for (int i = vertex_start; i < stop; i++) {
add_path(); // total overkill for points
@@ -372,9 +380,22 @@ public class PGraphics2 extends PGraphics {
// SHAPES
protected void draw_shape(Shape s) {
if (fill) {
graphics.setColor(fillColorObject);
graphics.fill(s);
}
if (stroke) {
graphics.setColor(strokeColorObject);
graphics.draw(s);
}
}
public void point(float x, float y) {
graphics.setColor(strokeColorObject);
graphics.drawLine(x1, y1, x2, y2);
//graphics.setColor(strokeColorObject);
//graphics.drawLine(x1, y1, x2, y2);
line(x, y, x, y);
}
@@ -386,68 +407,100 @@ public class PGraphics2 extends PGraphics {
public void triangle(float x1, float y1, float x2, float y2,
float x3, float y3) {
// TODO
GeneralPath gp = new GeneralPath();
gp.moveTo(x1, y1);
gp.lineTo(x2, y2);
gp.lineTo(x3, y3);
gp.closePath();
draw_shape(gp);
}
public void rect(float x1, float y1, float x2, float y2) {
if (fill) {
graphics.setColor(fillColorObject);
graphics.fillRect(x1, y1, x2, y2);
}
if (stroke) {
graphics.setColor(strokeColorObject);
graphics.drawRect(x1, y1, x2, y2);
switch (rectMode) {
case CORNERS:
rect.setFrameFromDiagonal(x1, y1, x2, y2);
break;
case CORNER:
rect.setFrame(x1, y1, x2, y2);
break;
case CENTER_RADIUS:
rect.setFrame(x1 - x2, y1 - y2, x1 + x2, y1 + y2);
break;
case CENTER:
rect.setFrame(x1 - x2/2.0f, y1 - y2/2.0f, x1 + x2/2.0f, y1 + y2/2.0f);
break;
}
draw_shape(rect);
}
public void quad(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4) {
GeneralPath gp = new GeneralPath();
gp.moveTo(x1, y1);
gp.lineTo(x2, y2);
gp.lineTo(x3, y3);
gp.lineTo(x4, y4);
gp.closePath();
draw_shape(gp);
}
public void image(PImage image, float x1, float y1) {
}
public void image(PImage image,
float x1, float y1, float x2, float y2) {
}
public void image(PImage image,
float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2) {
}
//public void cache(PImage image) {
//}
//public void cache(PImage images[]) {
//}
//public void arcMode(int mode) {
//}
public void arc(float start, float stop,
float x, float y, float radius) {
arc(start, stop, x, y, radius, radius);
}
public void arc(float start, float stop,
float x, float y, float hr, float vr) {
float x, float y, float w, float h) {
if (arcMode == CORNERS) {
w -= x;
h -= y;
} else if (arcMode == CENTER_RADIUS) {
x -= w;
y -= h;
w *= 2;
h *= 2;
} else if (arcMode == CENTER) {
x -= w;
y -= h;
}
arc.setArc(x, y, w, h, start, stop-start, Arc2D.PIE);
draw_shape(arc);
}
public void ellipse(float x, float y, float hradius, float vradius) {
ellipse.setFrame(x, y, hradius, vradius);
draw_shape(ellipse);
}
public void circle(float x, float y, float radius) {
ellipse(x, y, radius, radius);
}
public void bezier(float x1, float y1,
float x2, float y2,
float x3, float y3,
float x4, float y4) {
GeneralPath gp = new GeneralPath();
gp.moveTo(x1, y1);
gp.quadTo(x2, y2, x3, y3, x4, y4);
gp.closePath();
draw_shape(gp);
}
public void bezierDetail(int detail) {
// ignored in java2d
}
@@ -456,18 +509,91 @@ public class PGraphics2 extends PGraphics {
// ignored in java2d
}
public void curveTightness(float tightness) {
// TODO
}
public void curve(float x1, float y1,
float x2, float y2,
float x3, float y3,
float x4, float y4) {
// TODO
// TODO need inverse catmull rom to bezier matrix
}
//////////////////////////////////////////////////////////////
// IMAGES
public void image(PImage image, float x1, float y1) {
image(image, x1, y1, image.width, image.height);
}
public void image(PImage image,
float x1, float y1, float x2, float y2) {
if (imageMode == CORNER) {
x2 += x1; // x2 is width, need to add x1
y2 += y1;
} else if ((imageMode == CENTER) ||
(imageMode == CENTER_RADIUS)) {
x1 -= image.width /2f;
y1 -= image.height / 2f;
}
check_image_cache();
graphics.drawImage((Image) image.cache, x1, y1, x2, y2, null);
}
public void image(PImage image,
float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2) {
if (imageMode == CORNER) {
x2 += x1; // x2 is width, need to add x1
y2 += y1;
} else if ((imageMode == CENTER) ||
(imageMode == CENTER_RADIUS)) {
x1 -= image.width /2f;
y1 -= image.height / 2f;
}
check_image_cache();
graphics.drawImage((Image) image.cache,
(int)x1, (int)y1, (int)x2, (int)y2,
(int)u1, (int)v1, (int)u2, (int)v2,
null);
}
protected void check_image_cache(PImage what) {
if (image.cache == null) {
cache = new BufferedImage(image.width, image.height,
BufferedImage.TYPE_INT_ARGB);
image.modified(); // mark the whole thing for update
}
if (image.modified) {
// update the sub-portion of the image as necessary
BufferedImage bi = (BufferedImage) image.cache;
bi.setRGB(image.mx1, image.my1,
image.mx2 - image.mx1 + 1,
image.my2 - image.my1 + 1,
image.pixels,
image.my1*image.width + image.mx1, // offset for copy
image.width); // scan size
image.resetModified();
}
}
//////////////////////////////////////////////////////////////
/*
public void textFont(PFont which);
@@ -503,7 +629,6 @@ public class PGraphics2 extends PGraphics {
*/
//////////////////////////////////////////////////////////////
// MATRIX
@@ -645,7 +770,7 @@ public class PGraphics2 extends PGraphics {
protected void calc_tint() {
super.calc_tint();
// ??? how to do this
// TODO actually implement tinted images
tintColorObject = new Color(tintColor);
}
@@ -662,18 +787,6 @@ public class PGraphics2 extends PGraphics {
}
/*
public void noTint() {
}
public void noFill() {
}
public void noStroke() {
}
*/
public void background(PImage image) {
if ((image.width != width) || (image.height != height)) {
die("background image must be the same size " +
@@ -683,8 +796,10 @@ public class PGraphics2 extends PGraphics {
die("background images should be RGB or ARGB");
}
// make sure it's been properly updated
check_image_cache(image);
// blit image to the screen
//System.arraycopy(image.pixels, 0, pixels, 0, pixels.length);
graphics.drawImage((BufferedImage) image.cache, 0, 0);
}
@@ -709,11 +824,11 @@ public class PGraphics2 extends PGraphics {
public void alpha(int alpha[]) {
// TODO
// does nothing in PGraphics
}
public void alpha(PImage alpha) {
// TODO
// does nothing in PGraphics
}
public void filter(int kind) {
@@ -784,13 +899,27 @@ public class PGraphics2 extends PGraphics {
}
/**
* This is used to both set the pixels[] array so that it can be
* manipulated, and it also returns a PImage object that can be
* messed with directly.
*/
public PImage get() {
// TODO
//PImage outgoing = new PImage(width, height);
// int[] getRGB(int startX, int startY, int w, int h,
// int[] rgbArray, int offset, int scansize)
if (pixels == null) {
pixels = new int[width * height];
}
image.getRGB(0, 0, width, height, pixels, 0, width);
return new PImage(pixels, width, height, RGB);
}
public void save(String filename) {
// TODO
//static boolean write(RenderedImage im, String formatName, File output)
// maybe use ImageIO.save(File file) here if it's available?
get().save(filename);
}
@@ -804,4 +933,4 @@ public class PGraphics2 extends PGraphics {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
}
}
}

View File

@@ -84,9 +84,13 @@ public class PImage implements PConstants, Cloneable {
public int imageMode = CORNER;
public boolean smooth = false;
/** for gl subclass / hardware accel */
/** for subclasses that need to store info about the image */
public Object cache;
/** modified portion of the image */
public boolean modified;
public int mx1, my1, mx2, my2;
// private fields
private int fracU, ifU, fracV, ifV, u1, u2, v1, v2, sX, sY, iw, iw1, ih1;
private int ul, ll, ur, lr, cUL, cLL, cUR, cLR;
@@ -175,6 +179,44 @@ public class PImage implements PConstants, Cloneable {
}
public void modified() {
mx1 = 0;
my1 = 0;
mx2 = width;
my2 = height;
modified = true;
}
public void modified(int x, int y) {
if (x < mx1) mx1 = x;
if (x > mx2) mx2 = x;
if (y < my1) my1 = y;
if (y > my2) my2 = y;
modified = true;
}
public void modified(int x1, int y1, int x2, int y2) {
if (x1 < mx1) mx1 = x1;
if (x1 > mx2) mx2 = x1;
if (y1 < my1) my1 = y1;
if (y1 > my2) my2 = y1;
if (x2 < mx1) mx1 = x2;
if (x2 > mx2) mx2 = x2;
if (y2 < my1) my1 = y2;
if (y2 > my2) my2 = y2;
modified = true;
}
public void resetModified() {
mx1 = -Integer.MAX_VALUE;
my1 = -Integer.MAX_VALUE;
mx2 = Integer.MAX_VALUE;
my2 = Integer.MAX_VALUE;
}
/**
* Set alpha channel for an image.
*/