]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
c80ea92d1030bd7d6c550da4f7bbae450797eea8
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / ClientRenderer.java
1 package com.irtimaled.bbor.client;
2
3 import com.irtimaled.bbor.client.config.ConfigManager;
4 import com.irtimaled.bbor.client.interop.ClientInterop;
5 import com.irtimaled.bbor.client.models.*;
6 import com.irtimaled.bbor.client.providers.*;
7 import com.irtimaled.bbor.client.renderers.*;
8 import com.irtimaled.bbor.common.MathHelper;
9 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
10 import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
11 import com.irtimaled.bbor.common.models.DimensionId;
12 import org.lwjgl.opengl.GL11;
13
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Set;
18
19 public class ClientRenderer {
20     private static final int CHUNK_SIZE = 16;
21     private static final Map<Class<? extends AbstractBoundingBox>, AbstractRenderer> boundingBoxRendererMap = new HashMap<>();
22
23     private static boolean active;
24     private static final Set<IBoundingBoxProvider> providers = new HashSet<>();
25
26     public static boolean getActive() {
27         return active;
28     }
29
30     public static void toggleActive() {
31         active = !active;
32         if (!active) return;
33
34         Player.setActiveY();
35     }
36
37     static void deactivate() {
38         active = false;
39     }
40
41     static {
42         registerRenderer(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
43         registerRenderer(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
44         registerRenderer(BoundingBoxCuboid.class, new CuboidRenderer());
45         registerRenderer(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
46         registerRenderer(BoundingBoxSpawningSphere.class, new SpawningSphereRenderer());
47         registerRenderer(BoundingBoxBeacon.class, new BeaconRenderer());
48         registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
49         registerRenderer(BoundingBoxConduit.class, new ConduitRenderer());
50         registerRenderer(BoundingBoxSpawnableBlocks.class, new SpawnableBlocksRenderer());
51         registerRenderer(BoundingBoxLine.class, new LineRenderer());
52         registerRenderer(BoundingBoxSphere.class, new SphereRenderer());
53
54         registerProvider(new SlimeChunkProvider());
55         registerProvider(new WorldSpawnProvider());
56         registerProvider(new SpawningSphereProvider());
57         registerProvider(new BeaconProvider());
58         registerProvider(new CustomBoxProvider());
59         registerProvider(new CustomBeaconProvider());
60         registerProvider(new BiomeBorderProvider());
61         registerProvider(new MobSpawnerProvider());
62         registerProvider(new ConduitProvider());
63         registerProvider(new SpawnableBlocksProvider());
64         registerProvider(new CustomLineProvider());
65         registerProvider(new CustomSphereProvider());
66     }
67
68     public static <T extends AbstractBoundingBox> void registerProvider(IBoundingBoxProvider<T> provider) {
69         providers.add(provider);
70     }
71
72     public static <T extends AbstractBoundingBox> void registerRenderer(Class<? extends T> type, AbstractRenderer<T> renderer) {
73         boundingBoxRendererMap.put(type, renderer);
74     }
75
76     private static boolean isWithinRenderDistance(AbstractBoundingBox boundingBox) {
77         int renderDistanceBlocks = ClientInterop.getRenderDistanceChunks() * CHUNK_SIZE;
78         int minX = MathHelper.floor(Player.getX() - renderDistanceBlocks);
79         int maxX = MathHelper.floor(Player.getX() + renderDistanceBlocks);
80         int minZ = MathHelper.floor(Player.getZ() - renderDistanceBlocks);
81         int maxZ = MathHelper.floor(Player.getZ() + renderDistanceBlocks);
82
83         return boundingBox.intersectsBounds(minX, minZ, maxX, maxZ);
84     }
85
86     public static void render(DimensionId dimensionId) {
87         if (!active) return;
88
89         Set<AbstractBoundingBox> boundingBoxes = getBoundingBoxes(dimensionId);
90
91         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
92         GL11.glLineWidth(2.0f);
93         GL11.glDisable(GL11.GL_TEXTURE_2D);
94         GL11.glDisable(GL11.GL_CULL_FACE);
95         GL11.glEnable(GL11.GL_DEPTH_TEST);
96
97         if (ConfigManager.alwaysVisible.get()) {
98             GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
99         }
100
101         for (AbstractBoundingBox key : boundingBoxes) {
102             AbstractRenderer renderer = boundingBoxRendererMap.get(key.getClass());
103             if (renderer == null) continue;
104
105             renderer.render(key);
106         }
107
108         GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
109         GL11.glEnable(GL11.GL_CULL_FACE);
110         GL11.glEnable(GL11.GL_TEXTURE_2D);
111     }
112
113     private static Set<AbstractBoundingBox> getBoundingBoxes(DimensionId dimensionId) {
114         Set<AbstractBoundingBox> boundingBoxes = new HashSet<>();
115         for (IBoundingBoxProvider<?> provider : providers) {
116             if (provider.canProvide(dimensionId)) {
117                 for (AbstractBoundingBox boundingBox : provider.get(dimensionId)) {
118                     if (isWithinRenderDistance(boundingBox)) {
119                         boundingBoxes.add(boundingBox);
120                     }
121                 }
122             }
123         }
124         return boundingBoxes;
125     }
126 }