/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.pepsoft.worldpainter.heightMaps.gui; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import org.pepsoft.util.MathUtils; import org.pepsoft.util.swing.TileListener; import org.pepsoft.util.swing.TileProvider; import org.pepsoft.worldpainter.HeightMap; /** * * @author pepijn */ public class HeightMapTileProvider implements TileProvider { public HeightMapTileProvider(HeightMap heightMap) { if (heightMap == null) { throw new NullPointerException(); } this.heightMap = heightMap; } public HeightMap getHeightMap() { return heightMap; } // TileProvider @Override public int getTileSize() { return 128; } @Override public boolean isTilePresent(int x, int y) { return true; } @Override public boolean paintTile(Image tileImage, int x, int y, int imageX, int imageY) { final BufferedImage image = renderBufferRef.get(); final WritableRaster raster = image.getRaster(); final float vertScale = 255 / heightMap.getRange()[1]; if (zoom < 0) { final int scale = -zoom; final int xOffset = x << 7 << scale, yOffset = y << 7 << scale; for (int dx = 0; dx < 128; dx++) { for (int dy = 0; dy < 128; dy++) { raster.setSample(dx, dy, 0, MathUtils.clamp(0, (int) (heightMap.getHeight(xOffset + (dx << scale), yOffset + (dy << scale)) * vertScale + 0.5f), 255)); } } } else { final int xOffset = x << 7, yOffset = y << 7; for (int dx = 0; dx < 128; dx++) { for (int dy = 0; dy < 128; dy++) { raster.setSample(dx, dy, 0, MathUtils.clamp(0, (int) (heightMap.getHeight(xOffset + dx, yOffset + dy) * vertScale + 0.5f), 255)); } } } Graphics2D g2 = (Graphics2D) tileImage.getGraphics(); try { g2.drawImage(image, imageX, imageY, null); } finally { g2.dispose(); } return true; } @Override public int getTilePriority(int x, int y) { return 0; } @Override public Rectangle getExtent() { return null; } @Override public void addTileListener(TileListener tileListener) { // Do nothing } @Override public void removeTileListener(TileListener tileListener) { // Do nothing } @Override public boolean isZoomSupported() { return true; } @Override public int getZoom() { return zoom; } @Override public void setZoom(int zoom) { if (zoom != this.zoom) { if (zoom > 0) { throw new UnsupportedOperationException("Zooming in not supported"); } this.zoom = zoom; } } private final HeightMap heightMap; private final ThreadLocal<BufferedImage> renderBufferRef = new ThreadLocal<BufferedImage>() { @Override protected BufferedImage initialValue() { return new BufferedImage(128, 128, BufferedImage.TYPE_BYTE_GRAY); } }; private int zoom = 0; }