private void scheduleTileForRendering(final Tile tile) { // System.out.println("Scheduling tile for rendering: " + tile.getX() + ", " + // tile.getY()); if (SwingUtilities.isEventDispatchThread()) { Rectangle visibleArea = ((JViewport) getParent()).getViewRect(); Rectangle tileBounds = zoom(getTileBounds(tile.getX(), tile.getY())); if (tileBounds.intersects(visibleArea)) { // The tile is (partially) visible, so it should be repainted // immediately switch (refreshMode) { case IMMEDIATE: threeDeeRenderManager.renderTile(tile); break; case DELAYED: tilesWaitingToBeRendered.add(tile); lastTileChange = System.currentTimeMillis(); break; case MANUAL: // Do nothing break; default: throw new InternalError(); } } else { // The tile is not visible, so repaint it when it becomes visible tilesWaitingToBeRendered.remove(tile); renderedTiles.remove(tile); } } else { SwingUtilities.invokeLater( () -> { Rectangle visibleArea = ((JViewport) getParent()).getViewRect(); Rectangle tileBounds = zoom(getTileBounds(tile.getX(), tile.getY())); if (tileBounds.intersects(visibleArea)) { // The tile is (partially) visible, so it should be repainted // immediately switch (refreshMode) { case IMMEDIATE: threeDeeRenderManager.renderTile(tile); break; case DELAYED: tilesWaitingToBeRendered.add(tile); lastTileChange = System.currentTimeMillis(); break; case MANUAL: // Do nothing break; default: throw new InternalError(); } } else { // The tile is not visible, so repaint it when it becomes visible tilesWaitingToBeRendered.remove(tile); renderedTiles.remove(tile); } }); } }
@Override public void actionPerformed(ActionEvent e) { // Send tiles to be rendered if ((!tilesWaitingToBeRendered.isEmpty()) && ((System.currentTimeMillis() - lastTileChange) > 250)) { tilesWaitingToBeRendered.forEach(threeDeeRenderManager::renderTile); tilesWaitingToBeRendered.clear(); } // Collect rendered tiles Set<RenderResult> renderResults = threeDeeRenderManager.getRenderedTiles(); Rectangle repaintArea = null; for (RenderResult renderResult : renderResults) { Tile tile = renderResult.getTile(); int x = tile.getX(), y = tile.getY(); renderedTiles.put(tile, renderResult.getImage()); Rectangle tileBounds = zoom(getTileBounds(x, y)); if (repaintArea == null) { repaintArea = tileBounds; } else { repaintArea = repaintArea.union(tileBounds); } } if (repaintArea != null) { // System.out.println("Repainting " + repaintArea); repaint(repaintArea); } }
public BufferedImage getImage(ProgressReceiver progressReceiver) throws ProgressReceiver.OperationCancelled { Tile3DRenderer renderer = new Tile3DRenderer(dimension, colourScheme, biomeScheme, customBiomeManager, rotation); // Paint the complete image java.awt.Dimension preferredSize = unzoom(getPreferredSize()); BufferedImage image = new BufferedImage(preferredSize.width, preferredSize.height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); try { int tileCount = zSortedTiles.size(), tileNo = 0; for (Tile tile : zSortedTiles) { Rectangle tileBounds = getTileBounds(tile.getX(), tile.getY()); g2.drawImage(renderer.render(tile), tileBounds.x, tileBounds.y, null); if (progressReceiver != null) { tileNo++; progressReceiver.setProgress((float) tileNo / tileCount); } } } finally { g2.dispose(); } return image; }
@Override protected void paintComponent(Graphics g) { // System.out.println("Drawing"); Graphics2D g2 = (Graphics2D) g; if (zoom != 1) { double scaleFactor = Math.pow(2.0, zoom - 1); // System.out.println("Scaling with factor " + scaleFactor); g2.scale(scaleFactor, scaleFactor); if (zoom > 1) { g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); } else { g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); } } if (upsideDown) { g2.scale(1.0, -1.0); g2.translate(0, -getHeight()); } Rectangle visibleRect = unzoom(getVisibleRect()); // System.out.println("Unzoomed visible rectangle: " + visibleRect); int centerX = visibleRect.x + visibleRect.width / 2; int centerY = visibleRect.y + visibleRect.height / 2 + waterLevel; Tile mostCentredTile = null; int smallestDistance = Integer.MAX_VALUE; Rectangle clipBounds = g.getClipBounds(); for (Tile tile : zSortedTiles) { Rectangle tileBounds = getTileBounds(tile.getX(), tile.getY()); // System.out.print("Tile bounds: " + tileBounds); if (tileBounds.intersects(clipBounds)) { // System.out.println(" intersects"); int dx = tileBounds.x + tileBounds.width / 2 - centerX; int dy = tileBounds.y + tileBounds.height - TILE_SIZE / 2 - centerY; int dist = (int) Math.sqrt((dx * dx) + (dy * dy)); if (dist < smallestDistance) { smallestDistance = dist; mostCentredTile = tile; } BufferedImage tileImg = renderedTiles.get(tile); if (tileImg != null) { g.drawImage(tileImg, tileBounds.x, tileBounds.y, null); } else { tilesWaitingToBeRendered.add(0, tile); } // } else { // System.out.println(" does NOT intersect"); } } if (mostCentredTile != null) { centreTile = new Point(mostCentredTile.getX(), mostCentredTile.getY()); } if (highlightTile != null) { g.setColor(Color.RED); Rectangle rect = getTileBounds(highlightTile.x, highlightTile.y); g.drawRect(rect.x, rect.y, rect.width, rect.height); } if (highlightPoint != null) { g.setColor(Color.RED); g.drawLine(highlightPoint.x - 2, highlightPoint.y, highlightPoint.x + 2, highlightPoint.y); g.drawLine(highlightPoint.x, highlightPoint.y - 2, highlightPoint.x, highlightPoint.y + 2); } // for (Map.Entry<Point, BufferedImage> entry: renderedTiles.entrySet()) { // Point tileCoords = entry.getKey(); // BufferedImage tileImg = entry.getValue(); // Rectangle tileBounds = getTileBounds(tileCoords.x, tileCoords.y); // if (tileBounds.intersects(clipBounds)) { // g.drawImage(tileImg, tileBounds.x, tileBounds.y, null); //// g.setColor(Color.RED); //// g.drawRect(tileBounds.x, tileBounds.y, tileBounds.width, tileBounds.height); // } // } }