]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blobdiff - src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java
Update to 1.17.1 (#124)
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / renderers / AbstractRenderer.java
index d7f220f4dde2caf1a6916fb5a31828b67cd89ffa..98e8a919938f9ad4c8a2feac336fbf56c885fbff 100644 (file)
@@ -1,15 +1,29 @@
 package com.irtimaled.bbor.client.renderers;
 
+import com.irtimaled.bbor.client.Camera;
+import com.irtimaled.bbor.client.RenderCulling;
 import com.irtimaled.bbor.client.config.ConfigManager;
 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 net.minecraft.client.MinecraftClient;
 import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gl.VertexBuffer;
+import net.minecraft.client.render.BufferBuilder;
+import net.minecraft.client.render.BufferRenderer;
+import net.minecraft.client.render.GameRenderer;
+import net.minecraft.client.render.Shader;
+import net.minecraft.client.render.Tessellator;
+import net.minecraft.client.render.VertexFormat;
+import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import net.minecraft.util.math.Matrix4f;
+import org.lwjgl.opengl.GL11;
 
 import java.awt.*;
-import java.util.function.Supplier;
 
 public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
     private static final double TAU = 6.283185307179586D;
@@ -17,125 +31,122 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
     private static final double PI = TAU / 2D;
     public static final double THETA_SEGMENT = PHI_SEGMENT / 2D;
 
-    public abstract void render(T boundingBox);
+    private final VertexBuffer solidBox = new VertexBuffer();
+    private final VertexBuffer outlinedBox = new VertexBuffer();
 
-    void renderCuboid(OffsetBox bb, Color color) {
-        OffsetBox nudge = bb.nudge();
-        renderOutlinedCuboid(nudge, color);
-        renderFilledFaces(nudge.getMin(), nudge.getMax(), color);
+    {
+        final Box box = new Box(BlockPos.ORIGIN);
+        RenderHelper.drawSolidBox(box, solidBox);
+        RenderHelper.drawOutlinedBox(box, outlinedBox);
     }
 
-    void renderOutlinedCuboid(OffsetBox bb, Color color) {
-        RenderHelper.polygonModeLine();
-        OffsetPoint min = bb.getMin();
-        OffsetPoint max = bb.getMax();
-        renderFaces(min, max, color, 255, min.getY() == max.getY() ? Renderer::startLineLoop : Renderer::startLines);
-    }
+    public abstract void render(MatrixStack matrixStack, T boundingBox);
+
+    void renderCuboid(MatrixStack matrixStack, OffsetBox bb, Color color, boolean fillOnly) {
+        OffsetBox nudge = bb.nudge();
+
+        GL11.glEnable(GL11.GL_LINE_SMOOTH);
+        GL11.glEnable(GL11.GL_CULL_FACE);
+        RenderHelper.polygonModeFill();
+        matrixStack.push();
 
-    private void renderFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha, Supplier<Renderer> rendererSupplier) {
-        double minX = min.getX();
-        double minY = min.getY();
-        double minZ = min.getZ();
+        RenderHelper.applyRegionalRenderOffset(matrixStack);
+        renderCuboid0(matrixStack, nudge, color, fillOnly);
 
-        double maxX = max.getX();
-        double maxY = max.getY();
-        double maxZ = max.getZ();
+        matrixStack.pop();
+        GL11.glDisable(GL11.GL_LINE_SMOOTH);
+        RenderSystem.setShaderColor(1, 1, 1, 1);
+    }
 
+    private void renderCuboid0(MatrixStack stack, OffsetBox nudge, Color color, boolean fillOnly) {
+        if (!RenderCulling.isVisibleCulling(nudge.toBox())) return;
         if (ConfigManager.invertBoxColorPlayerInside.get() &&
-                playerInsideBoundingBox(minX, minY, minZ, maxX, maxY, maxZ)) {
+                playerInsideBoundingBox(nudge)) {
             color = new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue());
         }
-
-        Renderer renderer = rendererSupplier.get()
-                .setColor(color)
-                .setAlpha(alpha);
-
-        if (minX != maxX && minZ != maxZ) {
-            renderer.addPoint(minX, minY, minZ)
-                    .addPoint(maxX, minY, minZ)
-                    .addPoint(maxX, minY, maxZ)
-                    .addPoint(minX, minY, maxZ);
-
-            if (minY != maxY) {
-                renderer.addPoint(minX, maxY, minZ)
-                        .addPoint(maxX, maxY, minZ)
-                        .addPoint(maxX, maxY, maxZ)
-                        .addPoint(minX, maxY, maxZ);
-            }
-        }
-
-        if (minX != maxX && minY != maxY) {
-            renderer.addPoint(minX, minY, maxZ)
-                    .addPoint(minX, maxY, maxZ)
-                    .addPoint(maxX, maxY, maxZ)
-                    .addPoint(maxX, minY, maxZ);
-
-            if (minZ != maxZ) {
-                renderer.addPoint(minX, minY, minZ)
-                        .addPoint(minX, maxY, minZ)
-                        .addPoint(maxX, maxY, minZ)
-                        .addPoint(maxX, minY, minZ);
-            }
+        stack.push();
+        int regionX = (((int) Camera.getX()) >> 9) << 9;
+        int regionZ = (((int) Camera.getZ()) >> 9) << 9;
+        RenderSystem.setShader(GameRenderer::getPositionShader);
+        stack.translate(nudge.getMin().getX() - regionX, nudge.getMin().getY(), nudge.getMin().getZ() - regionZ);
+        stack.scale((float) (nudge.getMax().getX() - nudge.getMin().getX()),
+                (float) (nudge.getMax().getY() - nudge.getMin().getY()),
+                (float) (nudge.getMax().getZ() - nudge.getMin().getZ()));
+
+        Matrix4f viewMatrix = stack.peek().getModel();
+        Matrix4f projMatrix = RenderSystem.getProjectionMatrix();
+        Shader shader = RenderSystem.getShader();
+        if (fillOnly || ConfigManager.fill.get()) {
+            RenderSystem.setShaderColor(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 30 / 255F);
+            solidBox.setShader(viewMatrix, projMatrix, shader);
         }
-        if (minY != maxY && minZ != maxZ) {
-            renderer.addPoint(minX, minY, minZ)
-                    .addPoint(minX, minY, maxZ)
-                    .addPoint(minX, maxY, maxZ)
-                    .addPoint(minX, maxY, minZ);
-
-            if (minX != maxX) {
-                renderer.addPoint(maxX, minY, minZ)
-                        .addPoint(maxX, minY, maxZ)
-                        .addPoint(maxX, maxY, maxZ)
-                        .addPoint(maxX, maxY, minZ);
-            }
+        if (!fillOnly) {
+            RenderSystem.setShaderColor(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 1F);
+            outlinedBox.setShader(viewMatrix, projMatrix, shader);
         }
-        renderer.render();
-    }
-
-    private boolean playerInsideBoundingBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
-        return minX < 0 && maxX > 0 && minY < 0 && maxY > 0 && minZ < 0 && maxZ > 0;
-    }
 
-    void renderLine(OffsetPoint startPoint, OffsetPoint endPoint, Color color) {
-        RenderHelper.polygonModeLine();
-        Renderer.startLines()
-                .setColor(color)
-                .addPoint(startPoint)
-                .addPoint(endPoint)
-                .render();
+        stack.pop();
     }
 
-    void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color) {
-        renderFilledFaces(min, max, color, 30);
+    private boolean playerInsideBoundingBox(OffsetBox nudge) {
+        return nudge.getMin().getX() < 0 && nudge.getMax().getX() > 0 &&
+                nudge.getMin().getY() < 0 && nudge.getMax().getY() > 0 &&
+                nudge.getMin().getZ() < 0 && nudge.getMax().getZ() > 0;
     }
 
-    void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) {
-        if (!ConfigManager.fill.get()) return;
-        RenderQueue.deferRendering(() -> renderFaces(min, max, color, alpha, Renderer::startQuads));
+    void renderLine(MatrixStack matrixStack, OffsetPoint startPoint, OffsetPoint endPoint, Color color) {
+        if (!RenderCulling.isVisibleCulling(new OffsetBox(startPoint, endPoint).toBox())) return; // TODO better culling
+        matrixStack.push();
+
+        RenderHelper.applyRegionalRenderOffset(matrixStack);
+        RenderSystem.setShader(GameRenderer::getPositionShader);
+        RenderSystem.setShaderColor(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 0.55f);
+        int regionX = (((int) Camera.getX()) >> 9) * 512;
+        int regionZ = (((int) Camera.getZ()) >> 9) * 512;
+
+        BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
+        bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES,
+                VertexFormats.POSITION);
+        bufferBuilder
+                .vertex(matrixStack.peek().getModel(),
+                        (float) startPoint.getX() - regionX,
+                        (float) startPoint.getY(),
+                        (float) startPoint.getZ() - regionZ)
+                .next();
+        bufferBuilder
+                .vertex(matrixStack.peek().getModel(),
+                        (float) endPoint.getX() - regionX,
+                        (float) endPoint.getY(),
+                        (float) endPoint.getZ() - regionZ)
+                .next();
+        bufferBuilder.end();
+        BufferRenderer.draw(bufferBuilder);
+
+        matrixStack.pop();
     }
 
-    void renderText(OffsetPoint offsetPoint, String... texts) {
+    void renderText(MatrixStack matrixStack, OffsetPoint offsetPoint, String... texts) {
         TextRenderer fontRenderer = MinecraftClient.getInstance().textRenderer;
-        RenderHelper.beforeRenderFont(offsetPoint);
+        RenderHelper.beforeRenderFont(matrixStack, offsetPoint);
         float top = -(fontRenderer.fontHeight * texts.length) / 2f;
         for (String text : texts) {
             float left = fontRenderer.getWidth(text) / 2f;
             fontRenderer.draw(new MatrixStack(), text, -left, top, -1);
             top += fontRenderer.fontHeight;
         }
-        RenderHelper.afterRenderFont();
+        RenderHelper.afterRenderFont(matrixStack);
     }
 
-    void renderSphere(Point center, double radius, Color color) {
+    void renderSphere(MatrixStack matrixStack, Point center, double radius, Color color) {
         if (ConfigManager.renderSphereAsDots.get()) {
-            renderDotSphere(center, radius, color);
+            renderDotSphere(matrixStack, center, radius, color);
         } else {
-            renderLineSphere(center, radius, color);
+            renderLineSphere(matrixStack, center, radius, color);
         }
     }
 
-    private void renderLineSphere(Point center, double radius, Color color) {
+    private void renderLineSphere(MatrixStack matrixStack, Point center, double radius, Color color) {
+        if (!RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius))) return;
         RenderHelper.lineWidth2();
 
         double offset = ((radius - (int) radius) == 0) ? center.getY() - (int) center.getY() : 0;
@@ -143,26 +154,58 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
         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(center, circleRadius, color, dy + 0.001F);
+            renderCircle(matrixStack, center, circleRadius, color, dy + 0.001F);
         }
     }
 
-    private void renderCircle(Point center, double radius, Color color, double dy) {
-        Renderer renderer = Renderer.startLineLoop()
-                .setColor(color);
+    private void renderCircle(MatrixStack matrixStack, Point center, double radius, Color color, double dy) {
+        matrixStack.push();
+
+        RenderHelper.applyRegionalRenderOffset(matrixStack);
+        RenderSystem.setShader(GameRenderer::getPositionShader);
+        RenderSystem.setShaderColor(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 0.55f);
+        int regionX = (((int) Camera.getX()) >> 9) * 512;
+        int regionZ = (((int) Camera.getZ()) >> 9) * 512;
+
+        BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
+        bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP,
+                VertexFormats.POSITION);
+
+        Point firstPoint = null;
 
         for (double phi = 0.0D; phi < TAU; phi += PHI_SEGMENT) {
-            renderer.addPoint(new OffsetPoint(center.offset(Math.cos(phi) * radius, dy, Math.sin(phi) * radius)));
+            final Point point = center.offset(Math.cos(phi) * radius, dy, Math.sin(phi) * radius);
+            if (firstPoint == null) firstPoint = point;
+            bufferBuilder.vertex(matrixStack.peek().getModel(),
+                    (float) point.getX() - regionX,
+                    (float) point.getY(),
+                    (float) point.getZ() - regionZ)
+                    .next();
         }
 
-        renderer.render();
+        bufferBuilder.vertex(matrixStack.peek().getModel(),
+                (float) firstPoint.getX() - regionX,
+                (float) firstPoint.getY(),
+                (float) firstPoint.getZ() - regionZ)
+                .next();
+
+        bufferBuilder.end();
+        BufferRenderer.draw(bufferBuilder);
+        matrixStack.pop();
     }
 
-    private void renderDotSphere(Point center, double radius, Color color) {
-        RenderHelper.enablePointSmooth();
-        RenderHelper.pointSize5();
-        Renderer renderer = Renderer.startPoints()
-                .setColor(color);
+    private void renderDotSphere(MatrixStack matrixStack, Point center, double radius, Color color) {
+        if (!RenderCulling.isVisibleCulling(new Box(new BlockPos(center.getX(), center.getY(), center.getZ())).expand(radius))) return;
+        matrixStack.push();
+        RenderHelper.applyRegionalRenderOffset(matrixStack);
+        RenderSystem.setShader(GameRenderer::getPositionShader);
+        RenderSystem.setShaderColor(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 0.55f);
+        int regionX = (((int) Camera.getX()) >> 9) * 512;
+        int regionZ = (((int) Camera.getZ()) >> 9) * 512;
+
+        BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
+        bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
+                VertexFormats.POSITION);
 
         for (double phi = 0.0D; phi < TAU; phi += PHI_SEGMENT) {
             double dy = radius * Math.cos(phi);
@@ -171,9 +214,17 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
                 double dx = radiusBySinPhi * Math.cos(theta);
                 double dz = radiusBySinPhi * Math.sin(theta);
 
-                renderer.addPoint(new OffsetPoint(center.offset(dx, dy, dz)));
+                final Point point = center.offset(dx, dy, dz);
+                bufferBuilder
+                        .vertex(matrixStack.peek().getModel(),
+                                (float) point.getX() - regionX,
+                                (float) point.getY(),
+                                (float) point.getZ() - regionZ)
+                        .next();
             }
         }
-        renderer.render();
+        bufferBuilder.end();
+        BufferRenderer.draw(bufferBuilder);
+        matrixStack.pop();
     }
 }