]> git.lizzy.rs Git - LightOverlay.git/blobdiff - common/src/main/java/me/shedaniel/lightoverlay/common/ChunkData.java
2.8.0 Cubic Chunk calculation, using glList during caching
[LightOverlay.git] / common / src / main / java / me / shedaniel / lightoverlay / common / ChunkData.java
diff --git a/common/src/main/java/me/shedaniel/lightoverlay/common/ChunkData.java b/common/src/main/java/me/shedaniel/lightoverlay/common/ChunkData.java
new file mode 100644 (file)
index 0000000..e4278a1
--- /dev/null
@@ -0,0 +1,131 @@
+package me.shedaniel.lightoverlay.common;
+
+import it.unimi.dsi.fastutil.longs.Long2ByteMap;
+import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.phys.shapes.CollisionContext;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import org.lwjgl.opengl.GL11;
+
+import java.io.Closeable;
+
+import static me.shedaniel.lightoverlay.common.LightOverlay.*;
+
+public class ChunkData implements Closeable {
+    private static final IllegalStateException WRONG_TYPE = new IllegalStateException("Wrong type accessed!");
+    private Long2ByteMap data;
+    private int glListIndex = 0;
+    private boolean generatedList = false;
+    
+    public ChunkData() {
+        this(new Long2ByteOpenHashMap());
+    }
+    
+    public ChunkData(Long2ByteMap data) {
+        this.data = data;
+    }
+    
+    public Long2ByteMap data() {
+        return data;
+    }
+    
+    private void compileList(Level level, CollisionContext collisionContext) {
+        generatedList = true;
+        
+        if (data().isEmpty()) {
+            glListIndex = 0;
+            return;
+        }
+        
+        glListIndex = GL11.glGenLists(3);
+        GL11.glNewList(glListIndex, GL11.GL_COMPILE);
+        GL11.glBegin(GL11.GL_LINES);
+        color(redColor);
+        
+        BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
+        for (Long2ByteMap.Entry objectEntry : data().long2ByteEntrySet()) {
+            byte crossType = objectEntry.getByteValue();
+            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+            if (crossType == CROSS_RED) {
+                renderCross(level, mutable, collisionContext);
+            }
+        }
+        
+        GL11.glEnd();
+        GL11.glEndList();
+        
+        GL11.glNewList(glListIndex + 1, GL11.GL_COMPILE);
+        GL11.glBegin(GL11.GL_LINES);
+        color(yellowColor);
+        
+        for (Long2ByteMap.Entry objectEntry : data().long2ByteEntrySet()) {
+            byte crossType = objectEntry.getByteValue();
+            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+            if (crossType == CROSS_YELLOW) {
+                renderCross(level, mutable, collisionContext);
+            }
+        }
+        
+        GL11.glEnd();
+        GL11.glEndList();
+        
+        GL11.glNewList(glListIndex + 2, GL11.GL_COMPILE);
+        GL11.glBegin(GL11.GL_LINES);
+        color(secondaryColor);
+        
+        for (Long2ByteMap.Entry objectEntry : data().long2ByteEntrySet()) {
+            byte crossType = objectEntry.getByteValue();
+            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+            if (crossType == CROSS_SECONDARY) {
+                renderCross(level, mutable, collisionContext);
+            }
+        }
+        
+        GL11.glEnd();
+        GL11.glEndList();
+    }
+    
+    public void renderList(Level level, CollisionContext collisionContext) {
+        if (!generatedList) {
+            compileList(level, collisionContext);
+        }
+        
+        if (glListIndex != 0) {
+            GL11.glCallList(glListIndex);
+            GL11.glCallList(glListIndex + 1);
+            GL11.glCallList(glListIndex + 2);
+        }
+    }
+    
+    private static void color(int color) {
+        int red = (color >> 16) & 255;
+        int green = (color >> 8) & 255;
+        int blue = color & 255;
+        GL11.glColor4f(red / 255f, green / 255f, blue / 255f, 1f);
+    }
+    
+    public static void renderCross(Level level, BlockPos pos, CollisionContext collisionContext) {
+        double blockOffset = 0;
+        VoxelShape upperOutlineShape = level.getBlockState(pos).getShape(level, pos, collisionContext);
+        if (!upperOutlineShape.isEmpty())
+            blockOffset += upperOutlineShape.max(Direction.Axis.Y);
+        
+        
+        int x = pos.getX();
+        int y = pos.getY();
+        int z = pos.getZ();
+        GL11.glVertex3d(x + .01, y + blockOffset, z + .01);
+        GL11.glVertex3d(x - .01 + 1, y + blockOffset, z - .01 + 1);
+        GL11.glVertex3d(x - .01 + 1, y + blockOffset, z + .01);
+        GL11.glVertex3d(x + .01, y + blockOffset, z - .01 + 1);
+    }
+    
+    @Override
+    public void close() {
+        if (glListIndex != 0) {
+            GL11.glDeleteLists(glListIndex, 3);
+        }
+    }
+}