]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
Rewrite sphere renderer: filled faces and performance
authorishland <ishlandmc@yeah.net>
Sat, 26 Feb 2022 15:37:51 +0000 (23:37 +0800)
committerirtimaled <irtimaled@gmail.com>
Sat, 26 Feb 2022 18:33:12 +0000 (10:33 -0800)
src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/RenderBatch.java

index 94683d7030bc1fc1cecf76b062f941acac89d509..e879066d354c8436d2135f800273c145eaae198e 100644 (file)
@@ -7,6 +7,7 @@ import com.irtimaled.bbor.client.models.Point;
 import com.irtimaled.bbor.common.MathHelper;
 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
 import com.mojang.blaze3d.systems.RenderSystem;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.font.TextRenderer;
 import net.minecraft.client.render.GameRenderer;
@@ -124,48 +125,136 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
         if (ConfigManager.renderSphereAsDots.get()) {
             renderDotSphere(matrixStack, center, radius, color);
         } else {
-            renderLineSphere(matrixStack, center, radius, color);
+            renderFilledSphere(matrixStack, center, radius, color);
         }
     }
 
+    private void renderFilledSphere(MatrixStack matrixStack, Point center, double radius, Color color) {
+        if (ConfigManager.fastRender.get() >= 1 && !RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius)))
+            return;
+
+//        double offset = ((radius - (int) radius) == 0) ? center.getY() - (int) center.getY() : 0;
+
+        final ObjectArrayList<Point> top = new ObjectArrayList<>();
+        final ObjectArrayList<Point> bottom = new ObjectArrayList<>();
+        final Point topPoint = new Point(center.getX(), center.getY() + radius, center.getZ());
+        final Point bottomPoint = new Point(center.getX(), center.getY() - radius, center.getZ());
+        for (int i = 0; i < 360; i += 4) {
+            top.add(topPoint);
+            bottom.add(bottomPoint);
+        }
+
+//        double stepModifier = Math.min(32.0 / radius, 3.5D);
+
+//        int dyStep = radius < 64 ? 1 : MathHelper.floor(radius / 32);
+
+        final ObjectArrayList<ObjectArrayList<Point>> points = new ObjectArrayList<>();
+//        renderCircle(matrixStack, center, 0.1D, color, offset + radius, top);
+        points.add(bottom);
+        for (int i = -90; i <= 90; i += 4) {
+            double phi = Math.PI / 180 * i;
+            double dy = Math.sin(phi) * radius;
+            double circleRadius = Math.cos(phi) * radius;
+            if (circleRadius == 0) circleRadius = Math.sqrt(2) / 2;
+            final ObjectArrayList<Point> pointsCache = new ObjectArrayList<>();
+            renderCircle(matrixStack, center, circleRadius, color, dy + 0.001F, pointsCache);
+            points.add(pointsCache);
+        }
+//        for (double dy = offset + radius + 1; dy >= -radius; dy -= dyStep) {
+//            double circleRadius = Math.sqrt((radius * radius) - (dy * dy));
+//            if (circleRadius == 0) circleRadius = Math.sqrt(2) / 2;
+//            final ObjectArrayList<Point> pointsCache = new ObjectArrayList<>();
+//            renderCircle(matrixStack, center, circleRadius, color, dy + 0.001F, pointsCache);
+//            points.add(pointsCache);
+//        }
+//        renderCircle(matrixStack, center, 0.1D, color, offset - radius, bottom);
+        points.add(top);
+
+        matrixStack.push();
+
+        RenderHelper.applyRegionalRenderOffset(matrixStack);
+        RenderSystem.setShader(GameRenderer::getPositionShader);
+
+        final Boolean doFill = ConfigManager.fill.get();
+
+        for (int i = 0; i < points.size() - 1; i++) {
+            final ObjectArrayList<Point> pointsCache1 = points.get(i);
+            final ObjectArrayList<Point> pointsCache2 = points.get(i + 1);
+            assert pointsCache1.size() == pointsCache2.size();
+            Point lastPoint1 = null;
+            Point lastPoint2 = null;
+            for (int j = 0, pointsCacheSize = pointsCache1.size(); j < pointsCacheSize; j++) {
+                Point point1 = pointsCache1.get(j);
+                Point point2 = pointsCache2.get(j);
+                if (ConfigManager.fastRender.get() >= 1 && RenderCulling.isVisibleCulling(new OffsetBox(point1, point2).toBox()))
+                    RenderBatch.drawLine(matrixStack.peek(), point1, point2, color, 255);
+                if (doFill && lastPoint1 != null) {
+                    if (ConfigManager.fastRender.get() >= 1 && RenderCulling.isVisibleCulling(new OffsetBox(lastPoint1, point2).toBox()))
+                        RenderBatch.drawFilledFace(matrixStack.peek(), lastPoint1, lastPoint2, point2, point1, color, 127, false);
+                }
+                lastPoint1 = point1;
+                lastPoint2 = point2;
+            }
+            if (doFill && lastPoint1 != null) {
+                if (ConfigManager.fastRender.get() >= 1 && RenderCulling.isVisibleCulling(new OffsetBox(pointsCache1.get(0), lastPoint2).toBox()))
+                    RenderBatch.drawFilledFace(matrixStack.peek(), pointsCache1.get(0), pointsCache2.get(0), lastPoint2, lastPoint1, color, 127, false);
+            }
+        }
+
+        matrixStack.pop();
+    }
+
     private void renderLineSphere(MatrixStack matrixStack, Point center, double radius, Color color) {
-        if (ConfigManager.fastRender.get() >= 1 && !RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius))) return;
+        if (ConfigManager.fastRender.get() >= 1 && !RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius)))
+            return;
 
         double offset = ((radius - (int) radius) == 0) ? center.getY() - (int) center.getY() : 0;
         int dyStep = radius < 64 ? 1 : MathHelper.floor(radius / 32);
+        final ObjectArrayList<Point> pointsCache = new ObjectArrayList<>();
         for (double dy = offset - radius; dy <= radius + 1; dy += dyStep) {
             double circleRadius = Math.sqrt((radius * radius) - (dy * dy));
             if (circleRadius == 0) circleRadius = Math.sqrt(2) / 2;
-            renderCircle(matrixStack, center, circleRadius, color, dy + 0.001F);
+            renderCircle(matrixStack, center, circleRadius, color, dy + 0.001F, pointsCache);
+            pointsCache.clear();
         }
     }
 
-    private void renderCircle(MatrixStack matrixStack, Point center, double radius, Color color, double dy) {
+    private void renderCircle(MatrixStack matrixStack, Point center, double radius, Color color, double dy, ObjectArrayList<Point> cache) {
         matrixStack.push();
 
         RenderHelper.applyRegionalRenderOffset(matrixStack);
         RenderSystem.setShader(GameRenderer::getPositionShader);
 
-        Point firstPoint = null;
-        Point lastPoint = null;
-
-        for (double phi = 0.0D; phi < TAU; phi += PHI_SEGMENT) {
-            final Point point = center.offset(Math.cos(phi) * radius, dy, Math.sin(phi) * radius);
-            if (firstPoint == null) firstPoint = point;
-            if (lastPoint == null) {
-                lastPoint = point;
-                continue;
+        generateCircle(center, radius, dy, cache);
+        Point last = null;
+        //noinspection RedundantCast
+        for (Object _point : (Object[]) cache.elements()) {
+            if (_point != null) {
+                Point point = (Point) _point;
+                if (last != null) {
+                    RenderBatch.drawLine(matrixStack.peek(), last, point, color, 255);
+                }
+                last = point;
             }
-            RenderBatch.drawLine(matrixStack.peek(), lastPoint, point, color, 255);
-            lastPoint = point;
         }
-        RenderBatch.drawLine(matrixStack.peek(), lastPoint, firstPoint, color, 255);
+        if (last != null) {
+            RenderBatch.drawLine(matrixStack.peek(), last, cache.get(0), color, 255);
+        }
 
         matrixStack.pop();
     }
 
+    private void generateCircle(Point center, double radius, double dy, ObjectArrayList<Point> cache) {
+        for (int i = 0; i < 360; i += 4) {
+            double phi = Math.PI / 180 * i;
+            final Point point = center.offset(Math.cos(phi) * radius, dy, Math.sin(phi) * radius);
+            cache.add(point);
+        }
+    }
+
     private void renderDotSphere(MatrixStack matrixStack, Point center, double radius, Color color) {
-        if (ConfigManager.fastRender.get() >= 1 && !RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius))) return;
+        if (ConfigManager.fastRender.get() >= 1 && !RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius)))
+            return;
         matrixStack.push();
 
         for (double phi = 0.0D; phi < TAU; phi += PHI_SEGMENT) {
index 0d30a8cff86ab10359da4d89f8aff78361a4368e..42a679bfbb9ca7ffd5dcd8775be6dbb46dfda58e 100644 (file)
@@ -101,7 +101,37 @@ public class RenderBatch {
         }
     }
 
-    static void drawLine(MatrixStack.Entry matrixEntry, Point startPoint, Point endPoint, Color color, int alpha) {
+    public static void drawFilledFace(MatrixStack.Entry matrixEntry, Point point1, Point point2, Point point3, Point point4, Color color, int alpha, boolean mask) {
+        int regionX = (((int) Camera.getX()) >> 9) * 512;
+        int regionZ = (((int) Camera.getZ()) >> 9) * 512;
+
+        if (mask) quadMaskedCount.getAndIncrement();
+        else quadNonMaskedCount.getAndIncrement();
+
+        final BufferBuilder bufferBuilder = mask ? RenderBatch.quadBufferBuilderMasked : RenderBatch.quadBufferBuilderNonMasked;
+
+        final float x1 = (float) point1.getX() - regionX;
+        final float y1 = (float) point1.getY();
+        final float z1 = (float) point1.getZ() - regionZ;
+        bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x1, y1, z1).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
+
+        final float x2 = (float) point2.getX() - regionX;
+        final float y2 = (float) point2.getY();
+        final float z2 = (float) point2.getZ() - regionZ;
+        bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x2, y2, z2).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
+
+        final float x3 = (float) point3.getX() - regionX;
+        final float y3 = (float) point3.getY();
+        final float z3 = (float) point3.getZ() - regionZ;
+        bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x3, y3, z3).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
+
+        final float x4 = (float) point4.getX() - regionX;
+        final float y4 = (float) point4.getY();
+        final float z4 = (float) point4.getZ() - regionZ;
+        bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x4, y4, z4).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
+    }
+
+    public static void drawLine(MatrixStack.Entry matrixEntry, Point startPoint, Point endPoint, Color color, int alpha) {
         int regionX = (((int) Camera.getX()) >> 9) * 512;
         int regionZ = (((int) Camera.getZ()) >> 9) * 512;