]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
Add support for spawnable blocks rendering
[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.BoundingBoxVillage;
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(BoundingBoxVillage.class, new VillageRenderer());
43         registerRenderer(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
44         registerRenderer(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
45         registerRenderer(BoundingBoxCuboid.class, new CuboidRenderer());
46         registerRenderer(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
47         registerRenderer(BoundingBoxSpawningSphere.class, new SpawningSphereRenderer());
48         registerRenderer(BoundingBoxBeacon.class, new BeaconRenderer());
49         registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
50         registerRenderer(BoundingBoxConduit.class, new ConduitRenderer());
51         registerRenderer(BoundingBoxSpawnableBlocks.class, new SpawnableBlocksRenderer());
52
53         registerProvider(new SlimeChunkProvider());
54         registerProvider(new WorldSpawnProvider());
55         registerProvider(new SpawningSphereProvider());
56         registerProvider(new BeaconProvider());
57         registerProvider(new CustomBoxProvider());
58         registerProvider(new CustomBeaconProvider());
59         registerProvider(new BiomeBorderProvider());
60         registerProvider(new MobSpawnerProvider());
61         registerProvider(new ConduitProvider());
62         registerProvider(new SpawnableBlocksProvider());
63     }
64
65     public static <T extends AbstractBoundingBox> void registerProvider(IBoundingBoxProvider<T> provider) {
66         providers.add(provider);
67     }
68
69     public static <T extends AbstractBoundingBox> void registerRenderer(Class<? extends T> type, AbstractRenderer<T> renderer) {
70         boundingBoxRendererMap.put(type, renderer);
71     }
72
73     private static boolean isWithinRenderDistance(AbstractBoundingBox boundingBox) {
74         int renderDistanceBlocks = ClientInterop.getRenderDistanceChunks() * CHUNK_SIZE;
75         int minX = MathHelper.floor(Player.getX() - renderDistanceBlocks);
76         int maxX = MathHelper.floor(Player.getX() + renderDistanceBlocks);
77         int minZ = MathHelper.floor(Player.getZ() - renderDistanceBlocks);
78         int maxZ = MathHelper.floor(Player.getZ() + renderDistanceBlocks);
79
80         return boundingBox.intersectsBounds(minX, minZ, maxX, maxZ);
81     }
82
83     public static void render(int dimensionId) {
84         if (!active) return;
85
86         Set<AbstractBoundingBox> boundingBoxes = getBoundingBoxes(dimensionId);
87
88         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
89         GL11.glLineWidth(2.0f);
90         GL11.glDisable(GL11.GL_TEXTURE_2D);
91         GL11.glDisable(GL11.GL_CULL_FACE);
92
93         if (ConfigManager.alwaysVisible.get()) {
94             GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
95         }
96
97         for (AbstractBoundingBox key : boundingBoxes) {
98             AbstractRenderer renderer = boundingBoxRendererMap.get(key.getClass());
99             if (renderer == null) continue;
100
101             renderer.render(key);
102         }
103
104         GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
105         GL11.glEnable(GL11.GL_CULL_FACE);
106         GL11.glEnable(GL11.GL_TEXTURE_2D);
107     }
108
109     private static Set<AbstractBoundingBox> getBoundingBoxes(int dimensionId) {
110         Set<AbstractBoundingBox> boundingBoxes = new HashSet<>();
111         for (IBoundingBoxProvider<?> provider : providers) {
112             if (provider.canProvide(dimensionId)) {
113                 for (AbstractBoundingBox boundingBox : provider.get(dimensionId)) {
114                     if (isWithinRenderDistance(boundingBox)) {
115                         boundingBoxes.add(boundingBox);
116                     }
117                 }
118             }
119         }
120         return boundingBoxes;
121     }
122 }