]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java
Switch to using Blaze managed GL
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / renderers / AbstractRenderer.java
1 package com.irtimaled.bbor.client.renderers;
2
3 import com.irtimaled.bbor.client.config.ConfigManager;
4 import com.irtimaled.bbor.client.models.Point;
5 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
6 import net.minecraft.client.Minecraft;
7 import net.minecraft.client.gui.FontRenderer;
8
9 import java.awt.*;
10 import java.util.function.Supplier;
11
12 public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
13     private static final double TAU = 6.283185307179586D;
14     private static final double PI = TAU / 2D;
15
16     public abstract void render(T boundingBox);
17
18     void renderCuboid(OffsetBox bb, Color color) {
19         OffsetBox nudge = bb.nudge();
20         renderOutlinedCuboid(nudge, color);
21         renderFilledFaces(nudge.getMin(), nudge.getMax(), color);
22     }
23
24     void renderOutlinedCuboid(OffsetBox bb, Color color) {
25         RenderHelper.polygonModeLine();
26         OffsetPoint min = bb.getMin();
27         OffsetPoint max = bb.getMax();
28         renderFaces(min, max, color, 255, min.getY() == max.getY() ? Renderer::startLineLoop : Renderer::startLines);
29     }
30
31     private void renderFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha, Supplier<Renderer> rendererSupplier) {
32         double minX = min.getX();
33         double minY = min.getY();
34         double minZ = min.getZ();
35
36         double maxX = max.getX();
37         double maxY = max.getY();
38         double maxZ = max.getZ();
39
40         if (ConfigManager.invertBoxColorPlayerInside.get() &&
41                 playerInsideBoundingBox(minX, minY, minZ, maxX, maxY, maxZ)) {
42             color = new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue());
43         }
44
45         Renderer renderer = rendererSupplier.get()
46                 .setColor(color)
47                 .setAlpha(alpha);
48
49         if (minX != maxX && minZ != maxZ) {
50             renderer.addPoint(minX, minY, minZ)
51                     .addPoint(maxX, minY, minZ)
52                     .addPoint(maxX, minY, maxZ)
53                     .addPoint(minX, minY, maxZ);
54
55             if (minY != maxY) {
56                 renderer.addPoint(minX, maxY, minZ)
57                         .addPoint(maxX, maxY, minZ)
58                         .addPoint(maxX, maxY, maxZ)
59                         .addPoint(minX, maxY, maxZ);
60             }
61         }
62
63         if (minX != maxX && minY != maxY) {
64             renderer.addPoint(minX, minY, maxZ)
65                     .addPoint(minX, maxY, maxZ)
66                     .addPoint(maxX, maxY, maxZ)
67                     .addPoint(maxX, minY, maxZ);
68
69             if (minZ != maxZ) {
70                 renderer.addPoint(minX, minY, minZ)
71                         .addPoint(minX, maxY, minZ)
72                         .addPoint(maxX, maxY, minZ)
73                         .addPoint(maxX, minY, minZ);
74             }
75         }
76         if (minY != maxY && minZ != maxZ) {
77             renderer.addPoint(minX, minY, minZ)
78                     .addPoint(minX, minY, maxZ)
79                     .addPoint(minX, maxY, maxZ)
80                     .addPoint(minX, maxY, minZ);
81
82             if (minX != maxX) {
83                 renderer.addPoint(maxX, minY, minZ)
84                         .addPoint(maxX, minY, maxZ)
85                         .addPoint(maxX, maxY, maxZ)
86                         .addPoint(maxX, maxY, minZ);
87             }
88         }
89         renderer.render();
90     }
91
92     private boolean playerInsideBoundingBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
93         return minX < 0 && maxX > 0 && minY < 0 && maxY > 0 && minZ < 0 && maxZ > 0;
94     }
95
96     void renderLine(OffsetPoint startPoint, OffsetPoint endPoint, Color color) {
97         RenderHelper.polygonModeLine();
98         Renderer.startLines()
99                 .setColor(color)
100                 .addPoint(startPoint)
101                 .addPoint(endPoint)
102                 .render();
103     }
104
105     void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color) {
106         if (!ConfigManager.fill.get()) return;
107
108         RenderHelper.polygonModeFill();
109         RenderHelper.enableBlend();
110         renderFaces(min, max, color, 30, Renderer::startQuads);
111         RenderHelper.disableBlend();
112         RenderHelper.enablePolygonOffsetLine();
113         RenderHelper.polygonOffsetMinusOne();
114     }
115
116     void renderText(OffsetPoint offsetPoint, String... texts) {
117         FontRenderer fontRenderer = Minecraft.getInstance().fontRenderer;
118
119         RenderHelper.beforeRenderFont(offsetPoint);
120         float top = -(fontRenderer.FONT_HEIGHT * texts.length) / 2f;
121         for (String text : texts) {
122             float left = fontRenderer.getStringWidth(text) / 2f;
123             fontRenderer.drawString(text, -left, top, -1);
124             top += fontRenderer.FONT_HEIGHT;
125         }
126         RenderHelper.afterRenderFont();
127     }
128
129     void renderSphere(Point center, double radius, Color color) {
130         if (ConfigManager.renderSphereAsDots.get()) {
131             renderDotSphere(center, radius, color);
132         } else {
133             renderLineSphere(center, radius, color);
134         }
135     }
136
137     private void renderLineSphere(Point center, double radius, Color color) {
138         RenderHelper.lineWidth2();
139
140         double offset = ((radius - (int) radius) == 0) ? center.getY() - (int) center.getY() : 0;
141         for (double dy = offset - radius; dy <= radius + 1; dy++) {
142             double circleRadius = Math.sqrt((radius * radius) - (dy * dy));
143             if (circleRadius == 0) circleRadius = Math.sqrt(2) / 2;
144             renderCircle(center, circleRadius, color, dy + 0.001F);
145         }
146     }
147
148     private void renderCircle(Point center, double radius, Color color, double dy) {
149         Renderer renderer = Renderer.startLineLoop()
150                 .setColor(color);
151
152         for (int a = 0; a < 360; a += 5) {
153             double heading = a * PI / 180;
154             renderer.addPoint(new OffsetPoint(center.offset(Math.cos(heading) * radius, dy, Math.sin(heading) * radius)));
155         }
156
157         renderer.render();
158     }
159
160     private void renderDotSphere(Point center, double radius, Color color) {
161         RenderHelper.enablePointSmooth();
162         RenderHelper.pointSize5();
163         Renderer renderer = Renderer.startPoints()
164                 .setColor(color);
165
166         int segments = 64;
167         double thetaSegment = PI / (double) segments;
168         double phiSegment = TAU / (double) segments;
169
170         for (double phi = 0.0D; phi < TAU; phi += phiSegment) {
171             for (double theta = 0.0D; theta < PI; theta += thetaSegment) {
172                 double dx = radius * Math.sin(phi) * Math.cos(theta);
173                 double dz = radius * Math.sin(phi) * Math.sin(theta);
174                 double dy = radius * Math.cos(phi);
175
176                 renderer.addPoint(new OffsetPoint(center.offset(dx, dy, dz)));
177             }
178         }
179         renderer.render();
180     }
181 }