diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java index 848612492..b59e1e8e7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java @@ -4,11 +4,12 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FastColor; +import net.minecraft.util.Mth; import net.minecraft.util.Tuple; import net.minecraft.world.phys.Vec2; -import java.awt.*; -import java.awt.image.BufferedImage; +import java.awt.geom.Line2D; import java.util.List; import java.util.*; import java.util.concurrent.*; @@ -86,46 +87,38 @@ private static Map registerTextures(String patTextureK } private static NativeImage drawLines(List points, HexPatternPoints staticPoints, float unscaledLineWidth, int resPerUnit) { - BufferedImage img = new BufferedImage((int)(staticPoints.fullWidth*resPerUnit), (int)(staticPoints.fullHeight*resPerUnit), BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = img.createGraphics(); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g2d.setColor(new Color(0xFF_FFFFFF)); // set it to white so we can reuse the texture with different colors - g2d.setStroke(new BasicStroke(unscaledLineWidth * resPerUnit, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + NativeImage nativeImage = new NativeImage((int)(staticPoints.fullWidth*resPerUnit), (int)(staticPoints.fullHeight*resPerUnit), true); for (int i = 0; i < points.size() - 1; i++) { Tuple pointFrom = getTextureCoordinates(points.get(i), staticPoints, resPerUnit); Tuple pointTo = getTextureCoordinates(points.get(i+1), staticPoints, resPerUnit); - g2d.drawLine(pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB()); + drawLine(nativeImage, pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB(), unscaledLineWidth * resPerUnit); } - g2d.dispose(); - NativeImage nativeImage = new NativeImage(img.getWidth(), img.getHeight(), true); - for (int y = 0; y < img.getHeight(); y++) - for (int x = 0; x < img.getWidth(); x++) - nativeImage.setPixelRGBA(x, y, img.getRGB(x, y)); return nativeImage; } + private static void drawLine(NativeImage image, int x0, int y0, int x1, int y1, float width) { + var line = new Line2D.Float(x0, y0, x1, y1); + var bounds = line.getBounds(); + double halfWidth = width / 2; + for (int x = (int) (bounds.x - width - 1); x < (int) (bounds.x + bounds.width + width + 1); x++) { + for (int y = (int) (bounds.y - width - 1); y < (int) (bounds.y + bounds.height + width + 1); y++) { + double dist = line.ptSegDist(x, y); + int alpha = (int) (Mth.clamp(halfWidth - dist + 0.5, 0, 1) * 255); + if (alpha > 0) { + int oldAlpha = FastColor.ARGB32.alpha(image.getPixelRGBA(x, y)); + int newAlpha = Math.max(oldAlpha, alpha); + image.setPixelRGBA(x, y, 0xFFFFFF | (newAlpha << 24)); + } + } + } + } + private static Tuple getTextureCoordinates(Vec2 point, HexPatternPoints staticPoints, int resPerUnit) { int x = (int) ( point.x * resPerUnit); int y = (int) ( point.y * resPerUnit); return new Tuple<>(x, y); } - // keeping this around just in case we ever decide to put the dots in the textures instead of dynamic - private static void drawHexagon(Graphics2D g2d, int x, int y, int radius) { - int fracOfCircle = 6; - Polygon hexagon = new Polygon(); - - for (int i = 0; i < fracOfCircle; i++) { - double theta = (i / (double) fracOfCircle) * Math.PI * 2; - int hx = (int) (x + Math.cos(theta) * radius); - int hy = (int) (y + Math.sin(theta) * radius); - hexagon.addPoint(hx, hy); - } - - g2d.fill(hexagon); - } - public static void repaint() { repaintIndex++; patternTexturesToAdd.clear();