1 package com.irtimaled.bbor.client.renderers;
3 import com.irtimaled.bbor.client.Camera;
4 import com.irtimaled.bbor.client.models.Point;
5 import com.mojang.blaze3d.systems.RenderSystem;
6 import net.minecraft.client.render.BufferBuilder;
7 import net.minecraft.client.render.BufferRenderer;
8 import net.minecraft.client.render.GameRenderer;
9 import net.minecraft.client.render.VertexFormat;
10 import net.minecraft.client.render.VertexFormats;
11 import net.minecraft.client.util.math.MatrixStack;
12 import net.minecraft.util.math.Box;
15 import java.util.concurrent.atomic.AtomicLong;
17 public class RenderBatch {
19 private static final BufferBuilder quadBufferBuilderNonMasked = new BufferBuilder(2097152);
20 private static final BufferBuilder quadBufferBuilderMasked = new BufferBuilder(2097152);
21 private static final BufferBuilder lineBufferBuilder = new BufferBuilder(2097152);
23 private static final Object mutex = new Object();
24 private static final AtomicLong quadNonMaskedCount = new AtomicLong(0L);
25 private static final AtomicLong quadMaskedCount = new AtomicLong(0L);
26 private static final AtomicLong lineCount = new AtomicLong(0L);
27 private static final AtomicLong quadNonMaskedCountLast = new AtomicLong(0L);
28 private static final AtomicLong quadMaskedCountLast = new AtomicLong(0L);
29 private static final AtomicLong lineCountLast = new AtomicLong(0L);
31 private static final AtomicLong lastDurationNanos = new AtomicLong(0L);
33 static void beginBatch() {
34 quadBufferBuilderMasked.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
35 quadBufferBuilderNonMasked.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
36 lineBufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
39 public static void drawSolidBox(MatrixStack.Entry matrixEntry, Box box, Color color, int alpha, boolean mask, boolean sameX, boolean sameY, boolean sameZ) {
40 final float minX = (float) box.minX;
41 final float minY = (float) box.minY;
42 final float minZ = (float) box.minZ;
43 final float maxX = (float) box.maxX;
44 final float maxY = (float) box.maxY;
45 final float maxZ = (float) box.maxZ;
46 final int red = color.getRed();
47 final int green = color.getGreen();
48 final int blue = color.getBlue();
50 final BufferBuilder bufferBuilder = mask ? RenderBatch.quadBufferBuilderMasked : RenderBatch.quadBufferBuilderNonMasked;
52 if (!sameX && !sameZ) {
53 if (mask) quadMaskedCount.getAndIncrement();
54 else quadNonMaskedCount.getAndIncrement();
55 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, minY, minZ).color(red, green, blue, alpha).next();
56 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, minY, minZ).color(red, green, blue, alpha).next();
57 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
58 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, minY, maxZ).color(red, green, blue, alpha).next();
60 if (mask) quadMaskedCount.getAndIncrement();
61 else quadNonMaskedCount.getAndIncrement();
62 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, maxY, minZ).color(red, green, blue, alpha).next();
63 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
64 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
65 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
69 if (!sameX && !sameY) {
70 if (mask) quadMaskedCount.getAndIncrement();
71 else quadNonMaskedCount.getAndIncrement();
72 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, minY, minZ).color(red, green, blue, alpha).next();
73 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, maxY, minZ).color(red, green, blue, alpha).next();
74 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
75 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, minY, minZ).color(red, green, blue, alpha).next();
77 if (mask) quadMaskedCount.getAndIncrement();
78 else quadNonMaskedCount.getAndIncrement();
79 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, minY, maxZ).color(red, green, blue, alpha).next();
80 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
81 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
82 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
86 if (!sameY && !sameZ) {
87 if (mask) quadMaskedCount.getAndIncrement();
88 else quadNonMaskedCount.getAndIncrement();
89 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, minY, minZ).color(red, green, blue, alpha).next();
90 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, minY, maxZ).color(red, green, blue, alpha).next();
91 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
92 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), minX, maxY, minZ).color(red, green, blue, alpha).next();
94 if (mask) quadMaskedCount.getAndIncrement();
95 else quadNonMaskedCount.getAndIncrement();
96 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, minY, minZ).color(red, green, blue, alpha).next();
97 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
98 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
99 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
104 public static void drawFilledFace(MatrixStack.Entry matrixEntry, Point point1, Point point2, Point point3, Point point4, Color color, int alpha, boolean mask) {
105 int regionX = (((int) Camera.getX()) >> 9) * 512;
106 int regionZ = (((int) Camera.getZ()) >> 9) * 512;
108 if (mask) quadMaskedCount.getAndIncrement();
109 else quadNonMaskedCount.getAndIncrement();
111 final BufferBuilder bufferBuilder = mask ? RenderBatch.quadBufferBuilderMasked : RenderBatch.quadBufferBuilderNonMasked;
113 final float x1 = (float) point1.getX() - regionX;
114 final float y1 = (float) point1.getY();
115 final float z1 = (float) point1.getZ() - regionZ;
116 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x1, y1, z1).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
118 final float x2 = (float) point2.getX() - regionX;
119 final float y2 = (float) point2.getY();
120 final float z2 = (float) point2.getZ() - regionZ;
121 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x2, y2, z2).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
123 final float x3 = (float) point3.getX() - regionX;
124 final float y3 = (float) point3.getY();
125 final float z3 = (float) point3.getZ() - regionZ;
126 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x3, y3, z3).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
128 final float x4 = (float) point4.getX() - regionX;
129 final float y4 = (float) point4.getY();
130 final float z4 = (float) point4.getZ() - regionZ;
131 bufferBuilder.vertex(matrixEntry.getPositionMatrix(), x4, y4, z4).color(color.getRed(), color.getGreen(), color.getBlue(), alpha).next();
134 public static void drawLine(MatrixStack.Entry matrixEntry, Point startPoint, Point endPoint, Color color, int alpha) {
135 int regionX = (((int) Camera.getX()) >> 9) * 512;
136 int regionZ = (((int) Camera.getZ()) >> 9) * 512;
138 lineCount.getAndIncrement();
141 .vertex(matrixEntry.getPositionMatrix(),
142 (float) startPoint.getX() - regionX,
143 (float) startPoint.getY(),
144 (float) startPoint.getZ() - regionZ)
145 .color(color.getRed(), color.getGreen(), color.getBlue(), alpha)
148 .vertex(matrixEntry.getPositionMatrix(),
149 (float) endPoint.getX() - regionX,
150 (float) endPoint.getY(),
151 (float) endPoint.getZ() - regionZ)
152 .color(color.getRed(), color.getGreen(), color.getBlue(), alpha)
156 static void endBatch() {
157 RenderSystem.setShader(GameRenderer::getPositionColorShader);
158 long startTime = System.nanoTime();
159 quadBufferBuilderMasked.end();
160 quadBufferBuilderNonMasked.end();
161 lineBufferBuilder.end();
163 synchronized (mutex) {
164 quadMaskedCountLast.set(quadMaskedCount.get());
165 quadNonMaskedCountLast.set(quadNonMaskedCount.get());
166 lineCountLast.set(lineCount.get());
167 quadMaskedCount.set(0);
168 quadNonMaskedCount.set(0);
172 RenderSystem.depthMask(true);
173 BufferRenderer.draw(quadBufferBuilderMasked);
174 BufferRenderer.draw(lineBufferBuilder);
176 RenderSystem.depthMask(false);
177 BufferRenderer.draw(quadBufferBuilderNonMasked);
178 lastDurationNanos.set(System.nanoTime() - startTime);
180 RenderSystem.depthMask(true);
183 public static String debugString() {
184 return String.format("[BBOR] Statistics: Filled faces: %d+%d Lines: %d @ %.2fms", quadMaskedCountLast.get(), quadNonMaskedCountLast.get(), lineCountLast.get(), lastDurationNanos.get() / 1_000_000.0);