aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/makamys/lodmod
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/makamys/lodmod')
-rw-r--r--src/main/java/makamys/lodmod/LODMod.java239
-rw-r--r--src/main/java/makamys/lodmod/MixinConfigPlugin.java72
-rw-r--r--src/main/java/makamys/lodmod/ducks/IWorldRenderer.java13
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinChunkCache.java29
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java35
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinRenderBlocks.java29
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java40
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinRenderGlobal_OptiFine.java25
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java181
-rw-r--r--src/main/java/makamys/lodmod/renderer/ChunkMesh.java455
-rw-r--r--src/main/java/makamys/lodmod/renderer/FarChunkCache.java12
-rw-r--r--src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java14
-rw-r--r--src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java215
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODChunk.java184
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODRegion.java195
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODRenderer.java730
-rw-r--r--src/main/java/makamys/lodmod/renderer/Mesh.java44
-rw-r--r--src/main/java/makamys/lodmod/renderer/MeshQuad.java426
-rw-r--r--src/main/java/makamys/lodmod/renderer/SimpleChunkMesh.java350
-rw-r--r--src/main/java/makamys/lodmod/util/BufferWriter.java46
-rw-r--r--src/main/java/makamys/lodmod/util/GuiHelper.java61
-rw-r--r--src/main/java/makamys/lodmod/util/MCUtil.java20
-rw-r--r--src/main/java/makamys/lodmod/util/SpriteUtil.java55
-rw-r--r--src/main/java/makamys/lodmod/util/Util.java88
24 files changed, 0 insertions, 3558 deletions
diff --git a/src/main/java/makamys/lodmod/LODMod.java b/src/main/java/makamys/lodmod/LODMod.java
deleted file mode 100644
index 6b75d7d..0000000
--- a/src/main/java/makamys/lodmod/LODMod.java
+++ /dev/null
@@ -1,239 +0,0 @@
-package makamys.lodmod;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraft.client.renderer.entity.RenderManager;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.world.World;
-import net.minecraftforge.client.event.EntityViewRenderEvent;
-import net.minecraftforge.client.event.RenderGameOverlayEvent;
-import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.common.config.Configuration;
-import net.minecraftforge.event.world.ChunkEvent;
-import net.minecraftforge.event.world.WorldEvent;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-
-import cpw.mods.fml.common.FMLCommonHandler;
-import cpw.mods.fml.common.Mod;
-import cpw.mods.fml.common.Mod.EventHandler;
-import cpw.mods.fml.common.event.FMLInitializationEvent;
-import cpw.mods.fml.common.event.FMLPreInitializationEvent;
-import cpw.mods.fml.common.eventhandler.SubscribeEvent;
-import cpw.mods.fml.common.gameevent.TickEvent;
-import cpw.mods.fml.relauncher.Side;
-import cpw.mods.fml.relauncher.SideOnly;
-import makamys.lodmod.renderer.LODRenderer;
-import makamys.lodmod.util.SpriteUtil;
-
-@Mod(modid = LODMod.MODID, version = LODMod.VERSION)
-public class LODMod
-{
- public static final String MODID = "lodmod";
- public static final String VERSION = "0.0";
-
- public static final Logger LOGGER = LogManager.getLogger("lodmod");
-
- public static LODRenderer renderer;
-
- public static boolean enabled;
- public static int chunkLoadsPerTick;
- public static List<Class> blockClassBlacklist;
- public static double fogStart;
- public static double fogEnd;
- public static double farPlaneDistanceMultiplier;
- public static float maxSimpleMeshHeight;
- public static boolean forceVanillaBiomeTemperature;
- public static boolean hideUnderVanillaChunks;
- public static boolean disableChunkMeshes;
- public static boolean disableSimpleMeshes;
- public static boolean saveMeshes;
- public static boolean optimizeChunkMeshes;
- public static int maxMeshesPerFrame;
- public static int sortFrequency;
- public static int gcRate;
- public static int VRAMSize;
- public static int debugPrefix;
-
- private File configFile;
-
- public static boolean fogEventWasPosted;
-
- public static boolean ofFastRender;
- public static boolean enableFog;
-
- @EventHandler
- public void preInit(FMLPreInitializationEvent event)
- {
- configFile = event.getSuggestedConfigurationFile();
- reloadConfig();
- }
-
- private void reloadConfig() {
- Configuration config = new Configuration(configFile);
-
- config.load();
- enabled = config.get("General", "enabled", true).getBoolean();
- chunkLoadsPerTick = config.get("General", "chunkLoadsPerTick", 64).getInt();
- blockClassBlacklist = Arrays.stream(config.get("General", "blockClassBlacklist", "net.minecraft.block.BlockRotatedPillar;biomesoplenty.common.blocks.BlockBOPLog;gregapi.block.multitileentity.MultiTileEntityBlock").getString().split(";"))
- .map(className -> {
- try {
- return Class.forName(className);
- } catch (ClassNotFoundException e) {
- return null;
- }
- })
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
- fogStart = config.get("Fog", "fogStart", "0.4").getDouble();
- fogEnd = config.get("Fog", "fogEnd", "0.8").getDouble();
- farPlaneDistanceMultiplier = config.get("Fog", "farPlaneDistanceMultiplier", "1.0").getDouble();
-
- maxSimpleMeshHeight = (float)config.get("Debug", "maxSimpleMeshHeight", 1000.0).getDouble();
-
- forceVanillaBiomeTemperature = config.get("Simple mesh generation", "forceVanillaBiomeTemperature", true).getBoolean();
-
- hideUnderVanillaChunks = config.getBoolean("hideUnderVanillaChunks", "render", true, "");
- disableChunkMeshes = config.getBoolean("disableChunkMeshes", "render", true, "");
- disableSimpleMeshes = config.getBoolean("disableSimpleMeshes", "render", false, "");
- optimizeChunkMeshes = config.getBoolean("optimizeChunkMeshes", "render", true, "");
- saveMeshes = config.getBoolean("saveMeshes", "render", false, "");
- maxMeshesPerFrame = config.getInt("maxMeshesPerFrame", "render", -1, -1, Integer.MAX_VALUE, "");
- sortFrequency = config.getInt("sortFrequency", "render", 1, 1, Integer.MAX_VALUE, "");
- gcRate = config.getInt("gcRate", "render", 1, 1, Integer.MAX_VALUE, "Maximum number of meshes to relocate each frame.");
- VRAMSize = config.getInt("VRAMSize", "render", 1024, 1, Integer.MAX_VALUE, "VRAM buffer size (MB).");
- enableFog = config.getBoolean("enableFog", "render", true, "");
- debugPrefix = config.getInt("debugPrefix", "debug", Keyboard.KEY_F4, -1, Integer.MAX_VALUE, "This key has to be held down while pressing the debug keybinds. LWJGL keycode. Setting this to 0 will make the keybinds usable without holding anything else down. Setting this to -1 will disable debug keybinds entirely.");
-
- if(config.hasChanged()) {
- config.save();
- }
- }
-
- @EventHandler
- public void init(FMLInitializationEvent event)
- {
- FMLCommonHandler.instance().bus().register(this);
- MinecraftForge.EVENT_BUS.register(this);
- }
-
- private void onPlayerWorldChanged(World newWorld) {
- if(getRendererWorld() == null && newWorld != null) {
- reloadConfig();
- if(enabled) {
- SpriteUtil.init();
- }
- }
- if(renderer != null) {
- renderer.destroy();
- renderer = null;
- }
- if(enabled && newWorld != null) {
- renderer = new LODRenderer(newWorld);
- }
- }
-
- @SubscribeEvent
- @SideOnly(Side.CLIENT)
- public void onWorldUnload(WorldEvent.Unload event) {
- if(event.world == getRendererWorld()) {
- onPlayerWorldChanged(null);
- }
- }
-
- @SubscribeEvent
- public void onChunkLoad(ChunkEvent.Load event) {
- if(!event.world.isRemote) return;
-
- if(isActive()) {
- renderer.onChunkLoad(event);
- }
- }
-
- public static boolean isActive() {
- return renderer != null && renderer.hasInited && !renderer.destroyPending;
- }
-
- private World getRendererWorld() {
- return renderer != null ? renderer.world : null;
- }
-
- @SubscribeEvent
- public void onClientTick(TickEvent.ClientTickEvent event) {
- if(event.phase == TickEvent.Phase.START) {
- EntityPlayer player = Minecraft.getMinecraft().thePlayer;
- World world = player != null ? player.worldObj : null;
- if(world != getRendererWorld()) {
- onPlayerWorldChanged(world);
- }
-
- if(MixinConfigPlugin.isOptiFinePresent()) {
- try {
- ofFastRender = (boolean)Class.forName("Config").getMethod("isFastRender").invoke(null);
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
- | SecurityException | ClassNotFoundException e) {
- // oops
- }
- }
- }
- }
-
- @SubscribeEvent
- public void onServerTick(TickEvent.ServerTickEvent event) {
- if(event.phase == TickEvent.Phase.START) {
- if(isActive()) {
- renderer.serverTick();
- }
- }
- }
-
- @SubscribeEvent
- public void onRenderTick(TickEvent.RenderTickEvent event) {
- if(event.phase == TickEvent.Phase.END) {
- if(isActive()) {
- renderer.onRenderTickEnd();
- }
- }
- }
-
- @SubscribeEvent
- public void onRenderOverlay(RenderGameOverlayEvent event) {
- FontRenderer fontRenderer = RenderManager.instance.getFontRenderer();
- if(isActive() && event.type == ElementType.TEXT && fontRenderer != null && Minecraft.getMinecraft().gameSettings.showDebugInfo)
- {
- Minecraft mc = Minecraft.getMinecraft();
- ScaledResolution scaledresolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
- int w = scaledresolution.getScaledWidth();
- int h = scaledresolution.getScaledHeight();
-
- int yOffset = 0;
- for(String s : renderer.getDebugText()) {
- fontRenderer.drawStringWithShadow(s, w - fontRenderer.getStringWidth(s) - 10, 80 + yOffset, 0xFFFFFF);
- yOffset += 10;
- }
- }
- }
-
-
- @SubscribeEvent
- public void onRenderFog(EntityViewRenderEvent.RenderFogEvent event) {
- fogEventWasPosted = true;
- }
-
- public static boolean shouldRenderVanillaWorld() {
- return !isActive() || (isActive() && renderer.renderWorld && !renderer.rendererActive);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/MixinConfigPlugin.java b/src/main/java/makamys/lodmod/MixinConfigPlugin.java
deleted file mode 100644
index be8ac7c..0000000
--- a/src/main/java/makamys/lodmod/MixinConfigPlugin.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package makamys.lodmod;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import org.spongepowered.asm.lib.tree.ClassNode;
-import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
-import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
-
-public class MixinConfigPlugin implements IMixinConfigPlugin {
-
- private static boolean isOptiFinePresent = MixinConfigPlugin.class.getResource("/optifine/OptiFineTweaker.class") != null;
-
- @Override
- public void onLoad(String mixinPackage) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public String getRefMapperConfig() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
- return true;
- }
-
- @Override
- public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public List<String> getMixins() {
- List<String> mixins = new ArrayList<>();
- mixins.addAll(Arrays.asList("MixinChunkCache",
- "MixinEntityRenderer",
- "MixinRenderGlobal",
- "MixinWorldRenderer",
- "MixinRenderBlocks"));
-
- if (isOptiFinePresent()) {
- System.out.println("Detected OptiFine");
- mixins.add("MixinRenderGlobal_OptiFine");
- }
-
- return mixins;
- }
-
- @Override
- public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
- // TODO Auto-generated method stub
-
- }
-
- public static boolean isOptiFinePresent() {
- return isOptiFinePresent;
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/ducks/IWorldRenderer.java b/src/main/java/makamys/lodmod/ducks/IWorldRenderer.java
deleted file mode 100644
index 6527ba7..0000000
--- a/src/main/java/makamys/lodmod/ducks/IWorldRenderer.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package makamys.lodmod.ducks;
-
-import java.util.List;
-
-import org.spongepowered.asm.mixin.Mixin;
-
-import makamys.lodmod.renderer.ChunkMesh;
-import net.minecraft.client.renderer.WorldRenderer;
-
-public interface IWorldRenderer {
- public List<ChunkMesh> getChunkMeshes();
- public boolean isDrawn();
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java b/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java
deleted file mode 100644
index e989ddf..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package makamys.lodmod.mixin;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.renderer.FarChunkCache;
-import makamys.lodmod.renderer.LODRenderer;
-import net.minecraft.world.ChunkCache;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-
-@Mixin(ChunkCache.class)
-abstract class MixinChunkCache {
-
- @Redirect(method = "<init>*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getChunkFromChunkCoords(II)Lnet/minecraft/world/chunk/Chunk;"))
- private Chunk redirectGetChunkFromChunkCoords(World world, int p1, int p2) {
- Chunk chunk = world.getChunkFromChunkCoords(p1, p2);
- if(LODMod.isActive() && FarChunkCache.class.isInstance(this.getClass()) && chunk.isEmpty()) {
- Chunk myChunk = LODMod.renderer.getChunkFromChunkCoords(p1, p2);
- if(myChunk != null) {
- chunk = myChunk;
- }
- }
- return chunk;
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java b/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java
deleted file mode 100644
index 423fcd4..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package makamys.lodmod.mixin;
-
-import org.lwjgl.opengl.GL11;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import makamys.lodmod.LODMod;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.EntityRenderer;
-import net.minecraft.entity.EntityLivingBase;
-
-@Mixin(EntityRenderer.class)
-abstract class MixinEntityRenderer {
-
- @Shadow
- private float farPlaneDistance;
-
- @Inject(method = "setupCameraTransform", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/EntityRenderer;farPlaneDistance:F", shift = At.Shift.AFTER, ordinal = 1))
- private void onConstructed(CallbackInfo ci) {
- if(LODMod.isActive()) {
- farPlaneDistance *= LODMod.renderer.getFarPlaneDistanceMultiplier();
- }
- }
-
- @Inject(method = "setupFog", at = @At(value = "RETURN"))
- private void afterSetupFog(int mode, float alpha, CallbackInfo ci) {
- if(LODMod.isActive()) {
- LODMod.renderer.afterSetupFog(mode, alpha, farPlaneDistance);
- }
- }
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinRenderBlocks.java b/src/main/java/makamys/lodmod/mixin/MixinRenderBlocks.java
deleted file mode 100644
index 2812eff..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinRenderBlocks.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package makamys.lodmod.mixin;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-
-import cpw.mods.fml.relauncher.Side;
-import cpw.mods.fml.relauncher.SideOnly;
-import makamys.lodmod.LODMod;
-import makamys.lodmod.renderer.FarChunkCache;
-import net.minecraft.block.Block;
-import net.minecraft.client.renderer.RenderBlocks;
-import net.minecraft.world.IBlockAccess;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-
-@Mixin(RenderBlocks.class)
-abstract class MixinRenderBlocks {
-
- @Redirect(method = "renderBlockLiquid", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;shouldSideBeRendered(Lnet/minecraft/world/IBlockAccess;IIII)Z"))
- public boolean shouldSideBeRendered(Block block, IBlockAccess ba, int x, int y, int z, int w) {
- if(LODMod.isActive()) {
- return LODMod.renderer.shouldSideBeRendered(block, ba, x, y, z, w);
- } else {
- return block.shouldSideBeRendered(ba, x, y, z, w);
- }
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java b/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java
deleted file mode 100644
index 18f2177..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package makamys.lodmod.mixin;
-
-import java.nio.IntBuffer;
-
-import org.lwjgl.opengl.GL11;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.ModifyVariable;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import makamys.lodmod.LODMod;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.RenderGlobal;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.entity.Entity;
-
-@Mixin(RenderGlobal.class)
-abstract class MixinRenderGlobal {
-
- @Shadow
- private WorldRenderer[] sortedWorldRenderers;
-
- @Redirect(method = "renderSortedRenderers", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;renderAllRenderLists(ID)V"))
- private void redirectRenderAllRenderLists(RenderGlobal thiz, int p1, double p2) {
- if(LODMod.shouldRenderVanillaWorld()) {
- thiz.renderAllRenderLists(p1, p2);
- }
- }
-
- @Inject(method = "renderSortedRenderers", at = @At(value = "HEAD"))
- public void preRenderSortedRenderers(int startRenderer, int numRenderers, int renderPass, double partialTickTime, CallbackInfoReturnable cir) {
- if(LODMod.isActive()) {
- LODMod.renderer.preRenderSortedRenderers(renderPass, partialTickTime, sortedWorldRenderers);
- }
- }
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal_OptiFine.java b/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal_OptiFine.java
deleted file mode 100644
index 521bf1a..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal_OptiFine.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package makamys.lodmod.mixin;
-
-import java.nio.IntBuffer;
-
-import org.lwjgl.opengl.GL11;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-
-import makamys.lodmod.LODMod;
-import net.minecraft.client.renderer.RenderBlocks;
-import net.minecraft.client.renderer.RenderGlobal;
-
-@Mixin(RenderGlobal.class)
-abstract class MixinRenderGlobal_OptiFine {
-
- // for OptiFine's Fast Render option
- @Redirect(method = "renderSortedRenderersFast", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glCallLists(Ljava/nio/IntBuffer;)V"), remap=false)
- private void redirectRenderAllRenderLists(IntBuffer buffer) {
- if(LODMod.shouldRenderVanillaWorld()) {
- GL11.glCallLists(buffer);
- }
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java b/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
deleted file mode 100644
index 5753798..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package makamys.lodmod.mixin;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.lwjgl.opengl.GL11;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.ducks.IWorldRenderer;
-import makamys.lodmod.renderer.ChunkMesh;
-import makamys.lodmod.renderer.FarChunkCache;
-import makamys.lodmod.renderer.FarWorldRenderer;
-import makamys.lodmod.renderer.LODRenderer;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.entity.RenderItem;
-import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.util.AxisAlignedBB;
-import net.minecraft.world.ChunkCache;
-import net.minecraft.world.World;
-
-@Mixin(WorldRenderer.class)
-abstract class MixinWorldRenderer implements IWorldRenderer {
-
- @Shadow
- public int posX;
- @Shadow
- public int posY;
- @Shadow
- public int posZ;
-
- @Shadow
- private boolean isInFrustum;
- @Shadow
- public boolean[] skipRenderPass;
- @Shadow
- private int glRenderList;
-
- @Shadow
- public boolean needsUpdate;
-
- boolean savedDrawnStatus;
-
- public List<ChunkMesh> chunkMeshes;
-
- @Redirect(method = "setPosition", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/RenderItem;renderAABB(Lnet/minecraft/util/AxisAlignedBB;)V"))
- private void redirectRenderAABB(AxisAlignedBB p1) {
- if(!FarWorldRenderer.class.isInstance(this.getClass())) {
- RenderItem.renderAABB(p1);
- }
- }
-
- @Redirect(method = "updateRenderer", at = @At(value = "NEW", target = "Lnet/minecraft/world/ChunkCache;"))
- private ChunkCache redirectConstructChunkCache(World p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {
- if(!FarWorldRenderer.class.isInstance(this.getClass())) {
- return new ChunkCache(p1, p2, p3, p4, p5, p6, p7, p8);
- } else {
- return new FarChunkCache(p1, p2, p3, p4, p5, p6, p7, p8);
- }
- }
-
- @Inject(method = "updateRenderer", at = @At(value = "HEAD"))
- private void preUpdateRenderer(CallbackInfo ci) {
- saveDrawnStatus();
-
- if(LODMod.isActive()) {
- if(needsUpdate) {
- if(chunkMeshes != null) {
- chunkMeshes.clear();
- } else {
- chunkMeshes = new ArrayList<>();
- }
- } else {
- chunkMeshes = null;
- }
- }
- }
-
- @Inject(method = "updateRenderer", at = @At(value = "RETURN"))
- private void postUpdateRenderer(CallbackInfo ci) {
- notifyIfDrawnStatusChanged();
-
- if(LODMod.isActive()) {
- if(chunkMeshes != null) {
- LODMod.renderer.onWorldRendererPost(WorldRenderer.class.cast(this));
- chunkMeshes.clear();
- }
- }
- }
-
- @Inject(method = "postRenderBlocks", at = @At(value = "HEAD"))
- private void prePostRenderBlocks(int pass, EntityLivingBase entity, CallbackInfo ci) {
- if(LODMod.isActive() && !LODMod.disableChunkMeshes) {
- if(chunkMeshes != null) {
- chunkMeshes.add(ChunkMesh.fromTessellator(pass, WorldRenderer.class.cast(this), Tessellator.instance));
- }
- }
- }
-
- @Redirect(method = "postRenderBlocks", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/Tessellator;draw()I"))
- private int redirectPostRenderBlocksDraw() {
- if(!FarWorldRenderer.class.isInstance(this.getClass())) {
- return Tessellator.instance.draw();
- } else {
- Tessellator.instance.reset();
- return 0;
- }
- }
-
- // There's probably a nicer way to do this
-
- @Redirect(method = "postRenderBlocks", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glPopMatrix()V"))
- private void redirectPostRenderBlocksGL1() {
- if(!FarWorldRenderer.class.isInstance(this.getClass())) {
- GL11.glPopMatrix();
- }
- }
-
- @Redirect(method = "postRenderBlocks", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glEndList()V"))
- private void redirectPostRenderBlocksGL2() {
- if(!FarWorldRenderer.class.isInstance(this.getClass())) {
- GL11.glEndList();
- }
- }
-
- // XXX this is inconsistent, Forge callbacks are preserved in postRenderBlocks but not preRenderBlocks
-
- @Inject(method = "preRenderBlocks", at = @At(value = "HEAD"))
- private void preRenderBlocksInjector(CallbackInfo ci) {
- if(FarWorldRenderer.class.isInstance(this.getClass())) {
- Tessellator.instance.setTranslation((double)(-this.posX), (double)(-this.posY), (double)(-this.posZ));
- ci.cancel();
- }
- }
-
- @Inject(method = "setDontDraw", at = @At(value = "HEAD"))
- private void preSetDontDraw(CallbackInfo ci) {
- if(LODMod.isActive()) {
- LODMod.renderer.onWorldRendererChanged(WorldRenderer.class.cast(this), LODRenderer.WorldRendererChange.DELETED);
- }
- }
-
- @Override
- public List<ChunkMesh> getChunkMeshes() {
- return chunkMeshes;
- }
-
- @Inject(method = "updateInFrustum", at = @At(value = "HEAD"))
- private void preUpdateInFrustum(CallbackInfo ci) {
- saveDrawnStatus();
- }
-
- @Inject(method = "updateInFrustum", at = @At(value = "RETURN"))
- private void postUpdateInFrustum(CallbackInfo ci) {
- notifyIfDrawnStatusChanged();
- }
-
- private void saveDrawnStatus() {
- savedDrawnStatus = isDrawn();
- }
-
- private void notifyIfDrawnStatusChanged() {
- boolean drawn = isDrawn();
- if(LODMod.isActive() && drawn != savedDrawnStatus) {
- LODMod.renderer.onWorldRendererChanged(WorldRenderer.class.cast(this), drawn ? LODRenderer.WorldRendererChange.VISIBLE : LODRenderer.WorldRendererChange.INVISIBLE);
- }
- }
-
- @Override
- public boolean isDrawn() {
- return isInFrustum && (!skipRenderPass[0] || !skipRenderPass[1]);
- }
-}
diff --git a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java b/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
deleted file mode 100644
index f07a908..0000000
--- a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
+++ /dev/null
@@ -1,455 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.lwjgl.BufferUtils;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.MixinConfigPlugin;
-import makamys.lodmod.ducks.IWorldRenderer;
-import makamys.lodmod.util.BufferWriter;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.NBTBase;
-import net.minecraft.nbt.NBTTagByteArray;
-import net.minecraft.tileentity.TileEntity;
-
-public class ChunkMesh extends Mesh {
-
- Flags flags;
-
- // TODO move this somewhere else
- List<String> nameList = (List<String>) ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites.keySet().stream().collect(Collectors.toList());
-
- public static int usedRAM = 0;
- public static int instances = 0;
-
- public ChunkMesh(int x, int y, int z, Flags flags, int quadCount, ByteBuffer buffer, int pass) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.flags = flags;
- this.quadCount = quadCount;
- this.pass = pass;
-
- this.buffer = buffer;
- usedRAM += buffer.limit();
- instances++;
- }
-
- public ChunkMesh(int x, int y, int z, Flags flags, int quadCount, List<MeshQuad> quads, int pass) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.flags = flags;
- this.quadCount = quadCount;
- this.pass = pass;
-
- NBTBase nbtData = toNBT(quads, quadCount);
- buffer = createBuffer(((NBTTagByteArray)nbtData).func_150292_c(), nameList);
- usedRAM += buffer.limit();
- instances++;
- }
-
- private static int totalOriginalQuadCount = 0;
- private static int totalSimplifiedQuadCount = 0;
-
- public static ChunkMesh fromTessellator(int pass, WorldRenderer wr, Tessellator t) {
- if(t.vertexCount % 4 != 0) {
- System.out.println("Error: Vertex count is not a multiple of 4");
- return null;
- }
-
- int xOffset = wr.posX;
- int yOffset = wr.posY;
- int zOffset = wr.posZ;
-
- boolean fr = MixinConfigPlugin.isOptiFinePresent() && LODMod.ofFastRender;
- int tessellatorXOffset = fr ? xOffset : 0;
- int tessellatorYOffset = fr ? yOffset : 0;
- int tessellatorZOffset = fr ? zOffset : 0;
-
- boolean optimize = LODMod.optimizeChunkMeshes;
-
- ChunkMesh.Flags flags = new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals);
-
- if(optimize) {
- List<MeshQuad> quads = new ArrayList<>();
-
- for(int quadI = 0; quadI < t.vertexCount / 4; quadI++) {
- MeshQuad quad = new MeshQuad(t.rawBuffer, quadI * 32, flags, tessellatorXOffset, tessellatorYOffset, tessellatorZOffset);
- //if(quad.bUs[0] == quad.bUs[1] && quad.bUs[1] == quad.bUs[2] && quad.bUs[2] == quad.bUs[3] && quad.bUs[3] == quad.bVs[0] && quad.bVs[0] == quad.bVs[1] && quad.bVs[1] == quad.bVs[2] && quad.bVs[2] == quad.bVs[3] && quad.bVs[3] == 0) {
- // quad.deleted = true;
- //}
- if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) {
- // water hack
- quad.deleted = true;
- }
- quads.add(quad);
- }
-
- ArrayList<ArrayList<MeshQuad>> quadsByPlaneDir = new ArrayList<>(); // XY, XZ, YZ
- for(int i = 0; i < 3; i++) {
- quadsByPlaneDir.add(new ArrayList<MeshQuad>());
- }
- for(MeshQuad quad : quads) {
- if(quad.plane != MeshQuad.PLANE_NONE) {
- quadsByPlaneDir.get(quad.plane).add(quad);
- }
- }
- for(int plane = 0; plane < 3; plane++) {
- quadsByPlaneDir.get(plane).sort(MeshQuad.QuadPlaneComparator.quadPlaneComparators[plane]);
- }
-
- for(int plane = 0; plane < 3; plane++) {
- List<MeshQuad> planeDirQuads = quadsByPlaneDir.get(plane);
- int planeStart = 0;
- for(int quadI = 0; quadI < planeDirQuads.size(); quadI++) {
- MeshQuad quad = planeDirQuads.get(quadI);
- MeshQuad nextQuad = quadI == planeDirQuads.size() - 1 ? null : planeDirQuads.get(quadI + 1);
- if(!quad.onSamePlaneAs(nextQuad)) {
- simplifyPlane(planeDirQuads.subList(planeStart, quadI));
- planeStart = quadI + 1;
- }
- }
- }
-
- int quadCount = countValidQuads(quads);
-
- totalOriginalQuadCount += quads.size();
- totalSimplifiedQuadCount += quadCount;
- //System.out.println("simplified quads " + totalOriginalQuadCount + " -> " + totalSimplifiedQuadCount + " (ratio: " + ((float)totalSimplifiedQuadCount / (float)totalOriginalQuadCount) + ") totalMergeCountByPlane: " + Arrays.toString(totalMergeCountByPlane));
-
- if(quadCount > 0) {
- return new ChunkMesh(
- (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
- new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals),
- quadCount, quads, pass);
- } else {
- return null;
- }
- } else {
- int quadCount = t.vertexCount / 4;
- ByteBuffer buffer = BufferUtils.createByteBuffer(quadCount * 6 * 7 * 4);
- BufferWriter out = new BufferWriter(buffer);
-
- try {
- for(int i = 0; i < quadCount; i++) {
- writeBufferQuad(t, i * 32, out, -tessellatorXOffset + xOffset, -tessellatorYOffset + yOffset, -tessellatorZOffset + zOffset);
- }
- } catch(IOException e) {
- e.printStackTrace();
- }
- buffer.flip();
-
- if(quadCount > 0) {
- return new ChunkMesh(
- (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
- flags,
- quadCount, buffer, pass);
- } else {
- return null;
- }
- }
- }
-
- private static void writeBufferQuad(Tessellator t, int offset, BufferWriter out, float offsetX, float offsetY, float offsetZ) throws IOException {
- for(int vertexI = 0; vertexI < 6; vertexI++) {
-
- int vi = new int[]{0, 1, 2, 0, 2, 3}[vertexI];
-
- int i = offset + vi * 8;
-
- float x = Float.intBitsToFloat(t.rawBuffer[i + 0]) + offsetX;
- float y = Float.intBitsToFloat(t.rawBuffer[i + 1]) + offsetY;
- float z = Float.intBitsToFloat(t.rawBuffer[i + 2]) + offsetZ;
-
- out.writeFloat(x);
- out.writeFloat(y);
- out.writeFloat(z);
-
- float u = Float.intBitsToFloat(t.rawBuffer[i + 3]);
- float v = Float.intBitsToFloat(t.rawBuffer[i + 4]);
-
- out.writeFloat(u);
- out.writeFloat(v);
-
- int brightness = t.rawBuffer[i + 7];
- out.writeInt(brightness);
-
- int color = t.rawBuffer[i + 5];
- out.writeInt(color);
-
- i += 8;
- }
- }
-
- private static void simplifyPlane(List<MeshQuad> planeQuads) {
- MeshQuad lastQuad = null;
- // Pass 1: merge quads to create rows
- for(MeshQuad quad : planeQuads) {
- if(lastQuad != null) {
- lastQuad.tryToMerge(quad);
- }
- if(quad.isValid(quad)) {
- lastQuad = quad;
- }
- }
-
- // Pass 2: merge rows to create rectangles
- // TODO optimize?
- for(int i = 0; i < planeQuads.size(); i++) {
- for(int j = i + 1; j < planeQuads.size(); j++) {
- planeQuads.get(i).tryToMerge(planeQuads.get(j));
- }
- }
- }
-
- private static int countValidQuads(List<MeshQuad> quads) {
- int quadCount = 0;
- for(MeshQuad quad : quads) {
- if(!quad.deleted) {
- quadCount++;
- }
- }
- return quadCount;
- }
-
- private NBTBase toNBT(List<? extends MeshQuad> quads, int quadCount) {
- ByteArrayOutputStream byteOut = new ByteArrayOutputStream(quadCount * (2 + 4 * (3 + 2 + 2 + 4)));
- DataOutputStream out = new DataOutputStream(byteOut);
- try {
- for(int pass = 0; pass <= 9; pass++){
- for(MeshQuad quad : quads) {
- quad.writeToDisk(out, pass);
- }
- }
- } catch(IOException e) {}
-
- NBTTagByteArray arr = new NBTTagByteArray(byteOut.toByteArray());
- usedRAM += arr.func_150292_c().length;
- return arr;
- }
-
- void destroy() {
- if(buffer != null) {
- usedRAM -= buffer.limit();
- instances--;
- buffer = null;
-
- if(gpuStatus == Mesh.GPUStatus.SENT) {
- gpuStatus = Mesh.GPUStatus.PENDING_DELETE;
- }
- }
- }
-
- @Override
- public void destroyBuffer() {
- destroy();
- }
-
- private ByteBuffer createBuffer(byte[] data, List<String> stringTable) {
- if(!(flags.hasTexture && flags.hasColor && flags.hasBrightness && !flags.hasNormals)) {
- // for simplicity's sake we just assume this setup
- System.out.println("invalid mesh properties, expected a chunk");
- return null;
- }
- int coordsOffset = quadCount * 2;
- int textureOffset = quadCount * (2 + 4 + 4 + 4);
- int brightnessOffset = quadCount * (2 + 4 + 4 + 4 + 4 + 4);
- int colorOffset = quadCount * (2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
-
- ByteBuffer buffer = BufferUtils.createByteBuffer(quadCount * 6 * getStride());
- FloatBuffer floatBuffer = buffer.asFloatBuffer();
- ShortBuffer shortBuffer = buffer.asShortBuffer();
- IntBuffer intBuffer = buffer.asIntBuffer();
-
- try {
- for(int quadI = 0; quadI < quadCount; quadI++) {
- short spriteIndex = readShortAt(data, quadI * 2);
- String spriteName = stringTable.get(spriteIndex);
-
- TextureAtlasSprite tas = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).getAtlasSprite(spriteName);
-
- for (int vertexNum = 0; vertexNum < 6; vertexNum++) {
- int vi = new int[]{0, 1, 3, 1, 2, 3}[vertexNum];
- int vertexI = 4 * quadI + vi;
- int offset = vertexI * getStride();
- int simpleX = Byte.toUnsignedInt(data[coordsOffset + 0 * 4 * quadCount + 4 * quadI + vi]);
- if(simpleX == 255) simpleX = 256;
- int simpleY = Byte.toUnsignedInt(data[coordsOffset + 1 * 4 * quadCount + 4 * quadI + vi]);
- if(simpleY == 255) simpleY = 256;
- int simpleZ = Byte.toUnsignedInt(data[coordsOffset + 2 * 4 * quadCount + 4 * quadI + vi]);
- if(simpleZ == 255) simpleZ = 256;
- floatBuffer.put(x * 16 + simpleX / 16f); // x
- floatBuffer.put(y * 16 + simpleY / 16f); // y
- floatBuffer.put(z * 16 + simpleZ / 16f); // z
-
- byte relU = data[textureOffset + 0 * 4 * quadCount + 4 * quadI + vi];
- byte relV = data[textureOffset + 1 * 4 * quadCount + 4 * quadI + vi];
-
- floatBuffer.put(tas.getMinU() + (tas.getMaxU() - tas.getMinU()) * (relU / 16f)); // u
- floatBuffer.put(tas.getMinV() + (tas.getMaxV() - tas.getMinV()) * (relV / 16f)); // v
-
- shortBuffer.position(floatBuffer.position() * 2);
-
- shortBuffer.put((short)Byte.toUnsignedInt(data[brightnessOffset + 0 * 4 * quadCount + 4 * quadI + vi])); // bU
- shortBuffer.put((short)Byte.toUnsignedInt(data[brightnessOffset + 1 * 4 * quadCount + 4 * quadI + vi])); // bV
-
- intBuffer.position(shortBuffer.position() / 2);
-
- int integet = readIntAt(data, colorOffset + 4 * 4 * quadI + 4 * vi);
- intBuffer.put(integet); // c
-
- floatBuffer.position(intBuffer.position());
- }
- }
- } catch(Exception e) {
- e.printStackTrace();
- }
-
- buffer.position(floatBuffer.position() * 4);
- buffer.flip();
-
- usedRAM += buffer.limit();
-
- return buffer;
- }
-
- public void update() {
- }
-
- // Java is weird.
- public static short readShortAt(DataInputStream in, int offset) {
- try {
- in.reset();
- in.skip(offset);
- return in.readShort();
- } catch(IOException e) {
- return -1;
- }
- }
-
- public static short readShortAt(byte[] data, int offset) {
- return (short)(Byte.toUnsignedInt(data[offset]) << 8 | Byte.toUnsignedInt(data[offset + 1]));
- }
-
- public static int readIntAt(DataInputStream in, int offset) {
- try {
- in.reset();
- in.skip(offset);
- return in.readInt();
- } catch(IOException e) {
- return -1;
- }
- }
-
- public static int readIntAt(byte[] data, int offset) {
- return (int)(Byte.toUnsignedLong(data[offset]) << 24 | Byte.toUnsignedLong(data[offset + 1]) << 16 | Byte.toUnsignedLong(data[offset + 2]) << 8 | Byte.toUnsignedLong(data[offset + 3]));
- }
-
- public int getStride() {
- return (3 * 4 + (flags.hasTexture ? 8 : 0) + (flags.hasBrightness ? 4 : 0) + (flags.hasColor ? 4 : 0) + (flags.hasNormals ? 4 : 0));
- }
-
- static void saveChunks(List<Integer> coords) {
- System.out.println("saving " + (coords.size() / 3) + " cchunks");
- for(int i = 0; i < coords.size(); i += 3) {
- if(i % 300 == 0) {
- System.out.println((i / 3) + " / " + (coords.size() / 3));
- }
- int theX = coords.get(i);
- int theY = coords.get(i + 1);
- int theZ = coords.get(i + 2);
-
- WorldRenderer wr = new WorldRenderer(Minecraft.getMinecraft().theWorld, new ArrayList<TileEntity>(), theX * 16, theY * 16, theZ * 16, 100000);
- /*
- if (this.occlusionEnabled)
- {
- this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].glOcclusionQuery = this.glOcclusionQueryBase.get(var3);
- }*/
-
- wr.isWaitingOnOcclusionQuery = false;
- wr.isVisible = true;
- wr.isInFrustum = true;
- wr.chunkIndex = 0;
- wr.markDirty();
- wr.updateRenderer(Minecraft.getMinecraft().thePlayer);
- }
- //Tessellator.endSave();
- }
-
- static List<ChunkMesh> getChunkMesh(int theX, int theY, int theZ) {
- WorldRenderer wr = new WorldRenderer(Minecraft.getMinecraft().theWorld, new ArrayList<TileEntity>(), theX * 16, theY * 16, theZ * 16, 100000);
-
- wr.isWaitingOnOcclusionQuery = false;
- wr.isVisible = true;
- wr.isInFrustum = true;
- wr.chunkIndex = 0;
- wr.markDirty();
- wr.updateRenderer(Minecraft.getMinecraft().thePlayer);
- return ((IWorldRenderer)wr).getChunkMeshes();
- }
-
- public double distSq(Entity player) {
- int centerX = x * 16 + 8;
- int centerY = y * 16 + 8;
- int centerZ = z * 16 + 8;
-
- return player.getDistanceSq(centerX, centerY, centerZ);
- }
-
- public static class Flags {
- boolean hasTexture;
- boolean hasBrightness;
- boolean hasColor;
- boolean hasNormals;
-
- public Flags(byte flags) {
- hasTexture = (flags & 1) != 0;
- hasBrightness = (flags & 2) != 0;
- hasColor = (flags & 4) != 0;
- hasNormals = (flags & 8) != 0;
- }
-
- public Flags(boolean hasTexture, boolean hasBrightness, boolean hasColor, boolean hasNormals) {
- this.hasTexture = hasTexture;
- this.hasBrightness = hasBrightness;
- this.hasColor = hasColor;
- this.hasNormals = hasNormals;
- }
-
- public byte toByte() {
- byte flags = 0;
- if(hasTexture) {
- flags |= 1;
- }
- if(hasBrightness) {
- flags |= 2;
- }
- if(hasColor) {
- flags |= 4;
- }
- if(hasNormals) {
- flags |= 8;
- }
- return flags;
- }
- }
-
-}
-
diff --git a/src/main/java/makamys/lodmod/renderer/FarChunkCache.java b/src/main/java/makamys/lodmod/renderer/FarChunkCache.java
deleted file mode 100644
index f4e3cca..0000000
--- a/src/main/java/makamys/lodmod/renderer/FarChunkCache.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package makamys.lodmod.renderer;
-
-import net.minecraft.world.ChunkCache;
-import net.minecraft.world.World;
-
-public class FarChunkCache extends ChunkCache {
-
- public FarChunkCache(World p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {
- super(p1, p2, p3, p4, p5, p6, p7, p8);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java b/src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java
deleted file mode 100644
index 72eb4fd..0000000
--- a/src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.util.List;
-
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.world.World;
-
-public class FarWorldRenderer extends WorldRenderer {
-
- public FarWorldRenderer(World p1, List p2, int p3, int p4, int p5, int p6) {
- super(p1, p2, p3, p4, p5, p6);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java b/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java
deleted file mode 100644
index 19d4dbe..0000000
--- a/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package makamys.lodmod.renderer;
-
-import static org.lwjgl.opengl.GL15.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.renderer.Mesh.GPUStatus;
-import makamys.lodmod.util.GuiHelper;
-
-public class GPUMemoryManager {
-
- private int bufferSize;
-
- public int VBO;
-
- private int nextMesh;
-
- private List<Mesh> sentMeshes = new ArrayList<>();
-
- public GPUMemoryManager() {
- VBO = glGenBuffers();
-
- bufferSize = LODMod.VRAMSize * 1024 * 1024;
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
-
- glBufferData(GL_ARRAY_BUFFER, bufferSize, GL_DYNAMIC_DRAW);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- public void runGC(boolean full) {
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
-
- int moved = 0;
- int timesReachedEnd = 0;
- int checksLeft = sentMeshes.size();
-
- while((!full && (moved < 4 && checksLeft-- > 0)) || (full && timesReachedEnd < 2) && !sentMeshes.isEmpty()) {
- nextMesh++;
- if(nextMesh >= sentMeshes.size()) {
- nextMesh = 0;
- timesReachedEnd++;
- }
- Mesh mesh = sentMeshes.get(nextMesh);
-
- if(mesh.gpuStatus == GPUStatus.SENT) {
- int offset = nextMesh == 0 ? 0 : sentMeshes.get(nextMesh - 1).getEnd();
- if(mesh.offset != offset) {
- glBufferSubData(GL_ARRAY_BUFFER, offset, mesh.buffer);
- moved++;
- }
- mesh.iFirst = offset / mesh.getStride();
- mesh.offset = offset;
- } else if(mesh.gpuStatus == GPUStatus.PENDING_DELETE) {
- mesh.iFirst = mesh.offset = -1;
- mesh.visible = false;
- mesh.gpuStatus = GPUStatus.UNSENT;
-
- sentMeshes.remove(nextMesh);
-
- mesh.destroyBuffer();
-
- if(nextMesh > 0) {
- nextMesh--;
- }
- }
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- private int malloc(int size) {
- int nextBase = 0;
- if(!sentMeshes.isEmpty()) {
- if(nextMesh < sentMeshes.size() - 1) {
- Mesh next = sentMeshes.get(nextMesh);
- Mesh nextnext = sentMeshes.get(nextMesh + 1);
- if(nextnext.offset - next.getEnd() >= size) {
- return next.getEnd();
- }
- }
-
- nextBase = sentMeshes.get(sentMeshes.size() - 1).getEnd();
- }
-
- if(nextBase + size >= bufferSize) {
- return -1;
- } else {
- return nextBase;
- }
- }
-
- private int end() {
- return (sentMeshes.isEmpty() ? 0 : sentMeshes.get(sentMeshes.size() - 1).getEnd());
- }
-
- public void sendMeshToGPU(Mesh mesh) {
- if(mesh == null || mesh.buffer == null) {
- return;
- }
-
- if(end() + mesh.bufferSize() >= bufferSize) {
- runGC(true);
- }
-
- if(end() + mesh.bufferSize() >= bufferSize) {
- System.out.println("VRAM is full! Try increasing the allocated VRAM in the config, if possible. Reverting to vanilla renderer.");
- LODMod.renderer.destroyPending = true;
- // TODO restart renderer with more VRAM allocated when this happens.
- return;
- }
-
- int size = mesh.bufferSize();
- int insertIndex = -1;
-
- int nextBase = -1;
- if(!sentMeshes.isEmpty()) {
- if(nextMesh < sentMeshes.size() - 1) {
- Mesh next = sentMeshes.get(nextMesh);
- Mesh nextnext = null;
- for(int i = nextMesh + 1; i < sentMeshes.size(); i++) {
- Mesh m = sentMeshes.get(i);
- if(m.gpuStatus == Mesh.GPUStatus.SENT) {
- nextnext = m;
- break;
- }
- }
- if(nextnext != null && nextnext.offset - next.getEnd() >= size) {
- nextBase = next.getEnd();
- insertIndex = nextMesh + 1;
- }
- }
-
- if(nextBase == -1) {
- nextBase = sentMeshes.get(sentMeshes.size() - 1).getEnd();
- }
- }
- if(nextBase == -1) nextBase = 0;
-
-
- if(mesh.gpuStatus == GPUStatus.UNSENT) {
- mesh.prepareBuffer();
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
-
- glBufferSubData(GL_ARRAY_BUFFER, nextBase, mesh.buffer);
- mesh.iFirst = nextBase / mesh.getStride();
- mesh.iCount = mesh.quadCount * 6;
- mesh.offset = nextBase;
-
- if(insertIndex == -1) {
- sentMeshes.add(mesh);
- } else {
- sentMeshes.add(insertIndex, mesh);
- nextMesh = insertIndex;
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- mesh.gpuStatus = GPUStatus.SENT;
- }
-
- public void deleteMeshFromGPU(Mesh mesh) {
- if(mesh == null || mesh.gpuStatus == GPUStatus.UNSENT) {
- return;
- }
- mesh.gpuStatus = GPUStatus.PENDING_DELETE;
- }
-
- public void destroy() {
- glDeleteBuffers(VBO);
- }
-
- public List<String> getDebugText() {
- return Arrays.asList("VRAM: " + (end() / 1024 / 1024) + "MB / " + (bufferSize / 1024 / 1024) + "MB");
- }
-
- public void drawInfo() {
- int scale = 10000;
- int rowLength = 512;
- int yOff = 20;
-
- int height = (bufferSize / scale) / rowLength;
- GuiHelper.drawRectangle(0, yOff, rowLength, height, 0x000000, 50);
-
- int meshI = 0;
- for(Mesh mesh : sentMeshes) {
-
- int o = mesh.offset / 10000;
- int o2 = (mesh.offset + mesh.bufferSize()) / 10000;
- if(o / rowLength == o2 / rowLength) {
- if(mesh.gpuStatus != Mesh.GPUStatus.PENDING_DELETE) {
- GuiHelper.drawRectangle(o % rowLength, o / rowLength + yOff, mesh.buffer.limit() / scale + 1, 1, meshI == nextMesh ? 0x00FF00 : 0xFFFFFF);
- }
- } else {
- for(int i = o; i < o2; i++) {
- int x = i % rowLength;
- int y = i / rowLength;
- if(mesh.gpuStatus != Mesh.GPUStatus.PENDING_DELETE) {
- GuiHelper.drawRectangle(x, y + yOff, 1, 1, 0xFFFFFF);
- }
- }
- }
- meshI++;
- }
- GuiHelper.drawRectangle(0 % rowLength, 0 + yOff, 4, 4, 0x00FF00);
- GuiHelper.drawRectangle((bufferSize / scale) % rowLength, (bufferSize / scale) / rowLength + yOff, 4, 4, 0xFF0000);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/LODChunk.java b/src/main/java/makamys/lodmod/renderer/LODChunk.java
deleted file mode 100644
index 2c5d61c..0000000
--- a/src/main/java/makamys/lodmod/renderer/LODChunk.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.util.List;
-
-import makamys.lodmod.LODMod;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagEnd;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.world.chunk.Chunk;
-
-public class LODChunk {
-
- int x, z;
- public boolean needsChunk = true;
- int lod = 0;
- boolean visible;
- boolean dirty;
- boolean discardedMesh;
-
- SimpleChunkMesh[] simpleMeshes = new SimpleChunkMesh[2];
- ChunkMesh[] chunkMeshes = new ChunkMesh[32];
-
- public boolean[] isSectionVisible = new boolean[16];
-
- LODRenderer renderer = LODMod.renderer;
-
- public LODChunk(int x, int z) {
- this.x = x;
- this.z = z;
- }
- /*
- public LODChunk(NBTTagCompound nbt, List<String> spriteList) {
- this.x = nbt.getInteger("x");
- this.z = nbt.getInteger("z");
-
- loadChunkMeshesNBT(nbt.getCompoundTag("chunkMeshes"), spriteList);
- }
-
- private void loadChunkMeshesNBT(NBTTagCompound chunkMeshesCompound, List<String> spriteList) {
- for(Object o : chunkMeshesCompound.func_150296_c()) {
- String key = (String)o;
- int keyInt = Integer.parseInt(key);
-
- byte[] data = chunkMeshesCompound.getByteArray(key);
-
- chunkMeshes[keyInt] = new ChunkMesh(x, keyInt / 2, z, new ChunkMesh.Flags(true, true, true, false), data.length / (2 + 4 * (3 + 2 + 2 + 4)), data, spriteList, keyInt % 2);
- }
- }
- */
- @Override
- public String toString() {
- return "LODChunk(" + x + ", " + z + ")";
- }
-
- public double distSq(Entity entity) {
- return Math.pow(entity.posX - x * 16, 2) + Math.pow(entity.posZ - z * 16, 2);
- }
-
- public void putChunkMeshes(int cy, List<ChunkMesh> newChunkMeshes) {
- for(int i = 0; i < 2; i++) {
- ChunkMesh newChunkMesh = newChunkMeshes.size() > i ? newChunkMeshes.get(i) : null;
- if(chunkMeshes[cy * 2 + i] != null) {
- if(newChunkMesh != null) {
- newChunkMesh.pass = i;
- }
-
- renderer.removeMesh(chunkMeshes[cy * 2 + i]);
- chunkMeshes[cy * 2 + i].destroy();
- }
- chunkMeshes[cy * 2 + i] = newChunkMesh;
- }
- LODMod.renderer.lodChunkChanged(this);
- dirty = true;
- discardedMesh = false;
- }
-
- // nice copypasta
- public void putSimpleMeshes(List<SimpleChunkMesh> newSimpleMeshes) {
- for(int i = 0; i < 2; i++) {
- SimpleChunkMesh newSimpleMesh = newSimpleMeshes.size() > i ? newSimpleMeshes.get(i) : null;
- if(simpleMeshes[i] != null) {
- if(newSimpleMesh != null) {
- newSimpleMesh.pass = i;
- }
-
- renderer.setMeshVisible(simpleMeshes[i], false);
- simpleMeshes[i].destroy();
- }
- simpleMeshes[i] = newSimpleMesh;
- }
- LODMod.renderer.lodChunkChanged(this);
- }
-
- public boolean hasChunkMeshes() {
- for(ChunkMesh cm : chunkMeshes) {
- if(cm != null) {
- return true;
- }
- }
- return false;
- }
-
- public void tick(Entity player) {
- double distSq = distSq(player);
- if(LODMod.disableSimpleMeshes || distSq < Math.pow((LODMod.renderer.renderRange / 2) * 16, 2)) {
- setLOD(2);
- } else if(distSq < Math.pow((LODMod.renderer.renderRange) * 16, 2)) {
- setLOD(1);
- } else {
- setLOD(0);
- }
- }
-
- public void setLOD(int lod) {
- if(lod == this.lod) return;
-
- this.lod = lod;
- LODMod.renderer.lodChunkChanged(this);
- if(!dirty) {
- if(lod < 2) {
- for(int i = 0; i < chunkMeshes.length; i++) {
- if(chunkMeshes[i] != null) {
- chunkMeshes[i].destroy();
- chunkMeshes[i] = null;
- discardedMesh = true;
- }
- }
- }
- }
- }
- /*
- public NBTTagCompound saveToNBT(NBTTagCompound oldNbt, List<String> oldStringTable) {
- NBTTagCompound nbt = new NBTTagCompound();
- nbt.setInteger("x", x);
- nbt.setInteger("z", z);
-
- NBTTagCompound chunkMeshesCompound = oldNbt == null ? new NBTTagCompound() : oldNbt.getCompoundTag("chunkMeshes");
- if(!discardedMesh) {
- for(int i = 0; i < chunkMeshes.length; i++) {
- if(chunkMeshes[i] != null) {
- chunkMeshesCompound.setTag(String.valueOf(i), chunkMeshes[i].nbtData);
- }
- }
- } else if(oldNbt != null && discardedMesh && lod == 2) {
- loadChunkMeshesNBT(chunkMeshesCompound, oldStringTable);
- LODMod.renderer.lodChunkChanged(this);
- }
- nbt.setTag("chunkMeshes", chunkMeshesCompound);
- dirty = false;
- return nbt;
- }
- */
- public void destroy() {
- for(SimpleChunkMesh scm: simpleMeshes) {
- if(scm != null) {
- scm.destroy();
- }
- }
- for(ChunkMesh cm: chunkMeshes) {
- if(cm != null) {
- cm.destroy();
- }
- }
- LODMod.renderer.setVisible(this, false);
- }
-
- public void receiveChunk(Chunk chunk) {
- if(!LODMod.disableSimpleMeshes) {
- putSimpleMeshes(SimpleChunkMesh.generateSimpleMeshes(chunk));
- }
- }
-
- public boolean isFullyVisible() {
- if(!visible) return false;
- for(boolean b : isSectionVisible) {
- if(!b) {
- return false;
- }
- }
- return true;
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/LODRegion.java b/src/main/java/makamys/lodmod/renderer/LODRegion.java
deleted file mode 100644
index 9fdaa89..0000000
--- a/src/main/java/makamys/lodmod/renderer/LODRegion.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.io.BufferedOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import makamys.lodmod.LODMod;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.CompressedStreamTools;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.world.chunk.Chunk;
-import net.minecraftforge.common.util.Constants.NBT;
-
-public class LODRegion {
-
- private LODChunk[][] data = new LODChunk[32][32];
-
- int regionX, regionZ;
-
- public LODRegion(int regionX, int regionZ) {
- this.regionX = regionX;
- this.regionZ = regionZ;
-
- for(int i = 0; i < 32; i++) {
- for(int j = 0; j < 32; j++) {
- data[i][j] = new LODChunk(regionX * 32 + i, regionZ * 32 + j);
- }
- }
- }
- /*
- public LODRegion(int regionX, int regionZ, NBTTagCompound nbt) {
- this.regionX = regionX;
- this.regionZ = regionZ;
-
- NBTTagList list = nbt.getTagList("chunks", NBT.TAG_COMPOUND);
- List<String> stringTable = Arrays.asList(nbt.getString("stringTable").split("\\n"));
-
- int idx = 0;
- for(int i = 0; i < 32; i++) {
- for(int j = 0; j < 32; j++) {
- data[i][j] = new LODChunk(list.getCompoundTagAt(idx++), stringTable);
- if(data[i][j].hasChunkMeshes()) {
- LODMod.renderer.setVisible(data[i][j], true);
- }
- }
- }
- }
- */
- public static LODRegion load(Path saveDir, int regionX, int regionZ) {
- /*if(!(LODMod.disableChunkMeshes || !LODMod.saveMeshes)) {
- File saveFile = getSavePath(saveDir, regionX, regionZ).toFile();
- if(saveFile.exists()) {
- try {
- NBTTagCompound nbt = CompressedStreamTools.readCompressed(new FileInputStream(saveFile));
- return new LODRegion(regionX, regionZ, nbt);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }*/
- return new LODRegion(regionX, regionZ);
- }
- /*
- private static Path getSavePath(Path saveDir, int regionX, int regionZ) {
- return saveDir.resolve("lod").resolve(regionX + "," + regionZ + ".lod");
- }
-
- public void save(Path saveDir) {
- if(LODMod.disableChunkMeshes || !LODMod.saveMeshes) return;
-
- try {
- File saveFile = getSavePath(saveDir, regionX, regionZ).toFile();
- saveFile.getParentFile().mkdirs();
-
- NBTTagCompound oldNbt = null;
- NBTTagList oldList = null;
- List<String> oldStringTable = null;
- if(saveFile.exists()) {
- oldNbt = CompressedStreamTools.readCompressed(new FileInputStream(saveFile));
- oldList = oldNbt.getTagList("chunks", NBT.TAG_COMPOUND);;
- oldStringTable = Arrays.asList(oldNbt.getString("stringTable").split("\\n"));
- }
-
- NBTTagCompound nbt = new NBTTagCompound();
- nbt.setByte("V", (byte)0);
- nbt.setString("stringTable", String.join("\n", (List<String>) ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites.keySet().stream().collect(Collectors.toList())));
-
- NBTTagList list = new NBTTagList();
-
- int idx = 0;
- for(int i = 0; i < 32; i++) {
- for(int j = 0; j < 32; j++) {
- list.appendTag(data[i][j].saveToNBT(oldNbt == null ? null : oldList.getCompoundTagAt(idx++),
- oldNbt == null? null : oldStringTable));
- }
- }
- nbt.setTag("chunks", list);
-
- new Thread(
- new Runnable() {
-
- @Override
- public void run() {
- try {
- CompressedStreamTools.writeCompressed(nbt, new FileOutputStream(saveFile));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }).start();
-
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- */
- public LODChunk getChunkAbsolute(int chunkXAbs, int chunkZAbs) {
- return getChunk(chunkXAbs - regionX * 32, chunkZAbs - regionZ * 32);
- }
-
- public LODChunk getChunk(int x, int z) {
- if(x >= 0 && x < 32 && z >= 0 && z < 32) {
- return data[x][z];
- } else {
- return null;
- }
- }
-
- public LODChunk putChunk(Chunk chunk) {
- int relX = chunk.xPosition - regionX * 32;
- int relZ = chunk.zPosition - regionZ * 32;
-
- if(relX >= 0 && relX < 32 && relZ >= 0 && relZ < 32) {
- data[relX][relZ].receiveChunk(chunk);
- return data[relX][relZ];
- }
- return null;
- }
-
- public boolean tick(Entity player) {
- int visibleChunks = 0;
- for(int i = 0; i < 32; i++) {
- for(int j = 0; j < 32; j++) {
- LODChunk chunk = data[i][j];
- if(chunk != null) {
- chunk.tick(player);
- if(chunk.visible) {
- visibleChunks++;
- }
- }
- }
- }
- return visibleChunks > 0;
- }
-
- public void destroy(Path saveDir) {
- //save(saveDir);
- for(int i = 0; i < 32; i++) {
- for(int j = 0; j < 32; j++) {
- LODChunk chunk = data[i][j];
- if(chunk != null) {
- chunk.destroy();
- }
- }
- }
- }
-
- public double distanceTaxicab(Entity entity) {
- double centerX = ((regionX * 32) + 16) * 16;
- double centerZ = ((regionZ * 32) + 16) * 16;
-
- return Math.max(Math.abs(centerX - entity.posX), Math.abs(centerZ - entity.posZ));
-
- }
-
- @Override
- public String toString() {
- return "LODRegion(" + regionX + ", " + regionZ + ")";
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/LODRenderer.java b/src/main/java/makamys/lodmod/renderer/LODRenderer.java
deleted file mode 100644
index 3420c34..0000000
--- a/src/main/java/makamys/lodmod/renderer/LODRenderer.java
+++ /dev/null
@@ -1,730 +0,0 @@
-package makamys.lodmod.renderer;
-
-import net.minecraft.block.Block;
-import net.minecraft.block.material.Material;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.particle.EntityFX;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.util.EnumFacing;
-import net.minecraft.world.ChunkCoordIntPair;
-import net.minecraft.world.IBlockAccess;
-import net.minecraft.world.World;
-import net.minecraft.world.biome.BiomeGenBase;
-import net.minecraft.world.chunk.Chunk;
-import net.minecraft.world.gen.ChunkProviderServer;
-import net.minecraftforge.event.world.ChunkEvent;
-
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.lwjgl.BufferUtils;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.util.vector.Matrix4f;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.ducks.IWorldRenderer;
-import makamys.lodmod.renderer.Mesh.GPUStatus;
-import makamys.lodmod.util.GuiHelper;
-import makamys.lodmod.util.Util;
-
-import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL14.*;
-import static org.lwjgl.opengl.GL15.*;
-import static org.lwjgl.opengl.GL20.*;
-import static org.lwjgl.opengl.GL30.*;
-
-public class LODRenderer {
-
- public boolean hasInited = false;
- public boolean destroyPending;
-
- private boolean[] wasDown = new boolean[256];
- private int renderQuads = 0;
-
- public boolean renderWorld;
- public boolean rendererActive;
- private boolean showMemoryDebugger;
-
- private static int MAX_MESHES = 100000;
-
- private int VAO, shaderProgram;
- private IntBuffer[] piFirst = new IntBuffer[2];
- private IntBuffer[] piCount = new IntBuffer[2];
- private List<Mesh>[] sentMeshes = (List<Mesh>[])new ArrayList[] {new ArrayList<Mesh>(), new ArrayList<Mesh>()};
- GPUMemoryManager mem;
-
- List<Chunk> myChunks = new ArrayList<Chunk>();
- List<LODChunk> pendingLODChunks = new ArrayList<>();
-
- private boolean hasServerInited = false;
- private Map<ChunkCoordIntPair, LODRegion> loadedRegionsMap = new HashMap<>();
-
- public World world;
-
- // TODO make these packets to make this work on dedicated servers
- Queue<Chunk> farChunks = new ConcurrentLinkedQueue<>();
-
- List<ChunkCoordIntPair> serverChunkLoadQueue = new ArrayList<>();
-
- private double lastSortX = Double.NaN;
- private double lastSortY = Double.NaN;
- private double lastSortZ = Double.NaN;
-
- private long lastGCTime = -1;
- private long lastSaveTime = -1;
- private long gcInterval = 10 * 1000;
- private long saveInterval = 60 * 1000;
-
- private int renderedMeshes;
- private int frameCount;
-
- public int renderRange = 48;
-
- private boolean freezeMeshes;
-
- public LODRenderer(World world){
- this.world = world;
- if(shouldRenderInWorld(world)) {
- hasInited = init();
- }
-
- renderWorld = true;
- rendererActive = true;
- }
-
- public void preRenderSortedRenderers(int renderPass, double alpha, WorldRenderer[] sortedWorldRenderers) {
- if(renderPass != 0) return;
-
- LODMod.fogEventWasPosted = false;
-
- renderedMeshes = 0;
-
- Minecraft.getMinecraft().entityRenderer.enableLightmap((double)alpha);
-
- if(hasInited) {
- mainLoop();
- if(Minecraft.getMinecraft().currentScreen == null) {
- handleKeyboard();
- }
- if(frameCount % 2 == 0) {
- mem.runGC(false);
- }
- lastGCTime = System.currentTimeMillis();
- if(lastSaveTime == -1 || (System.currentTimeMillis() - lastSaveTime) > saveInterval && LODMod.saveMeshes) {
- onSave();
- lastSaveTime = System.currentTimeMillis();
- }
-
- if(rendererActive && renderWorld) {
- if(frameCount % LODMod.sortFrequency == 0) {
- sort();
- }
-
- updateMeshes();
- initIndexBuffers();
- render(alpha);
- }
- }
-
- frameCount++;
-
- Minecraft.getMinecraft().entityRenderer.disableLightmap((double)alpha);
- }
-
- public void onRenderTickEnd() {
- if(destroyPending) {
- LODMod.renderer = null;
- return;
- }
- if(showMemoryDebugger && mem != null) {
- GuiHelper.begin();
- mem.drawInfo();
- GuiHelper.end();
- }
- }
-
- private void sort() {
- Entity player = Minecraft.getMinecraft().renderViewEntity;
- for(List<Mesh> list : sentMeshes) {
- list.sort(new MeshDistanceComparator(player.posX / 16, player.posY / 16, player.posZ / 16));
- }
- }
-
- private void updateMeshes() {
- for(List<Mesh> list : sentMeshes) {
- for(Mesh mesh : list) {
- mesh.update();
- }
- }
- }
-
- private void initIndexBuffers() {
- for(int i = 0; i < 2; i++) {
- piFirst[i].limit(sentMeshes[i].size());
- piCount[i].limit(sentMeshes[i].size());
- for(Mesh mesh : sentMeshes[i]) {
- if(mesh.visible && (LODMod.maxMeshesPerFrame == -1 || renderedMeshes < LODMod.maxMeshesPerFrame)) {
- renderedMeshes++;
- piFirst[i].put(mesh.iFirst);
- piCount[i].put(mesh.iCount);
- }
- }
- piFirst[i].flip();
- piCount[i].flip();
- }
- }
-
- private void mainLoop() {
- while(!farChunks.isEmpty()) {
- LODChunk lodChunk = receiveFarChunk(farChunks.remove());
- sendChunkToGPU(lodChunk);
- }
-
- if(Minecraft.getMinecraft().playerController.netClientHandler.doneLoadingTerrain) {
- Entity player = Minecraft.getMinecraft().renderViewEntity;
-
- List<ChunkCoordIntPair> newServerChunkLoadQueue = new ArrayList<>();
-
- if(Double.isNaN(lastSortX) || getLastSortDistanceSq(player) > 16 * 16) {
- int centerX = (int)Math.floor(player.posX / 16.0);
- int centerZ = (int)Math.floor(player.posZ / 16.0);
-
- for(int x = -renderRange; x <= renderRange; x++) {
- for(int z = -renderRange; z <= renderRange; z++) {
- if(x * x + z * z < renderRange * renderRange) {
- int chunkX = centerX + x;
- int chunkZ = centerZ + z;
-
- if(getLODChunk(chunkX, chunkZ).needsChunk) {
- newServerChunkLoadQueue.add(new ChunkCoordIntPair(chunkX, chunkZ));
- getLODChunk(chunkX, chunkZ).needsChunk = false;
- }
- }
- }
- }
- Collections.sort(newServerChunkLoadQueue, new ChunkCoordDistanceComparator(player.posX, player.posY, player.posZ));
- addToServerChunkLoadQueue(newServerChunkLoadQueue);
-
- lastSortX = player.posX;
- lastSortY = player.posY;
- lastSortZ = player.posZ;
- for(Iterator<ChunkCoordIntPair> it = loadedRegionsMap.keySet().iterator(); it.hasNext();) {
- ChunkCoordIntPair k = it.next();
- LODRegion v = loadedRegionsMap.get(k);
-
- if(v.distanceTaxicab(player) > renderRange * 16 + 16 * 16) {
- System.out.println("unloading " + v);
- v.destroy(getSaveDir());
- it.remove();
- } else {
- v.tick(player);
- }
- }
- }
- }
- }
-
- public float getFarPlaneDistanceMultiplier() {
- return (float)LODMod.farPlaneDistanceMultiplier;
- }
-
- public void afterSetupFog(int mode, float alpha, float farPlaneDistance) {
- EntityLivingBase entity = Minecraft.getMinecraft().renderViewEntity;
- if(LODMod.fogEventWasPosted && !Minecraft.getMinecraft().theWorld.provider.doesXZShowFog((int)entity.posX, (int)entity.posZ)) {
- GL11.glFogf(GL11.GL_FOG_START, mode < 0 ? 0 : farPlaneDistance * (float)LODMod.fogStart);
- GL11.glFogf(GL11.GL_FOG_END, mode < 0 ? farPlaneDistance/4 : farPlaneDistance * (float)LODMod.fogEnd);
- }
- }
-
- private void handleKeyboard() {
- if(LODMod.debugPrefix == 0 || (LODMod.debugPrefix != -1 && Keyboard.isKeyDown(LODMod.debugPrefix))) {
- if(Keyboard.isKeyDown(Keyboard.KEY_F) && !wasDown[Keyboard.KEY_F]) {
- rendererActive = !rendererActive;
- }
- if(Keyboard.isKeyDown(Keyboard.KEY_V) && !wasDown[Keyboard.KEY_V]) {
- renderWorld = !renderWorld;
- }
- if(Keyboard.isKeyDown(Keyboard.KEY_R) && !wasDown[Keyboard.KEY_R]) {
- loadShader();
- }
- if(Keyboard.isKeyDown(Keyboard.KEY_M) && !wasDown[Keyboard.KEY_M]) {
- showMemoryDebugger = !showMemoryDebugger;
- //LODChunk chunk = getLODChunk(9, -18);
- //setMeshVisible(chunk.chunkMeshes[7], false, true);
- //freezeMeshes = false;
- //chunk.chunkMeshes[7].quadCount = 256;
- //setMeshVisible(chunk.chunkMeshes[7], true, true);
- }
- }
- for(int i = 0; i < 256; i++) {
- wasDown[i] = Keyboard.isKeyDown(i);
- }
- }
-
- FloatBuffer modelView = BufferUtils.createFloatBuffer(16);
- FloatBuffer projBuf = BufferUtils.createFloatBuffer(16);
- IntBuffer viewportBuf = BufferUtils.createIntBuffer(16);
- FloatBuffer projInvBuf = BufferUtils.createFloatBuffer(16);
- FloatBuffer fogColorBuf = BufferUtils.createFloatBuffer(16);
- FloatBuffer fogStartEnd = BufferUtils.createFloatBuffer(2);
- Matrix4f projMatrix = new Matrix4f();
-
- private void render(double alpha) {
- GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
- GL11.glDisable(GL11.GL_TEXTURE_2D);
-
- glUseProgram(shaderProgram);
-
- int u_modelView = glGetUniformLocation(shaderProgram, "modelView");
- int u_proj = glGetUniformLocation(shaderProgram, "proj");
- int u_playerPos = glGetUniformLocation(shaderProgram, "playerPos");
- int u_light = glGetUniformLocation(shaderProgram, "lightTex");
- int u_viewport = glGetUniformLocation(shaderProgram, "viewport");
- int u_projInv = glGetUniformLocation(shaderProgram, "projInv");
- int u_fogColor = glGetUniformLocation(shaderProgram, "fogColor");
- int u_fogStartEnd = glGetUniformLocation(shaderProgram, "fogStartEnd");
-
- if(false && (u_modelView == -1 || u_proj == -1 || u_playerPos == -1 || u_light == -1 || u_viewport == -1 || u_projInv == -1 || u_fogColor == -1 || u_fogStartEnd == -1)) {
- System.out.println("failed to get the uniform");
- } else {
- glGetFloat(GL_MODELVIEW_MATRIX, modelView);
-
- glGetFloat(GL_PROJECTION_MATRIX, projBuf);
-
- glGetInteger(GL_VIEWPORT, viewportBuf);
-
- projMatrix.load(projBuf);
- projBuf.flip();
- projMatrix.invert();
- projMatrix.store(projInvBuf);
- projInvBuf.flip();
-
- fogColorBuf.limit(16);
- glGetFloat(GL_FOG_COLOR, fogColorBuf);
- fogColorBuf.limit(4);
-
- fogStartEnd.put(glGetFloat(GL_FOG_START));
- fogStartEnd.put(glGetFloat(GL_FOG_END));
- fogStartEnd.flip();
-
- glUniformMatrix4(u_modelView, false, modelView);
- glUniformMatrix4(u_proj, false, projBuf);
- glUniformMatrix4(u_projInv, false, projInvBuf);
- glUniform4f(u_viewport, viewportBuf.get(0),viewportBuf.get(1),viewportBuf.get(2),viewportBuf.get(3));
- glUniform4(u_fogColor, fogColorBuf);
- glUniform2(u_fogStartEnd, fogStartEnd);
-
- float originX = 0;
- float originY = 0;
- float originZ = 0;
-
- Entity rve = Minecraft.getMinecraft().renderViewEntity;
- double interpX = rve.lastTickPosX + (rve.posX - rve.lastTickPosX) * alpha;
- double interpY = rve.lastTickPosY + (rve.posY - rve.lastTickPosY) * alpha + rve.getEyeHeight();
- double interpZ = rve.lastTickPosZ + (rve.posZ - rve.lastTickPosZ) * alpha;
-
- glUniform3f(u_playerPos, (float)interpX - originX, (float)interpY - originY, (float)interpZ - originZ);
-
- glUniform1i(u_light, 1);
-
- modelView.position(0);
- projBuf.position(0);
- viewportBuf.position(0);
- projInvBuf.position(0);
- fogColorBuf.position(0);
- fogStartEnd.position(0);
- }
-
- glBindVertexArray(VAO);
- GL11.glDisable(GL11.GL_BLEND);
- glMultiDrawArrays(GL_TRIANGLES, piFirst[0], piCount[0]);
- GL11.glEnable(GL11.GL_BLEND);
- GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
- glMultiDrawArrays(GL_TRIANGLES, piFirst[1], piCount[1]);
-
- glBindVertexArray(0);
- glUseProgram(0);
-
- GL11.glDepthMask(true);
- GL11.glPopAttrib();
-
-
- }
-
- public boolean init() {
- Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
-
- loadShader();
-
- VAO = glGenVertexArrays();
- glBindVertexArray(VAO);
-
- mem = new GPUMemoryManager();
-
- glBindBuffer(GL_ARRAY_BUFFER, mem.VBO);
-
- int stride = 7 * 4;
-
- glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, 0);
- glVertexAttribPointer(1, 2, GL_FLOAT, false, stride, 3 * 4);
- glVertexAttribPointer(2, 2, GL_SHORT, false, stride, 5 * 4);
- glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, false, stride, 6 * 4);
-
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glEnableVertexAttribArray(2);
- glEnableVertexAttribArray(3);
-
- for(int i = 0; i < 2; i++) {
- piFirst[i] = BufferUtils.createIntBuffer(MAX_MESHES);
- piFirst[i].flip();
- piCount[i] = BufferUtils.createIntBuffer(MAX_MESHES);
- piCount[i].flip();
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
-
- return true;
- }
-
- private void loadShader() {
- int vertexShader;
- vertexShader = glCreateShader(GL_VERTEX_SHADER);
-
- glShaderSource(vertexShader, Util.readFile("shaders/chunk.vert"));
- glCompileShader(vertexShader);
-
- if(glGetShaderi(vertexShader, GL_COMPILE_STATUS) == 0) {
- System.out.println("Error compiling vertex shader: " + glGetShaderInfoLog(vertexShader, 256));
- }
-
- int fragmentShader;
- fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
-
- glShaderSource(fragmentShader, Util.readFile(LODMod.enableFog ? "shaders/chunk_fog.frag" : "shaders/chunk.frag"));
- glCompileShader(fragmentShader);
-
- if(glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == 0) {
- System.out.println("Error compiling fragment shader: " + glGetShaderInfoLog(fragmentShader, 256));
- }
-
- shaderProgram = glCreateProgram();
- glAttachShader(shaderProgram, vertexShader);
- glAttachShader(shaderProgram, fragmentShader);
- glLinkProgram(shaderProgram);
-
- if(glGetProgrami(shaderProgram, GL_LINK_STATUS) == 0) {
- System.out.println("Error linking shader: " + glGetShaderInfoLog(shaderProgram, 256));
- }
-
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- }
-
- public void destroy() {
- onSave();
-
- glDeleteProgram(shaderProgram);
- glDeleteVertexArrays(VAO);
- mem.destroy();
-
- SimpleChunkMesh.instances = 0;
- SimpleChunkMesh.usedRAM = 0;
- ChunkMesh.instances = 0;
- ChunkMesh.usedRAM = 0;
- }
-
- public void onWorldRendererChanged(WorldRenderer wr, WorldRendererChange change) {
- int x = Math.floorDiv(wr.posX, 16);
- int y = Math.floorDiv(wr.posY, 16);
- int z = Math.floorDiv(wr.posZ, 16);
- LODChunk lodChunk = getLODChunk(x, z);
-
- lodChunk.isSectionVisible[y] = change == WorldRendererChange.VISIBLE;
- if(change == WorldRendererChange.DELETED) {
- removeMesh(lodChunk.chunkMeshes[y]);
- }
- lodChunkChanged(lodChunk);
- }
-
- public void onWorldRendererPost(WorldRenderer wr) {
- if(LODMod.disableChunkMeshes) return;
-
- int x = Math.floorDiv(wr.posX, 16);
- int y = Math.floorDiv(wr.posY, 16);
- int z = Math.floorDiv(wr.posZ, 16);
-
- if(Minecraft.getMinecraft().theWorld.getChunkFromChunkCoords(x, z).isChunkLoaded) {
- LODChunk lodChunk = getLODChunk(x, z);
- lodChunk.isSectionVisible[y] = ((IWorldRenderer)wr).isDrawn();
- lodChunk.putChunkMeshes(y, ((IWorldRenderer)wr).getChunkMeshes());
- }
- }
-
- private double getLastSortDistanceSq(Entity player) {
- return Math.pow(lastSortX - player.posX, 2) + Math.pow(lastSortZ - player.posZ, 2);
- }
-
- private synchronized void addToServerChunkLoadQueue(List<ChunkCoordIntPair> coords) {
- serverChunkLoadQueue.addAll(coords);
- }
-
- private LODChunk receiveFarChunk(Chunk chunk) {
- LODRegion region = getRegionContaining(chunk.xPosition, chunk.zPosition);
- return region.putChunk(chunk);
- }
-
- private LODChunk getLODChunk(int chunkX, int chunkZ) {
- return getRegionContaining(chunkX, chunkZ).getChunkAbsolute(chunkX, chunkZ);
- }
-
- public void onStopServer() {
-
- }
-
- public synchronized void serverTick() {
- int chunkLoadsRemaining = LODMod.chunkLoadsPerTick;
- while(!serverChunkLoadQueue.isEmpty() && chunkLoadsRemaining-- > 0) {
- ChunkCoordIntPair coords = serverChunkLoadQueue.remove(0);
- ChunkProviderServer chunkProviderServer = Minecraft.getMinecraft().getIntegratedServer().worldServerForDimension(world.provider.dimensionId).theChunkProviderServer;
- Chunk chunk = chunkProviderServer.currentChunkProvider.provideChunk(coords.chunkXPos, coords.chunkZPos);
- SimpleChunkMesh.prepareFarChunkOnServer(chunk);
- farChunks.add(chunk);
- }
- }
-
- private LODRegion getRegionContaining(int chunkX, int chunkZ) {
- ChunkCoordIntPair key = new ChunkCoordIntPair(Math.floorDiv(chunkX , 32), Math.floorDiv(chunkZ, 32));
- LODRegion region = loadedRegionsMap.get(key);
- if(region == null) {
- region = LODRegion.load(getSaveDir(), Math.floorDiv(chunkX , 32), Math.floorDiv(chunkZ , 32));
- loadedRegionsMap.put(key, region);
- }
- return region;
- }
-
- private void sendChunkToGPU(LODChunk lodChunk) {
- Entity player = Minecraft.getMinecraft().renderViewEntity;
-
- lodChunk.tick(player);
- setVisible(lodChunk, true, true);
- }
-
- public void setVisible(LODChunk chunk, boolean visible) {
- setVisible(chunk, visible, false);
- }
-
- public void setVisible(LODChunk lodChunk, boolean visible, boolean forceCheck) {
- if(!forceCheck && visible == lodChunk.visible) return;
-
- lodChunk.visible = visible;
- lodChunkChanged(lodChunk);
- }
-
- public void lodChunkChanged(LODChunk lodChunk) {
- int newLOD = (!lodChunk.hasChunkMeshes() && lodChunk.lod == 2) ? (LODMod.disableSimpleMeshes ? 0 : 1) : lodChunk.lod;
- for(SimpleChunkMesh sm : lodChunk.simpleMeshes) {
- if(sm != null) {
- if(lodChunk.isFullyVisible() && newLOD == 1) {
- if(!sm.visible) {
- setMeshVisible(sm, true);
- }
- } else {
- if(sm.visible) {
- setMeshVisible(sm, false);
- }
- }
- }
- }
- for(int y = 0; y < 16; y++) {
- for(int pass = 0; pass < 2; pass++) {
- ChunkMesh cm = lodChunk.chunkMeshes[y * 2 + pass];
- if(cm != null) {
- if(lodChunk.isSectionVisible[y] && newLOD == 2) {
- if(!cm.visible) {
- setMeshVisible(cm, true);
- }
- } else {
- if(cm.visible) {
- setMeshVisible(cm, false);
- }
- }
- }
- }
- }
- }
-
- protected void setMeshVisible(Mesh mesh, boolean visible) {
- setMeshVisible(mesh, visible, false);
- }
-
- protected void setMeshVisible(Mesh mesh, boolean visible, boolean force) {
- if((!force && freezeMeshes) || mesh == null) return;
-
- if(mesh.visible != visible) {
- mesh.visible = visible;
-
- if(mesh.gpuStatus == GPUStatus.UNSENT) {
- mem.sendMeshToGPU(mesh);
- sentMeshes[mesh.pass].add(mesh);
- }
- }
- }
-
- public void removeMesh(Mesh mesh) {
- if(mesh == null) return;
-
- mem.deleteMeshFromGPU(mesh);
- sentMeshes[mesh.pass].remove(mesh);
- setMeshVisible(mesh, false);
- }
-
- public Chunk getChunkFromChunkCoords(int x, int z) {
- for(Chunk chunk : myChunks) {
- if(chunk.xPosition == x && chunk.zPosition == z) {
- return chunk;
- }
- }
- return null;
- }
-
- public boolean shouldSideBeRendered(Block block, IBlockAccess ba, int x, int y, int z, int w) {
- EnumFacing facing = EnumFacing.values()[w];
- if(block.getMaterial() == Material.water && facing != EnumFacing.UP && facing != EnumFacing.DOWN && !Minecraft.getMinecraft().theWorld.getChunkFromBlockCoords(x, z).isChunkLoaded) {
- return false;
- } else {
- return block.shouldSideBeRendered(ba, x, y, z, w);
- }
- }
-
- public List<String> getDebugText() {
- List<String> text = new ArrayList<>();
- text.addAll(mem.getDebugText());
- text.addAll(Arrays.asList(
- "Simple meshes: " + SimpleChunkMesh.instances + " (" + SimpleChunkMesh.usedRAM / 1024 / 1024 + "MB)",
- "Full meshes: " + ChunkMesh.instances + " (" + ChunkMesh.usedRAM / 1024 / 1024 + "MB)",
- "Total RAM used: " + ((SimpleChunkMesh.usedRAM + ChunkMesh.usedRAM) / 1024 / 1024) + " MB",
- "Rendered: " + renderedMeshes
- ));
- return text;
- }
-
- public void onSave() {
- System.out.println("Saving LOD regions...");
- long t0 = System.currentTimeMillis();
- //loadedRegionsMap.forEach((k, v) -> v.save(getSaveDir()));
- System.out.println("Finished saving LOD regions in " + ((System.currentTimeMillis() - t0) / 1000.0) + "s");
- }
-
- public void onChunkLoad(ChunkEvent.Load event) {
- farChunks.add(event.getChunk());
- }
-
- private Path getSaveDir(){
- return Minecraft.getMinecraft().mcDataDir.toPath().resolve("lodmod").resolve(Minecraft.getMinecraft().getIntegratedServer().getFolderName());
- }
-
- private boolean shouldRenderInWorld(World world) {
- return world != null && !world.provider.isHellWorld;
- }
-
- public static class LODChunkComparator implements Comparator<LODChunk> {
- Entity player;
-
- public LODChunkComparator(Entity player) {
- this.player = player;
- }
-
- @Override
- public int compare(LODChunk p1, LODChunk p2) {
- int distSq1 = distSq(p1);
- int distSq2 = distSq(p2);
- return distSq1 < distSq2 ? -1 : distSq1 > distSq2 ? 1 : 0;
- }
-
- int distSq(LODChunk p) {
- return (int)(
- Math.pow(((p.x * 16) - player.chunkCoordX), 2) +
- Math.pow(((p.z * 16) - player.chunkCoordZ), 2)
- );
- }
- }
-
- public static class ChunkCoordDistanceComparator implements Comparator<ChunkCoordIntPair> {
- double x, y, z;
-
- public ChunkCoordDistanceComparator(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- @Override
- public int compare(ChunkCoordIntPair p1, ChunkCoordIntPair p2) {
- int distSq1 = distSq(p1);
- int distSq2 = distSq(p2);
- return distSq1 < distSq2 ? -1 : distSq1 > distSq2 ? 1 : 0;
- }
-
- int distSq(ChunkCoordIntPair p) {
- return (int)(
- Math.pow(((p.chunkXPos * 16) - x), 2) +
- Math.pow(((p.chunkZPos * 16) - z), 2)
- );
- }
- }
-
- public static class MeshDistanceComparator implements Comparator<Mesh> {
- double x, y, z;
-
- MeshDistanceComparator(double x, double y, double z){
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- @Override
- public int compare(Mesh a, Mesh b) {
- if(a.pass < b.pass) {
- return -1;
- } else if(a.pass > b.pass) {
- return 1;
- } else {
- double distSqA = a.distSq(x, y, z);
- double distSqB = b.distSq(x, y, z);
- if(distSqA > distSqB) {
- return 1;
- } else if(distSqA < distSqB) {
- return -1;
- } else {
- return 0;
- }
- }
- }
-
- }
-
- public static enum WorldRendererChange {
- VISIBLE, INVISIBLE, DELETED
- }
-} \ No newline at end of file
diff --git a/src/main/java/makamys/lodmod/renderer/Mesh.java b/src/main/java/makamys/lodmod/renderer/Mesh.java
deleted file mode 100644
index fb1b8f1..0000000
--- a/src/main/java/makamys/lodmod/renderer/Mesh.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-import makamys.lodmod.util.Util;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.NBTBase;
-
-public abstract class Mesh {
-
- /** Can be null, unless gpuStatus is SENT */
- public ByteBuffer buffer;
- public int quadCount;
- public boolean visible;
- public GPUStatus gpuStatus = GPUStatus.UNSENT;
- public int iFirst = -1, iCount = -1;
- public int offset = -1;
- public int pass;
- int x, y, z;
-
- public abstract int getStride();
-
- public double distSq(double x2, double y2, double z2) {
- return Util.distSq(x, y, z, x2, y2, z2);
- }
-
- public int bufferSize() {
- return buffer == null ? 0 : buffer.limit();
- }
-
- public int getEnd() {
- return offset + bufferSize();
- }
-
- public void prepareBuffer() {}
- public void destroyBuffer() {}
-
- public void update() {}
-
- public static enum GPUStatus {
- UNSENT, SENT, PENDING_DELETE
- }
-}
diff --git a/src/main/java/makamys/lodmod/renderer/MeshQuad.java b/src/main/java/makamys/lodmod/renderer/MeshQuad.java
deleted file mode 100644
index 48f0a12..0000000
--- a/src/main/java/makamys/lodmod/renderer/MeshQuad.java
+++ /dev/null
@@ -1,426 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Comparator;
-import java.util.Locale;
-import java.util.Map;
-
-import makamys.lodmod.renderer.MeshQuad.QuadPlaneComparator;
-import makamys.lodmod.util.SpriteUtil;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.util.EnumFacing;
-
-public class MeshQuad {
- public int spriteIndex;
- public String spriteName;
- public int[] xs = new int[4];
- public int[] ys = new int[4];
- public int[] zs = new int[4];
- public int baseX = -1, baseY, baseZ;
- public int minX = Integer.MAX_VALUE;
- public int minY = Integer.MAX_VALUE;
- public int minZ = Integer.MAX_VALUE;
- public int maxX = Integer.MIN_VALUE;
- public int maxY = Integer.MIN_VALUE;
- public int maxZ = Integer.MIN_VALUE;
- public int[] relUs = new int[4];
- public int[] relVs = new int[4];
- public int[] bUs = new int[4];
- public int[] bVs = new int[4];
- public int[] cs = new int[4];
- public int[] normals = new int[4];
- public boolean deleted;
- public boolean isFullQuad;
-
- public static final int PLANE_NONE = -1, PLANE_XY = 0, PLANE_XZ = 1, PLANE_YZ = 2;
- public int plane = PLANE_NONE;
- public int offset;
- public ChunkMesh.Flags flags;
-
- public static int[] totalMergeCountByPlane = new int[3];
-
- private int minPositive(int a, int b) {
- if(a == -1) {
- return b;
- } else {
- return a < b ? a : b;
- }
- }
- private int maxPositive(int a, int b) {
- if(a == -1) {
- return b;
- } else {
- return a > b ? a : b;
- }
- }
-
- public MeshQuad(int[] rawBuffer, int offset, ChunkMesh.Flags flags, int offsetX, int offsetY, int offsetZ) {
- this.offset = offset;
- this.flags = flags;
- int i = offset;
- float[] us = new float[4];
- float uSum = 0;
- float[] vs = new float[4];
- float vSum = 0;
- for(int vertexI = 0; vertexI < 4; vertexI++) {
- float u = Float.intBitsToFloat(rawBuffer[vertexI * 8 + i + 3]);
- float v = Float.intBitsToFloat(rawBuffer[vertexI * 8 + i + 4]);
-
- us[vertexI] = u;
- vs[vertexI] = v;
-
- uSum += u;
- vSum += v;
- }
-
- float avgU = uSum / 4f;
- float avgV = vSum / 4f;
-
- TextureAtlasSprite sprite = null;
- Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
-
- spriteIndex = SpriteUtil.getSpriteIndexForUV(avgU, avgV);
- sprite = SpriteUtil.getSprite(spriteIndex);
-
- if(sprite == null) {
- System.out.println("Error: couldn't find sprite");
- } else {
- spriteName = sprite.getIconName();
- for(int vertexI = 0; vertexI < 4; vertexI++) {
- float x = Float.intBitsToFloat(rawBuffer[i + 0]) - offsetX;
- float y = Float.intBitsToFloat(rawBuffer[i + 1]) - offsetY;
- float z = Float.intBitsToFloat(rawBuffer[i + 2]) - offsetZ;
-
- int simpleX = (int)(x * 16);
- //if(simpleX == 256) simpleX = 255;
- int simpleY = (int)(y * 16);
- //if(simpleY == 256) simpleY = 255;
- int simpleZ = (int)(z * 16);
- //if(simpleZ == 256) simpleZ = 255;
-
- xs[vertexI] = simpleX;
- ys[vertexI] = simpleY;
- zs[vertexI] = simpleZ;
-
- // hasTexture
- float u = us[vertexI];
- float v = vs[vertexI];
-
- int simpleRelU = (int)((u - sprite.getMinU()) / (sprite.getMaxU() - sprite.getMinU()) * 16);
- int simpleRelV = (int)((v - sprite.getMinV()) / (sprite.getMaxV() - sprite.getMinV()) * 16);
- if(flags.hasTexture) {
- relUs[vertexI] = simpleRelU;
- relVs[vertexI] = simpleRelV;
- }
-
- // hasBrightness
- int brightness = rawBuffer[i + 7];
- int brightnessU = brightness & 0xFFFF;
- int brightnessV = (brightness >> 16) & 0xFFFF;
- if(flags.hasBrightness) {
- bUs[vertexI] = (int)brightnessU;
- bVs[vertexI] = (int)brightnessV;
- }
-
- // hasColor
- int color = rawBuffer[i + 5];
- if(flags.hasColor) {
- cs[vertexI] = color;
- }
-
- // hasNormals
- int normal = rawBuffer[i + 6];
- if(flags.hasNormals) {
- normals[vertexI] = normal;
- }
-
- i += 8;
- }
- }
-
- updateMinMaxXYZ();
-
- if(ys[0] == ys[1] && ys[1] == ys[2] && ys[2] == ys[3]) {
- plane = PLANE_XZ;
- } else if(xs[0] == xs[1] && xs[1] == xs[2] && xs[2] == xs[3]) {
- plane = PLANE_YZ;
- } else if(zs[0] == zs[1] && zs[1] == zs[2] && zs[2] == zs[3]) {
- plane = PLANE_XY;
- } else {
- plane = PLANE_NONE;
- }
-
- boolean equalToAABB = true;
- for(int minOrMaxX = 0; minOrMaxX < 2; minOrMaxX++) {
- for(int minOrMaxY = 0; minOrMaxY < 2; minOrMaxY++) {
- for(int minOrMaxZ = 0; minOrMaxZ < 2; minOrMaxZ++) {
- if(getCornerVertex(minOrMaxX == 1, minOrMaxY == 1, minOrMaxZ == 1) == -1) {
- equalToAABB = false;
- break;
- }
- }
- }
- }
-
- switch(plane) {
- case PLANE_XY:
- isFullQuad = equalToAABB && (maxX - minX) == 16 && (maxY - minY) == 16;
- break;
- case PLANE_XZ:
- isFullQuad = equalToAABB && (maxX - minX) == 16 && (maxZ - minZ) == 16;
- break;
- case PLANE_YZ:
- isFullQuad = equalToAABB && (maxY - minY) == 16 && (maxZ - minZ) == 16;
- break;
- default:
- isFullQuad = false;
- }
-
- for(int c = 0; c < 3; c++) {
- if(getMin(c) < 0 || getMax(c) < 0 || getMax(c) - getMin(c) > 16 || getMin(c) > 256 || getMax(c) > 256) {
- this.deleted = true;
- // TODO handle weirdness more gracefully
- }
- }
- }
-
- // yeah this is kinda unoptimal
- private int getCornerVertex(boolean minOrMaxX, boolean minOrMaxY, boolean minOrMaxZ) {
- int aabbCornerX = !minOrMaxX ? minX : maxX;
- int aabbCornerY = !minOrMaxY ? minY : maxY;
- int aabbCornerZ = !minOrMaxZ ? minZ : maxZ;
-
- for(int vi = 0; vi < 4; vi++) {
- if(xs[vi] == aabbCornerX && ys[vi] == aabbCornerY && zs[vi] == aabbCornerZ) {
- return vi;
- }
- }
- return -1;
- }
-
- public void tryToMerge(MeshQuad o) {
- if(isValid(this) && isValid(o) && plane == o.plane
- && spriteIndex == o.spriteIndex && isFullQuad && o.isFullQuad) {
- int numVerticesTouching = 0;
- for(int i = 0; i < 4; i++) {
- for(int j = 0; j < 4; j++) {
- if(xs[i] == o.xs[j] && ys[i] == o.ys[j] && zs[i] == o.zs[j]) {
- numVerticesTouching++;
- }
- }
- }
- if(numVerticesTouching == 2) {
- mergeWithQuad(o);
-
- totalMergeCountByPlane[plane]++;
-
- o.deleted = true;
- }
- }
- }
-
- private void mergeWithQuad(MeshQuad o) {
- if(minX < o.minX) {
- copyEdgeFrom(o, EnumFacing.EAST);
- } else if(minX > o.minX) {
- copyEdgeFrom(o, EnumFacing.WEST);
- } else if(minY < o.minY) {
- copyEdgeFrom(o, EnumFacing.UP);
- } else if(minY > o.minY) {
- copyEdgeFrom(o, EnumFacing.DOWN);
- } else if(minZ < o.minZ) {
- copyEdgeFrom(o, EnumFacing.NORTH);
- } else if(minX > o.minX) {
- copyEdgeFrom(o, EnumFacing.SOUTH);
- }
- }
-
- private void copyEdgeFrom(MeshQuad o, EnumFacing side) {
- int whichX, whichY, whichZ;
- whichX = whichY = whichZ = -1;
-
- switch(plane) {
- case PLANE_XY:
- whichZ = 0;
- break;
- case PLANE_XZ:
- whichY = 0;
- break;
- case PLANE_YZ:
- whichX = 0;
- break;
- }
-
- switch(side) {
- case EAST:
- copyCornerVertexFrom(o, 1, whichY, whichZ);
- break;
- case WEST:
- copyCornerVertexFrom(o, 0, whichY, whichZ);
- break;
- case UP:
- copyCornerVertexFrom(o, whichX, 1, whichZ);
- break;
- case DOWN:
- copyCornerVertexFrom(o, whichX, 0, whichZ);
- break;
- case NORTH:
- copyCornerVertexFrom(o, whichX, whichY, 1);
- break;
- case SOUTH:
- copyCornerVertexFrom(o, whichX, whichY, 0);
- break;
- }
-
- updateMinMaxXYZ();
- }
-
- private void updateMinMaxXYZ() {
- for(int i = 0; i < 4; i++) {
- minX = Math.min(minX, xs[i]);
- minY = Math.min(minY, ys[i]);
- minZ = Math.min(minZ, zs[i]);
- maxX = Math.max(maxX, xs[i]);
- maxY = Math.max(maxY, ys[i]);
- maxZ = Math.max(maxZ, zs[i]);
- }
- }
-
- private void copyCornerVertexFrom(MeshQuad o, int whichX, int whichY, int whichZ) {
- int whichXMin, whichXMax, whichYMin, whichYMax, whichZMin, whichZMax;
- whichXMin = whichYMin = whichZMin = 0;
- whichXMax = whichYMax = whichZMax = 1;
-
- if(whichX != -1) whichXMin = whichXMax = whichX;
- if(whichY != -1) whichYMin = whichYMax = whichY;
- if(whichZ != -1) whichZMin = whichZMax = whichZ;
-
- for(int minOrMaxX = whichXMin; minOrMaxX <= whichXMax; minOrMaxX++) {
- for(int minOrMaxY = whichYMin; minOrMaxY <= whichYMax; minOrMaxY++) {
- for(int minOrMaxZ = whichZMin; minOrMaxZ <= whichZMax; minOrMaxZ++) {
- copyVertexFrom(o,
- o.getCornerVertex(minOrMaxX == 1, minOrMaxY == 1, minOrMaxZ == 1),
- getCornerVertex(minOrMaxX == 1, minOrMaxY == 1, minOrMaxZ == 1));
- }
- }
- }
- }
-
- private void copyVertexFrom(MeshQuad o, int src, int dest) {
- xs[dest] = o.xs[src];
- ys[dest] = o.ys[src];
- zs[dest] = o.zs[src];
- relUs[dest] = o.relUs[src];
- relVs[dest] = o.relVs[src];
- bUs[dest] = o.bUs[src];
- bVs[dest] = o.bVs[src];
- cs[dest] = o.cs[src];
- normals[dest] = o.normals[src];
- }
-
- public void writeToDisk(DataOutputStream out, int pass) throws IOException {
- if(deleted) {
- return;
- }
-
- if(flags.hasTexture) {
- if(pass == 0) out.writeShort(spriteIndex);
- }
- for (int vertexI = 0; vertexI < 4; vertexI++) {
- if(pass == 1) out.writeByte(xs[vertexI] == 256 ? 255 : xs[vertexI]);
- if(pass == 2) out.writeByte(ys[vertexI] == 256 ? 255 : ys[vertexI]);
- if(pass == 3) out.writeByte(zs[vertexI] == 256 ? 255 : zs[vertexI]);
-
- if (flags.hasTexture) {
- if(pass == 4) out.writeByte(relUs[vertexI]);
- if(pass == 5) out.writeByte(relVs[vertexI]);
- }
-
- if (flags.hasBrightness) {
- if(pass == 6) out.writeByte(bUs[vertexI]);
- if(pass == 7) out.writeByte(bVs[vertexI]);
- }
-
- if (flags.hasColor) {
- if(pass == 8) out.writeInt(cs[vertexI]);
- }
-
- if (flags.hasNormals) {
- if(pass == 9) out.writeInt(normals[vertexI]);
- }
- }
- }
-
- // maybe minXYZ and maxXYZ should be arrays instead
- public int getMin(int coord) {
- return coord == 0 ? minX : coord == 1 ? minY : coord == 2 ? minZ : -1;
- }
-
- public int getMax(int coord) {
- return coord == 0 ? maxX : coord == 1 ? maxY : coord == 2 ? maxZ : -1;
- }
-
- public boolean onSamePlaneAs(MeshQuad o) {
- return isValid(this) && isValid(o) && plane == o.plane &&
- ((plane == PLANE_XY && minZ == o.minZ) ||
- (plane == PLANE_XZ && minY == o.minY) ||
- (plane == PLANE_YZ && minX == o.minX));
- }
-
- // this should be static..
- public boolean isValid(MeshQuad q) {
- return q != null && !q.deleted;
- }
-
- public boolean isClockwiseXZ() {
- return (xs[1] - xs[0]) * (zs[2] - zs[0]) - (xs[2] - xs[0]) * (zs[1] - zs[0]) < 0;
- }
-
- @Override
- public String toString() {
- return String.format(Locale.ENGLISH, "%s(%.1f, %.1f, %.1f -- %.1f, %.1f, %.1f) %s", deleted ? "XXX " : "", minX/16f, minY/16f, minZ/16f, maxX/16f, maxY/16f, maxZ/16f, spriteName);
- }
-
- public static class QuadPlaneComparator implements Comparator<MeshQuad> {
-
- public static final QuadPlaneComparator[] quadPlaneComparators = new QuadPlaneComparator[]{
- new QuadPlaneComparator(2, 1, 0), // PLANE_XY -> ZYX
- new QuadPlaneComparator(1, 2, 0), // PLANE_XZ -> YZX
- new QuadPlaneComparator(0, 2, 1) // PLANE_YZ -> XZY
- };
-
- private int c0, c1, c2;
-
- public QuadPlaneComparator(int firstCoordToCompare, int secondCoordToCompare, int thirdCoordToCompare) {
- this.c0 = firstCoordToCompare;
- this.c1 = secondCoordToCompare;
- this.c2 = thirdCoordToCompare;
- }
-
- @Override
- public int compare(MeshQuad a, MeshQuad b) {
- if(a.getMin(c0) < b.getMin(c0)) {
- return -1;
- } else if(a.getMin(c0) > b.getMin(c0)) {
- return 1;
- } else {
- if(a.getMin(c1) < b.getMin(c1)) {
- return -1;
- } else if(a.getMin(c1) > b.getMin(c1)) {
- return 1;
- } else {
- if(a.getMin(c2) < b.getMin(c2)) {
- return -1;
- } else if(a.getMin(c2) > b.getMin(c2)) {
- return 1;
- } else {
- return (int)Math.signum(a.offset - b.offset);
- }
- }
- }
- }
- }
-}
diff --git a/src/main/java/makamys/lodmod/renderer/SimpleChunkMesh.java b/src/main/java/makamys/lodmod/renderer/SimpleChunkMesh.java
deleted file mode 100644
index 4065b6c..0000000
--- a/src/main/java/makamys/lodmod/renderer/SimpleChunkMesh.java
+++ /dev/null
@@ -1,350 +0,0 @@
-package makamys.lodmod.renderer;
-
-import static org.lwjgl.opengl.GL11.GL_FLOAT;
-import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
-import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER;
-import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
-import static org.lwjgl.opengl.GL15.glBufferData;
-import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
-import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.util.Arrays;
-import java.util.List;
-
-import org.lwjgl.BufferUtils;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.util.MCUtil;
-import net.minecraft.block.Block;
-import net.minecraft.block.BlockGrass;
-import net.minecraft.block.BlockLeaves;
-import net.minecraft.block.material.Material;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.entity.Entity;
-import net.minecraft.init.Blocks;
-import net.minecraft.nbt.NBTTagString;
-import net.minecraft.util.IIcon;
-import net.minecraft.world.biome.BiomeGenBase;
-import net.minecraft.world.chunk.Chunk;
-
-public class SimpleChunkMesh extends Mesh {
-
- private FloatBuffer vertices;
-
- public static int usedRAM;
- public static int instances;
- public static int divisions = 4;
-
- private static boolean isSolid(Block block) {
- return block.isBlockNormalCube() && block.isOpaqueCube() && block.renderAsNormalBlock();
- }
-
- private static boolean isBad(Block block) {
- for(Class clazz : LODMod.blockClassBlacklist) {
- if(clazz.isInstance(block)) {
- return true;
- }
- }
- return false;
- }
-
- public static List<SimpleChunkMesh> generateSimpleMeshes(Chunk target){
- SimpleChunkMesh pass1 = new SimpleChunkMesh(target.xPosition, target.zPosition, divisions * divisions * 25, 0);
- SimpleChunkMesh pass2 = new SimpleChunkMesh(target.xPosition, target.zPosition, divisions * divisions * 25, 1);
-
- SimpleChunkMeshBuilder builder = new SimpleChunkMeshBuilder();
-
- for(int divX = 0; divX < divisions; divX++) {
- for(int divZ = 0; divZ < divisions; divZ++) {
- IIcon icon = null;
- int color = 0xFFFFFFFF;
- int size = 16 / divisions;
- int y = 255;
- boolean foundWater = false;
-
- int xOff = divX * size;
- int zOff = divZ * size;
-
- int biomeId = target.getBiomeArray()[xOff << 4 | zOff] & 255;
- if(biomeId == 255) {
- System.out.println("Missing biome data for chunk " + target.xPosition + ", " + target.zPosition);
- }
- BiomeGenBase biome = BiomeGenBase.getBiome(biomeId) == null ? BiomeGenBase.plains : BiomeGenBase.getBiome(biomeId);
-
- for(y = 255; y > 0; y--) {
- Block block = target.getBlock(xOff, y, zOff);
-
- int worldX = target.xPosition * 16 + divX * size;
- int worldY = y;
- int worldZ = target.zPosition * 16 + divZ * size;
-
- if(!foundWater && block.getMaterial() == Material.water) {
- foundWater = true;
- int meta = target.getBlockMetadata(xOff, y, zOff);
- IIcon waterIcon = block.getIcon(1, meta);
-
- int waterColor = biome.getWaterColorMultiplier();
- waterColor |= 0xFF000000;
- pass2.addFaceYPos(worldX, worldY, worldZ, size, size, waterIcon, waterColor, 1);
- }
-
- if(isSolid(block) && isBad(block)) {
- for(int dx = -1; dx <= 1; dx++) {
- for(int dz = -1; dz <= 1; dz++) {
- int newX = xOff + dx;
- int newZ = zOff + dz;
- if(newX >= 0 && newX < 16 && newZ >= 0 && newZ < 16) {
- Block newBlock = target.getBlock(newX, y, newZ);
- if(!isBad(newBlock)) {
- xOff += dx;
- zOff += dz;
- worldX += dx;
- worldZ += dz;
- block = newBlock;
- }
- }
- }
- }
- }
- if(isSolid(block)) {
-
- float brightnessMult = foundWater ? 0.2f : 1f;
- int meta = target.getBlockMetadata(xOff, y, zOff);
- icon = block.getIcon(1, meta);
-
- if(block instanceof BlockGrass) {
- color = biome.getBiomeGrassColor(worldX, y, worldZ);
- } else if(block instanceof BlockLeaves) {
- color = biome.getBiomeFoliageColor(worldX, y, worldZ);
- } else {
- color = block.colorMultiplier(Minecraft.getMinecraft().theWorld, worldX, y, worldZ);
- }
- color = (0xFF << 24) | ((color >> 16 & 0xFF) << 0) | ((color >> 8 & 0xFF) << 8) | ((color >> 0 & 0xFF) << 16);
-
- if((LODMod.forceVanillaBiomeTemperature ? MCUtil.getBiomeTemperatureVanilla(biome, worldX, y, worldZ)
- : biome.getFloatTemperature(worldX, y, worldZ)) < 0.15f) {
-
- builder.addCube(divX, divZ, worldY + 0.2f, 1f, Blocks.snow_layer.getIcon(1, 0), 0xFFFFFFFF, brightnessMult);
- builder.addCube(divX, divZ, worldY - 0.8f, -1, icon, color, brightnessMult);
- } else {
- builder.addCube(divX, divZ, worldY, -1, icon, color, brightnessMult);
- }
-
-
- break;
- }
- }
- }
- }
-
- builder.render(pass1, target.xPosition, target.zPosition);
-
- pass1.finish();
- pass2.finish();
-
- return Arrays.asList(new SimpleChunkMesh[] {pass1.quadCount != 0 ? pass1 : null, pass2.quadCount != 0 ? pass2 : null});
- }
-
- private static class SimpleChunkMeshBuilder {
- int maxIconsPerColumn = 2;
- float[][][] heights = new float[divisions][divisions][maxIconsPerColumn];
- float[][][] depths = new float[divisions][divisions][maxIconsPerColumn];
- IIcon[][][] icons = new IIcon[divisions][divisions][maxIconsPerColumn];
- int[][][] colors = new int[divisions][divisions][maxIconsPerColumn];
- float[][][] brightnessMults = new float[divisions][divisions][maxIconsPerColumn];
-
- public void addCube(int x, int z, float height, float depth, IIcon icon, int color, float brightnessMult) {
- IIcon[] iconz = icons[x][z];
- int i = iconz[0] == null ? 0 : 1;
- if(iconz[0] != null && iconz[1] != null) {
- throw new IllegalStateException("Too many icons in column");
- }
-
- heights[x][z][i] = height;
- depths[x][z][i] = depth;
- icons[x][z][i] = icon;
- colors[x][z][i] = color;
- brightnessMults[x][z][i] = brightnessMult;
- }
-
- public void render(SimpleChunkMesh mesh, int chunkX, int chunkZ) {
- float size = 16 / divisions;
-
- for(int x = 0; x < divisions; x++) {
- for(int z = 0; z < divisions; z++) {
- float worldX = chunkX * 16 + x * size;
- float worldZ = chunkZ * 16 + z * size;
- for(int i = 0; i < maxIconsPerColumn; i++) {
- IIcon icon = icons[x][z][i];
- if(icon != null) {
- float height = heights[x][z][i];
- float depthValue = depths[x][z][i];
- float depth = depthValue == -1 ? height : depthValue;
- int color = colors[x][z][i];
- float brightnessMult = brightnessMults[x][z][i];
-
- if(i == 0) {
- mesh.addFaceYPos(worldX, height, worldZ, size, size, icon, color, brightnessMult);
- }
- float heightX0 = x > 0 ? heights[x - 1][z][0] : 0;
- if(heightX0 < height) {
- mesh.addFaceX2(worldX, height, worldZ, Math.min(depth, height - heightX0), size, icon, color, brightnessMult);
- }
-
- float heightX1 = x < divisions - 1 ? heights[x + 1][z][0] : 0;
- if(heightX1 < height) {
- mesh.addFaceX1(worldX + size, height, worldZ, Math.min(depth, height - heightX1), size, icon, color, brightnessMult);
- }
-
- float heightZ0 = z > 0 ? heights[x][z - 1][0] : 0;
- if(heightZ0 < height) {
- mesh.addFaceZ1(worldX, height, worldZ, size, Math.min(depth, height - heightZ0), icon, color, brightnessMult);
- }
-
- float heightZ1 = z < divisions - 1 ? heights[x][z + 1][0] : 0;
- if(heightZ1 < height) {
- mesh.addFaceZ2(worldX, height, worldZ + size, size, Math.min(depth, height - heightZ1), icon, color, brightnessMult);
- }
- }
- }
- }
- }
- }
- }
-
- public SimpleChunkMesh(int x, int z, int maxQuads, int pass) {
- this.x = x;
- this.y = 64;
- this.z = z;
- this.pass = pass;
-
- buffer = BufferUtils.createByteBuffer(4 * 6 * 7 * maxQuads);
- vertices = buffer.asFloatBuffer();
- }
-
- public void finish() {
- vertices.flip();
- buffer.limit(vertices.limit() * 4);
-
- // may want to shrink the buffers to actual size to not waste memory
-
- usedRAM += buffer.limit();
- instances++;
- }
-
- private void addCube(float x, float y, float z, float sizeX, float sizeZ, float sizeY, IIcon icon, int color, float brightnessMult) {
- addFaceYPos(x, y, z, sizeX, sizeZ, icon, color, brightnessMult);
- addFaceZ1(x, y, z, sizeX, sizeY, icon, color, brightnessMult);
- addFaceZ2(x, y, z + sizeZ, sizeX, sizeY, icon, color, brightnessMult);
- addFaceX1(x + sizeX, y, z, sizeX, sizeY, icon, color, brightnessMult);
- addFaceX2(x, y, z, sizeX, sizeY, icon, color, brightnessMult);
- }
-
- private void addFaceZ1(float x, float y, float z, float sizeX, float sizeY, IIcon icon, int color, float brightnessMult) {
- addFace(
- x + 0, y - sizeY, z + 0,
- x + 0, y + 0, z + 0,
- x + sizeX, y + 0, z + 0,
- x + sizeX, y - sizeY, z + 0,
- icon, color, (int)(200 * brightnessMult)
- );
- }
-
- private void addFaceZ2(float x, float y, float z, float sizeX, float sizeY, IIcon icon, int color, float brightnessMult) {
- addFace(
- x + sizeX, y - sizeY, z,
- x + sizeX, y + 0, z,
- x + 0, y + 0, z,
- x + 0, y - sizeY, z,
- icon, color, (int)(200 * brightnessMult)
- );
- }
-
- private void addFaceX1(float x, float y, float z, float sizeY, float sizeZ, IIcon icon, int color, float brightnessMult) {
- addFace(
- x, y - sizeY, z + 0,
- x, y + 0, z + 0,
- x, y + 0, z + sizeZ,
- x, y - sizeY, z + sizeZ,
- icon, color, (int)(160 * brightnessMult)
- );
- }
-
- private void addFaceX2(float x, float y, float z, float sizeY, float sizeZ, IIcon icon, int color, float brightnessMult) {
- addFace(
- x + 0, y - sizeY, z + sizeZ,
- x + 0, y + 0, z + sizeZ,
- x + 0, y + 0, z + 0,
- x + 0, y - sizeY, z + 0,
- icon, color, (int)(160 * brightnessMult)
- );
- }
-
- private void addFaceYPos(float x, float y, float z, float sizeX, float sizeZ, IIcon icon, int color, float brightnessMult) {
- addFace(
- x + 0, y + 0, z + 0,
- x + 0, y + 0, z + sizeZ,
- x + sizeX, y + 0, z + sizeZ,
- x + sizeX, y + 0, z + 0,
- icon, color, (int)(240 * brightnessMult)
- );
- }
-
- private void addFace(float p1x, float p1y, float p1z,
- float p2x, float p2y, float p2z,
- float p3x, float p3y, float p3z,
- float p4x, float p4y, float p4z,
- IIcon icon, int color, int brightness) {
- int off = vertices.position() * 4;
- vertices.put(new float[] {
- p1x, p1y, p1z, icon.getMinU(), icon.getMaxV(), 0, 0,
- p2x, p2y, p2z, icon.getMinU(), icon.getMinV(), 0, 0,
- p4x, p4y, p4z, icon.getMaxU(), icon.getMaxV(), 0, 0,
- p2x, p2y, p2z, icon.getMinU(), icon.getMinV(), 0, 0,
- p3x, p3y, p3z, icon.getMaxU(), icon.getMinV(), 0, 0,
- p4x, p4y, p4z, icon.getMaxU(), icon.getMaxV(), 0, 0
- });
- buffer.putInt(off + 0 * getStride() + 6 * 4, color);
- buffer.putShort(off + 0 * getStride() + 5 * 4 + 2, (short)brightness);
- buffer.putInt(off + 1 * getStride() + 6 * 4, color);
- buffer.putShort(off + 1 * getStride() + 5 * 4 + 2, (short)brightness);
- buffer.putInt(off + 2 * getStride() + 6 * 4, color);
- buffer.putShort(off + 2 * getStride() + 5 * 4 + 2, (short)brightness);
- buffer.putInt(off + 3 * getStride() + 6 * 4, color);
- buffer.putShort(off + 3 * getStride() + 5 * 4 + 2, (short)brightness);
- buffer.putInt(off + 4 * getStride() + 6 * 4, color);
- buffer.putShort(off + 4 * getStride() + 5 * 4 + 2, (short)brightness);
- buffer.putInt(off + 5 * getStride() + 6 * 4, color);
- buffer.putShort(off + 5 * getStride() + 5 * 4 + 2, (short)brightness);
-
- quadCount++;
- }
-
- public int getStride() {
- return (3 * 4 + 8 + 4 + 4);
- }
-
- public void destroy() {
- usedRAM -= buffer.limit();
- instances--;
- }
-
- public static void prepareFarChunkOnServer(Chunk chunk) {
- for(int divX = 0; divX < divisions; divX++) {
- for(int divZ = 0; divZ < divisions; divZ++) {
- int size = 16 / divisions;
-
- int xOff = divX * size;
- int zOff = divZ * size;
-
- chunk.getBiomeGenForWorldCoords(xOff, zOff, chunk.worldObj.getWorldChunkManager());
- }
- }
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/util/BufferWriter.java b/src/main/java/makamys/lodmod/util/BufferWriter.java
deleted file mode 100644
index ae81be1..0000000
--- a/src/main/java/makamys/lodmod/util/BufferWriter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package makamys.lodmod.util;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-
-public class BufferWriter {
-
- private ByteBuffer buf;
-
- private FloatBuffer floatBuffer;
- private ShortBuffer shortBuffer;
- private IntBuffer intBuffer;
-
- public BufferWriter(ByteBuffer buf) {
- this.buf = buf;
- this.floatBuffer = buf.asFloatBuffer();
- this.shortBuffer = buf.asShortBuffer();
- this.intBuffer = buf.asIntBuffer();
- }
-
- private void incrementPosition(int add) {
- buf.position(buf.position() + add);
- floatBuffer.position(buf.position() / 4);
- shortBuffer.position(buf.position() / 2);
- intBuffer.position(buf.position() / 4);
- }
-
- public void writeFloat(float x) {
- try {
- floatBuffer.put(x);
-
- incrementPosition(4);
- } catch(Exception e){
- e.printStackTrace();
- }
- }
-
- public void writeInt(int x) {
- intBuffer.put(x);
-
- incrementPosition(4);
- }
-
-} \ No newline at end of file
diff --git a/src/main/java/makamys/lodmod/util/GuiHelper.java b/src/main/java/makamys/lodmod/util/GuiHelper.java
deleted file mode 100644
index 3054237..0000000
--- a/src/main/java/makamys/lodmod/util/GuiHelper.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package makamys.lodmod.util;
-
-import org.lwjgl.opengl.GL11;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.Tessellator;
-
-public class GuiHelper {
-
- public static void begin() {
- GL11.glDisable(GL11.GL_TEXTURE_2D);
-
- Minecraft mc = Minecraft.getMinecraft();
-
- //GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
- GL11.glMatrixMode(GL11.GL_PROJECTION);
- //GL11.glEnable(GL11.GL_COLOR_MATERIAL);
- GL11.glLoadIdentity();
- GL11.glOrtho(0.0D, (double)mc.displayWidth, (double)mc.displayHeight, 0.0D, 1000.0D, 3000.0D);
- GL11.glMatrixMode(GL11.GL_MODELVIEW);
- GL11.glLoadIdentity();
- GL11.glTranslatef(0.0F, 0.0F, -2000.0F);
- //GL11.glLineWidth(1.0F);
- //GL11.glDisable(GL11.GL_TEXTURE_2D);
- }
-
- public static void drawRectangle(int x, int y, int w, int h, int color) {
- Tessellator tessellator = Tessellator.instance;
- tessellator.startDrawingQuads();
- tessellator.setColorOpaque_I(color);
- tessellator.addVertex(x, y, 0);
- tessellator.addVertex(x, y+h, 0);
- tessellator.addVertex(x+w, y+h, 0);
- tessellator.addVertex(x+w, y, 0);
-
- tessellator.draw();
- }
-
- public static void drawRectangle(int x, int y, int w, int h, int color, int opacity) {
- GL11.glEnable(GL11.GL_BLEND);
-
- Tessellator tessellator = Tessellator.instance;
- tessellator.startDrawingQuads();
- tessellator.setColorRGBA_I(color, opacity);
- tessellator.addVertex(x, y, 0);
- tessellator.addVertex(x, y+h, 0);
- tessellator.addVertex(x+w, y+h, 0);
- tessellator.addVertex(x+w, y, 0);
-
- tessellator.draw();
-
- GL11.glDisable(GL11.GL_BLEND);
- }
-
- public static void end() {
- //GL11.glDisable(GL11.GL_BLEND);
-
- //GL11.glEnable(GL11.GL_TEXTURE_2D);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/util/MCUtil.java b/src/main/java/makamys/lodmod/util/MCUtil.java
deleted file mode 100644
index 7f81d74..0000000
--- a/src/main/java/makamys/lodmod/util/MCUtil.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package makamys.lodmod.util;
-
-import net.minecraft.world.biome.BiomeGenBase;
-
-public class MCUtil {
-
- public static float getBiomeTemperatureVanilla(BiomeGenBase biome, int p_150564_1_, int p_150564_2_, int p_150564_3_){
- if (p_150564_2_ > 64)
- {
- float f = (float)BiomeGenBase.temperatureNoise
- .func_151601_a((double)p_150564_1_ * 1.0D / 8.0D, (double)p_150564_3_ * 1.0D / 8.0D) * 4.0F;
- return biome.temperature - (f + (float)p_150564_2_ - 64.0F) * 0.05F / 30.0F;
- }
- else
- {
- return biome.temperature;
- }
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/util/SpriteUtil.java b/src/main/java/makamys/lodmod/util/SpriteUtil.java
deleted file mode 100644
index 34bc544..0000000
--- a/src/main/java/makamys/lodmod/util/SpriteUtil.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package makamys.lodmod.util;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.world.ChunkCoordIntPair;
-
-public class SpriteUtil {
-
- private static int[] spriteIndexMap;
- public static List<TextureAtlasSprite> sprites;
-
- private static Map<Long, Integer> uv2spriteIndex = new HashMap<>();
-
- private static int findSpriteIndexForUV(float u, float v) {
- Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
-
- int spriteIndex = 0;
- for(TextureAtlasSprite tas : uploadedSprites.values()) {
- if(tas.getMinU() <= u && u <= tas.getMaxU() && tas.getMinV() <= v && v <= tas.getMaxV()) {
- break;
- }
- spriteIndex++;
- }
- return spriteIndex;
- }
-
- public static int getSpriteIndexForUV(float u, float v){
- long key = ChunkCoordIntPair.chunkXZ2Int((int)(u * Integer.MAX_VALUE), (int)(v * Integer.MAX_VALUE));
- int index = uv2spriteIndex.getOrDefault(key, -1);
- if(index == -1) {
- index = findSpriteIndexForUV(u, v);
- uv2spriteIndex.put(key, index);
- }
- return index;
- }
-
- public static TextureAtlasSprite getSprite(int i){
- if(i >= 0 && i < sprites.size()) {
- return sprites.get(i);
- } else {
- return null;
- }
- }
-
- public static void init() {
- Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
- sprites = uploadedSprites.values().stream().collect(Collectors.toList());
- }
-}
diff --git a/src/main/java/makamys/lodmod/util/Util.java b/src/main/java/makamys/lodmod/util/Util.java
deleted file mode 100644
index 6ca5f86..0000000
--- a/src/main/java/makamys/lodmod/util/Util.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package makamys.lodmod.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import net.minecraft.launchwrapper.Launch;
-
-public class Util {
-
- private static boolean allowResourceOverrides = Boolean.parseBoolean(System.getProperty("lodmod.allowResourceOverrides", "false"));
-
- public static Path getResourcePath(String relPath) {
- if(allowResourceOverrides) {
- File overrideFile = new File(new File(Launch.minecraftHome, "lodmod/resources"), relPath);
- if(overrideFile.exists()) {
- return overrideFile.toPath();
- }
- }
-
- try {
- URL resourceURL = Util.class.getClassLoader().getResource(relPath);
-
- switch(resourceURL.getProtocol()) {
- case "jar":
- String urlString = resourceURL.getPath();
- int lastExclamation = urlString.lastIndexOf('!');
- String newURLString = urlString.substring(0, lastExclamation);
- return FileSystems.newFileSystem(new File(URI.create(newURLString)).toPath(), null).getPath(relPath);
- case "file":
- return new File(URI.create(resourceURL.toString())).toPath();
- default:
- return null;
- }
- } catch(IOException e) {
- return null;
- }
- }
-
- public static String readFile(String path){
- try {
- return new String(Files.readAllBytes(Util.getResourcePath(path)));
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
-
- public static byte[] byteBufferToArray(ByteBuffer buffer) {
- byte[] dst = new byte[buffer.limit()];
- int pos = buffer.position();
- buffer.position(0);
- buffer.get(dst);
- buffer.position(pos);
- return dst;
- }
-
- public static int[] intBufferToArray(IntBuffer buffer) {
- int[] dst = new int[buffer.limit()];
- int pos = buffer.position();
- buffer.position(0);
- buffer.get(dst);
- buffer.position(pos);
- return dst;
- }
-
- public static float[] floatBufferToArray(FloatBuffer buffer) {
- float[] dst = new float[buffer.limit()];
- int pos = buffer.position();
- buffer.position(0);
- buffer.get(dst);
- buffer.position(pos);
- return dst;
- }
-
- public static double distSq(double x1, double y1, double z1, double x2, double y2, double z2) {
- return Math.pow(x1 - x2, 2) +
- Math.pow(y1 - y2, 2) +
- Math.pow(z1 - z2, 2);
- }
-}