Optimized the fringe tile creation process (we only create the graphics
context once and use it to stamp all fringe fragments). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3633 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -50,11 +50,12 @@ public class TileFringer
|
|||||||
public String getDefaultType ();
|
public String getDefaultType ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface ImageSource
|
public static interface ImageSource extends ImageUtil.ImageCreator
|
||||||
{
|
{
|
||||||
/** Creates a blank image into which various fringe images will be
|
/** Creates a blank image into which various fringe images will be
|
||||||
* composited. */
|
* composited. */
|
||||||
public BufferedImage createImage (int width, int height);
|
public BufferedImage createImage (
|
||||||
|
int width, int height, int transparency);
|
||||||
|
|
||||||
/** Returns the source image for a tile of the specified type.
|
/** Returns the source image for a tile of the specified type.
|
||||||
* This can be randomly selected and change from call to call. */
|
* This can be randomly selected and change from call to call. */
|
||||||
@@ -143,25 +144,34 @@ public class TileFringer
|
|||||||
QuickSort.sort(fringers);
|
QuickSort.sort(fringers);
|
||||||
|
|
||||||
BufferedImage source = _isrc.getTileSource(baseType);
|
BufferedImage source = _isrc.getTileSource(baseType);
|
||||||
int width = source.getWidth(), height = source.getHeight();
|
BufferedImage ftimg = _isrc.createImage(
|
||||||
BufferedImage ftimg = _isrc.createImage(width, height);
|
source.getWidth(), source.getHeight(), Transparency.OPAQUE);
|
||||||
stampTileImage(source, ftimg, width, height);
|
Graphics2D gfx = (Graphics2D)ftimg.getGraphics();
|
||||||
for (int ii = 0; ii < fringers.length; ii++) {
|
try {
|
||||||
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
// start with the base tile image
|
||||||
for (int jj = 0; jj < indexes.length; jj++) {
|
gfx.drawImage(source, 0, 0, null);
|
||||||
ftimg = getTileImage(ftimg, fringers[ii].fringerType,
|
|
||||||
indexes[jj], masks, hashValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// and stamp the fringers on top of it
|
||||||
|
for (int ii = 0; ii < fringers.length; ii++) {
|
||||||
|
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
||||||
|
for (int jj = 0; jj < indexes.length; jj++) {
|
||||||
|
stampTileImage(gfx, fringers[ii].fringerType,
|
||||||
|
indexes[jj], masks, hashValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
gfx.dispose();
|
||||||
|
}
|
||||||
return ftimg;
|
return ftimg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve or compose an image for the specified fringe.
|
* Looks up or creates the appropriate fringe mask and draws it into
|
||||||
|
* the supplied graphics context.
|
||||||
*/
|
*/
|
||||||
protected BufferedImage getTileImage (
|
protected void stampTileImage (
|
||||||
BufferedImage ftimg, String fringerType, int index,
|
Graphics2D gfx, String fringerType, int index,
|
||||||
HashMap masks, int hashValue)
|
HashMap masks, int hashValue)
|
||||||
{
|
{
|
||||||
FringeConfiguration.FringeRecord frec =
|
FringeConfiguration.FringeRecord frec =
|
||||||
@@ -171,28 +181,26 @@ public class TileFringer
|
|||||||
if (fsimg == null) {
|
if (fsimg == null) {
|
||||||
Log.warning("Missing fringe source image [type=" + fringerType +
|
Log.warning("Missing fringe source image [type=" + fringerType +
|
||||||
", hash=" + hashValue + ", frec=" + frec + "].");
|
", hash=" + hashValue + ", frec=" + frec + "].");
|
||||||
return ftimg;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frec.mask) {
|
if (frec.mask) {
|
||||||
|
// it's a mask; look for it in the cache
|
||||||
|
String maskkey = fringerType + ":" + frec.name + ":" + index;
|
||||||
|
BufferedImage mimg = (BufferedImage)masks.get(maskkey);
|
||||||
|
if (mimg == null) {
|
||||||
|
BufferedImage fsrc = getSubimage(fsimg, index);
|
||||||
|
BufferedImage bsrc = _isrc.getTileSource(fringerType);
|
||||||
|
mimg = ImageUtil.composeMaskedImage(_isrc, fsrc, bsrc);
|
||||||
|
masks.put(maskkey, mimg);
|
||||||
|
}
|
||||||
|
gfx.drawImage(mimg, 0, 0, null);
|
||||||
|
|
||||||
|
} else {
|
||||||
// this is a non-mask image so just use the data from the
|
// this is a non-mask image so just use the data from the
|
||||||
// fringe source image directly
|
// fringe source image directly
|
||||||
BufferedImage stamp = getSubimage(fsimg, index);
|
gfx.drawImage(getSubimage(fsimg, index), 0, 0, null);
|
||||||
return stampTileImage(stamp, ftimg, stamp.getWidth(),
|
|
||||||
stamp.getHeight());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, it's a mask; look for it in the cache
|
|
||||||
String maskkey = fringerType + ":" + frec.name + ":" + index;
|
|
||||||
BufferedImage mimg = (BufferedImage)masks.get(maskkey);
|
|
||||||
if (mimg == null) {
|
|
||||||
BufferedImage fsrc = getSubimage(fsimg, index);
|
|
||||||
BufferedImage bsrc = _isrc.getTileSource(fringerType);
|
|
||||||
mimg = ImageUtil.composeMaskedImage(null, fsrc, bsrc); // TODO
|
|
||||||
masks.put(maskkey, mimg);
|
|
||||||
}
|
|
||||||
return stampTileImage(mimg, ftimg, mimg.getWidth(null),
|
|
||||||
mimg.getHeight(null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,23 +214,6 @@ public class TileFringer
|
|||||||
return source.getSubimage(x, 0, size, size);
|
return source.getSubimage(x, 0, size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper function for {@link #getTileImage}. */
|
|
||||||
protected BufferedImage stampTileImage (
|
|
||||||
BufferedImage stamp, BufferedImage ftimg, int width, int height)
|
|
||||||
{
|
|
||||||
// create the target image if necessary
|
|
||||||
if (ftimg == null) {
|
|
||||||
ftimg = _isrc.createImage(width, height);
|
|
||||||
}
|
|
||||||
Graphics2D gfx = (Graphics2D)ftimg.getGraphics();
|
|
||||||
try {
|
|
||||||
gfx.drawImage(stamp, 0, 0, null);
|
|
||||||
} finally {
|
|
||||||
gfx.dispose();
|
|
||||||
}
|
|
||||||
return ftimg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the fringe index specified by the fringebits. If no index
|
* Get the fringe index specified by the fringebits. If no index
|
||||||
* is available, try breaking down the bits into contiguous regions of
|
* is available, try breaking down the bits into contiguous regions of
|
||||||
|
|||||||
Reference in New Issue
Block a user