}
private final Texture2D getTexture(Image base, boolean border, Color col, float alpha, boolean tile) {
if (base == null) return null;
Texture2D tex = textureCache.get(new ImageAlpha(base, alpha));
if (tex == null) {
MediaTracker tracker = new MediaTracker(comp);
// Fully load image before continuing
tracker.addImage(base, 0);
do {
try { tracker.waitForID(0); } catch (InterruptedException e) { continue; }
} while (false);
tracker.removeImage(base);
final int w = base.getWidth(null), h = base.getHeight(null);
BufferedImage tmp = new BufferedImage(w*2, h*2, BufferedImage.TYPE_INT_ARGB);
Graphics2D tgr = tmp.createGraphics();
if (col != null) {
tgr.setColor(col);
tgr.fillRect(0, 0, w*2, h*2);
}
tgr.translate(w/2, h/2);
tgr.drawImage(base, null, null);
if (tile) {
// create an image of a hex with all 6 surrounding hexes to get
// better interpolation at the borders
tgr.translate(0, -h);
tgr.drawImage(base, null, null);
tgr.translate(0, 2*h);
tgr.drawImage(base, null, null);
tgr.translate(-3*w/4, -h/2);
tgr.drawImage(base, null, null);
tgr.translate(0, -h);
tgr.drawImage(base, null, null);
tgr.translate(3*w/2, 0);
tgr.drawImage(base, null, null);
tgr.translate(0, h);
tgr.drawImage(base, null, null);
}
tracker.addImage(tmp, 1);
do {
try { tracker.waitForID(1); } catch (InterruptedException e) { continue; }
} while (false);
tracker.removeImage(tmp);
// TODO: Make this configurable.
// Cut outer pixel border? This removes the distinct tile border present in most tiles.
int border_cut = 1;
// Add our own pixel border? Higher quality (resolution) than the image's tile border.
int border_add = 3;
if (!border) {
border_cut = 0;
border_add = 0;
}
// Scale texture image, cutting border if needed
BufferedImage src = new BufferedImage(TEXSIZE, TEXSIZE, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(TEXSIZE/(double)(w-border_cut*2), TEXSIZE/(double)(h-border_cut*2));
at.translate(-w/2-border_cut, -h/2-border_cut);
AffineTransformOp ato = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
ato.filter(tmp, src);
if (border_add > 0) {
// Add border if needed
Graphics2D gr = src.createGraphics();
gr.setColor(Color.DARK_GRAY);
gr.setStroke(new BasicStroke(border_add));
gr.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
int[] xvals = { TEXSIZE/4, 3*TEXSIZE/4-1, TEXSIZE-1, 3*TEXSIZE/4-1, TEXSIZE/4, 0, TEXSIZE/4 };
int[] yvals = { 0, 0, TEXSIZE/2, TEXSIZE-1, TEXSIZE-1, TEXSIZE/2, 0 };
gr.drawPolygon(xvals, yvals, xvals.length);
}
if (alpha < 1.0f) {
WritableRaster wr = src.getAlphaRaster();
for (int y = 0; y < src.getHeight(); y++) {
for (int x = 0; x < src.getWidth(); x++)
wr.setSample(x, y, 0, alpha*wr.getSampleFloat(x, y, 0));
}
}
// Finally create actual texture
TextureLoader tl = new TextureLoader(src, TextureLoader.GENERATE_MIPMAP);
tex = (Texture2D)tl.getTexture();
tex.setMagFilter(Texture.NICEST);
tex.setMinFilter(Texture.NICEST);
if (tileManager.isLoaded()) textureCache.put(new ImageAlpha(base, alpha), tex);
}
return tex;
}