Tune shadow render, add to accept wait queue on web server

This commit is contained in:
Mike Primm 2011-05-20 23:26:46 -05:00
parent b56332eae8
commit 024e7dc96c
2 changed files with 72 additions and 49 deletions

View File

@ -63,8 +63,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
World world = tile.getWorld(); World world = tile.getWorld();
boolean isnether = (world.getEnvironment() == Environment.NETHER); boolean isnether = (world.getEnvironment() == Environment.NETHER);
BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB); BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
BufferedImage zim = new BufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2, BufferedImage.TYPE_INT_RGB);
WritableRaster r = im.getRaster(); WritableRaster r = im.getRaster();
WritableRaster zr = zim.getRaster();
boolean isempty = true; boolean isempty = true;
int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2 - ((127-maximumHeight)/2); int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2 - ((127-maximumHeight)/2);
@ -81,7 +82,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
Color c1 = new Color(); Color c1 = new Color();
Color c2 = new Color(); Color c2 = new Color();
int[] rgb = new int[3]; int[] rgb = new int[3*KzedMap.tileWidth];
int[] zrgb = new int[3*KzedMap.tileWidth/2];
/* draw the map */ /* draw the map */
for (y = 0; y < KzedMap.tileHeight;) { for (y = 0; y < KzedMap.tileHeight;) {
jx = ix; jx = ix;
@ -90,21 +92,27 @@ public class DefaultTileRenderer implements MapTileRenderer {
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) { for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
scan(world, jx, iy, jz, 0, isnether, c1, cache); scan(world, jx, iy, jz, 0, isnether, c1, cache);
scan(world, jx, iy, jz, 2, isnether, c2, cache); scan(world, jx, iy, jz, 2, isnether, c2, cache);
if(c1.isTransparent() == false) {
rgb[0] = c1.getRed(); rgb[1] = c1.getGreen(); rgb[2] = c1.getBlue(); rgb[3*x] = c1.getRed();
r.setPixel(x, y, rgb); rgb[3*x+1] = c1.getGreen();
isempty = false; rgb[3*x+2] = c1.getBlue();
} rgb[3*x-3] = c2.getRed();
if(c2.isTransparent() == false) { rgb[3*x-2] = c2.getGreen();
rgb[0] = c2.getRed(); rgb[1] = c2.getGreen(); rgb[2] = c2.getBlue(); rgb[3*x-1] = c2.getBlue();
r.setPixel(x - 1, y, rgb);
isempty = false; isempty = isempty && c1.isTransparent() && c2.isTransparent();
}
jx++; jx++;
jz++; jz++;
} }
r.setPixels(0, y, KzedMap.tileWidth, 1, rgb);
/* Sum up zoomed pixels - bilinar filter */
for(x = 0; x < KzedMap.tileWidth / 2; x++) {
zrgb[3*x] = rgb[6*x] + rgb[6*x+3];
zrgb[3*x+1] = rgb[6*x+1] + rgb[6*x+4];
zrgb[3*x+2] = rgb[6*x+2] + rgb[6*x+5];
}
y++; y++;
@ -116,18 +124,24 @@ public class DefaultTileRenderer implements MapTileRenderer {
jx++; jx++;
jz++; jz++;
scan(world, jx, iy, jz, 0, isnether, c2, cache); scan(world, jx, iy, jz, 0, isnether, c2, cache);
if(c1.isTransparent() == false) {
rgb[0] = c1.getRed(); rgb[1] = c1.getGreen(); rgb[2] = c1.getBlue();
r.setPixel(x, y, rgb);
isempty = false;
}
if(c2.isTransparent() == false) {
rgb[0] = c2.getRed(); rgb[1] = c2.getGreen(); rgb[2] = c2.getBlue();
r.setPixel(x - 1, y, rgb); rgb[3*x] = c1.getRed();
isempty = false; rgb[3*x+1] = c1.getGreen();
rgb[3*x+2] = c1.getBlue();
rgb[3*x-3] = c2.getRed();
rgb[3*x-2] = c2.getGreen();
rgb[3*x-1] = c2.getBlue();
isempty = isempty && c1.isTransparent() && c2.isTransparent();
} }
r.setPixels(0, y, KzedMap.tileWidth, 1, rgb);
/* Finish summing values for zoomed pixels */
for(x = 0; x < KzedMap.tileWidth / 2; x++) {
zrgb[3*x] = (zrgb[3*x] + rgb[6*x] + rgb[6*x+3]) >> 2;
zrgb[3*x+1] = (zrgb[3*x+1] + rgb[6*x+1] + rgb[6*x+4]) >> 2;
zrgb[3*x+2] = (zrgb[3*x+2] + rgb[6*x+2] + rgb[6*x+5]) >> 2;
} }
zr.setPixels(0, y/2, KzedMap.tileWidth/2, 1, zrgb);
y++; y++;
@ -139,13 +153,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
final File fname = outputFile; final File fname = outputFile;
final KzedMapTile mtile = tile; final KzedMapTile mtile = tile;
final BufferedImage img = im; final BufferedImage img = im;
final BufferedImage zimg = zim;
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(), final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
(KzedMap) mtile.getMap(), mtile); (KzedMap) mtile.getMap(), mtile);
final File zoomFile = MapManager.mapman.getTileFile(zmtile); final File zoomFile = MapManager.mapman.getTileFile(zmtile);
MapManager.mapman.enqueueImageWrite(new Runnable() { MapManager.mapman.enqueueImageWrite(new Runnable() {
public void run() { public void run() {
doFileWrites(fname, mtile, img, zmtile, zoomFile); doFileWrites(fname, mtile, img, zmtile, zoomFile, zimg);
} }
}); });
@ -153,7 +168,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
private void doFileWrites(final File fname, final KzedMapTile mtile, private void doFileWrites(final File fname, final KzedMapTile mtile,
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) { final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile,
final BufferedImage zimg) {
Debug.debug("saving image " + fname.getPath()); Debug.debug("saving image " + fname.getPath());
try { try {
ImageIO.write(img, "png", fname); ImageIO.write(img, "png", fname);
@ -162,6 +178,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
} }
img.flush();
mtile.file = fname; mtile.file = fname;
// Since we've already got the new tile, and we're on an async thread, just // Since we've already got the new tile, and we're on an async thread, just
// make the zoomed tile here // make the zoomed tile here
@ -199,12 +217,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
/* blit scaled rendered tile onto zoom-out tile */ /* blit scaled rendered tile onto zoom-out tile */
Graphics2D g2 = zIm.createGraphics(); WritableRaster zim = zIm.getRaster();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); zim.setRect(ox, oy, zimg.getRaster());
g2.drawImage(img, ox, oy, scw, sch, null); zimg.flush();
g2.dispose(); /* Supposed to speed up non-heap memory recovery */
img.flush();
/* save zoom-out tile */ /* save zoom-out tile */
@ -226,12 +241,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result, protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
MapChunkCache cache) { MapChunkCache cache) {
scan(world, x, y, z, seq, isnether, result, cache, 15); int lightlevel = 15;
}
private void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
MapChunkCache cache, int lightlevel) {
int newlightlevel = 15;
result.setTransparent(); result.setTransparent();
for (;;) { for (;;) {
if (y < 0) { if (y < 0) {
@ -250,11 +260,27 @@ public class DefaultTileRenderer implements MapTileRenderer {
else else
isnether = false; isnether = false;
} }
if(id != 0) { /* No update needed for air */
if(colorScheme.datacolors[id] != null) { /* If data colored */ if(colorScheme.datacolors[id] != null) { /* If data colored */
data = cache.getBlockData(x, y, z); data = cache.getBlockData(x, y, z);
} }
if(shadowscale != null) { if((shadowscale != null) && (y < 127)) {
newlightlevel = cache.getBlockSkyLight(x, y, z); /* Remember this - light path for next block */ /* Find light level of previous chunk */
switch(seq) {
case 0:
lightlevel = cache.getBlockSkyLight(x, y+1, z);
break;
case 1:
lightlevel = cache.getBlockSkyLight(x+1, y, z);
break;
case 2:
lightlevel = cache.getBlockSkyLight(x, y+1, z);
break;
case 3:
lightlevel = cache.getBlockSkyLight(x, y, z-1);
break;
}
}
} }
switch (seq) { switch (seq) {
@ -298,7 +324,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
/* this block is transparent, so recurse */ /* this block is transparent, so recurse */
scan(world, x, y, z, seq, isnether, result, cache, newlightlevel); scan(world, x, y, z, seq, isnether, result, cache);
int cr = c.getRed(); int cr = c.getRed();
int cg = c.getGreen(); int cg = c.getGreen();
@ -319,14 +345,11 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
} }
} }
lightlevel = newlightlevel; /* Advance - next block uses last block's light */
} }
} }
private final void shadowColor(Color c, int lightlevel) { private final void shadowColor(Color c, int lightlevel) {
int scale = shadowscale[lightlevel]; int scale = shadowscale[lightlevel];
if(scale == 0) if(scale < 256)
c.setRGBA(0, 0, 0, c.getAlpha());
else if(scale < 256)
c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8, c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
(c.getBlue() * scale) >> 8, c.getAlpha()); (c.getBlue() * scale) >> 8, c.getAlpha());
} }

View File

@ -29,7 +29,7 @@ public class HttpServer extends Thread {
} }
public void startServer() throws IOException { public void startServer() throws IOException {
sock = new ServerSocket(port, 5, bindAddress); sock = new ServerSocket(port, 50, bindAddress); /* 5 too low - more than a couple users during render will get connect errors on some tile loads */
listeningThread = this; listeningThread = this;
start(); start();
Log.info("Dynmap WebServer started on " + bindAddress + ":" + port); Log.info("Dynmap WebServer started on " + bindAddress + ":" + port);