From 5bea63de0d78487b91dd701a8f6931b9314f2be5 Mon Sep 17 00:00:00 2001 From: makamys Date: Thu, 9 Jun 2022 12:57:52 +0200 Subject: Rebrand pt. 1: Rename mod to Neodymium --- src/main/java/makamys/lodmod/LODMod.java | 239 ------- .../java/makamys/lodmod/MixinConfigPlugin.java | 72 -- .../java/makamys/lodmod/ducks/IWorldRenderer.java | 13 - .../java/makamys/lodmod/mixin/MixinChunkCache.java | 29 - .../makamys/lodmod/mixin/MixinEntityRenderer.java | 35 - .../makamys/lodmod/mixin/MixinRenderBlocks.java | 29 - .../makamys/lodmod/mixin/MixinRenderGlobal.java | 40 -- .../lodmod/mixin/MixinRenderGlobal_OptiFine.java | 25 - .../makamys/lodmod/mixin/MixinWorldRenderer.java | 181 ----- .../java/makamys/lodmod/renderer/ChunkMesh.java | 455 ------------- .../makamys/lodmod/renderer/FarChunkCache.java | 12 - .../makamys/lodmod/renderer/FarWorldRenderer.java | 14 - .../makamys/lodmod/renderer/GPUMemoryManager.java | 215 ------ .../java/makamys/lodmod/renderer/LODChunk.java | 184 ------ .../java/makamys/lodmod/renderer/LODRegion.java | 195 ------ .../java/makamys/lodmod/renderer/LODRenderer.java | 730 --------------------- src/main/java/makamys/lodmod/renderer/Mesh.java | 44 -- .../java/makamys/lodmod/renderer/MeshQuad.java | 426 ------------ .../makamys/lodmod/renderer/SimpleChunkMesh.java | 350 ---------- .../java/makamys/lodmod/util/BufferWriter.java | 46 -- src/main/java/makamys/lodmod/util/GuiHelper.java | 61 -- src/main/java/makamys/lodmod/util/MCUtil.java | 20 - src/main/java/makamys/lodmod/util/SpriteUtil.java | 55 -- src/main/java/makamys/lodmod/util/Util.java | 88 --- src/main/java/makamys/neodymium/LODMod.java | 239 +++++++ .../java/makamys/neodymium/MixinConfigPlugin.java | 72 ++ .../makamys/neodymium/ducks/IWorldRenderer.java | 13 + .../makamys/neodymium/mixin/MixinChunkCache.java | 29 + .../neodymium/mixin/MixinEntityRenderer.java | 35 + .../makamys/neodymium/mixin/MixinRenderBlocks.java | 29 + .../makamys/neodymium/mixin/MixinRenderGlobal.java | 40 ++ .../mixin/MixinRenderGlobal_OptiFine.java | 25 + .../neodymium/mixin/MixinWorldRenderer.java | 181 +++++ .../java/makamys/neodymium/renderer/ChunkMesh.java | 455 +++++++++++++ .../makamys/neodymium/renderer/FarChunkCache.java | 12 + .../neodymium/renderer/FarWorldRenderer.java | 14 + .../neodymium/renderer/GPUMemoryManager.java | 215 ++++++ .../java/makamys/neodymium/renderer/LODChunk.java | 184 ++++++ .../java/makamys/neodymium/renderer/LODRegion.java | 195 ++++++ .../makamys/neodymium/renderer/LODRenderer.java | 730 +++++++++++++++++++++ src/main/java/makamys/neodymium/renderer/Mesh.java | 44 ++ .../java/makamys/neodymium/renderer/MeshQuad.java | 426 ++++++++++++ .../neodymium/renderer/SimpleChunkMesh.java | 350 ++++++++++ .../java/makamys/neodymium/util/BufferWriter.java | 46 ++ .../java/makamys/neodymium/util/GuiHelper.java | 61 ++ src/main/java/makamys/neodymium/util/MCUtil.java | 20 + .../java/makamys/neodymium/util/SpriteUtil.java | 55 ++ src/main/java/makamys/neodymium/util/Util.java | 88 +++ src/main/resources/lodmod.mixin.json | 11 - src/main/resources/mcmod.info | 4 +- src/main/resources/neodymium.mixin.json | 11 + 51 files changed, 3571 insertions(+), 3571 deletions(-) delete mode 100644 src/main/java/makamys/lodmod/LODMod.java delete mode 100644 src/main/java/makamys/lodmod/MixinConfigPlugin.java delete mode 100644 src/main/java/makamys/lodmod/ducks/IWorldRenderer.java delete mode 100644 src/main/java/makamys/lodmod/mixin/MixinChunkCache.java delete mode 100644 src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java delete mode 100644 src/main/java/makamys/lodmod/mixin/MixinRenderBlocks.java delete mode 100644 src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java delete mode 100644 src/main/java/makamys/lodmod/mixin/MixinRenderGlobal_OptiFine.java delete mode 100644 src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java delete mode 100644 src/main/java/makamys/lodmod/renderer/ChunkMesh.java delete mode 100644 src/main/java/makamys/lodmod/renderer/FarChunkCache.java delete mode 100644 src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java delete mode 100644 src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java delete mode 100644 src/main/java/makamys/lodmod/renderer/LODChunk.java delete mode 100644 src/main/java/makamys/lodmod/renderer/LODRegion.java delete mode 100644 src/main/java/makamys/lodmod/renderer/LODRenderer.java delete mode 100644 src/main/java/makamys/lodmod/renderer/Mesh.java delete mode 100644 src/main/java/makamys/lodmod/renderer/MeshQuad.java delete mode 100644 src/main/java/makamys/lodmod/renderer/SimpleChunkMesh.java delete mode 100644 src/main/java/makamys/lodmod/util/BufferWriter.java delete mode 100644 src/main/java/makamys/lodmod/util/GuiHelper.java delete mode 100644 src/main/java/makamys/lodmod/util/MCUtil.java delete mode 100644 src/main/java/makamys/lodmod/util/SpriteUtil.java delete mode 100644 src/main/java/makamys/lodmod/util/Util.java create mode 100644 src/main/java/makamys/neodymium/LODMod.java create mode 100644 src/main/java/makamys/neodymium/MixinConfigPlugin.java create mode 100644 src/main/java/makamys/neodymium/ducks/IWorldRenderer.java create mode 100644 src/main/java/makamys/neodymium/mixin/MixinChunkCache.java create mode 100644 src/main/java/makamys/neodymium/mixin/MixinEntityRenderer.java create mode 100644 src/main/java/makamys/neodymium/mixin/MixinRenderBlocks.java create mode 100644 src/main/java/makamys/neodymium/mixin/MixinRenderGlobal.java create mode 100644 src/main/java/makamys/neodymium/mixin/MixinRenderGlobal_OptiFine.java create mode 100644 src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java create mode 100644 src/main/java/makamys/neodymium/renderer/ChunkMesh.java create mode 100644 src/main/java/makamys/neodymium/renderer/FarChunkCache.java create mode 100644 src/main/java/makamys/neodymium/renderer/FarWorldRenderer.java create mode 100644 src/main/java/makamys/neodymium/renderer/GPUMemoryManager.java create mode 100644 src/main/java/makamys/neodymium/renderer/LODChunk.java create mode 100644 src/main/java/makamys/neodymium/renderer/LODRegion.java create mode 100644 src/main/java/makamys/neodymium/renderer/LODRenderer.java create mode 100644 src/main/java/makamys/neodymium/renderer/Mesh.java create mode 100644 src/main/java/makamys/neodymium/renderer/MeshQuad.java create mode 100644 src/main/java/makamys/neodymium/renderer/SimpleChunkMesh.java create mode 100644 src/main/java/makamys/neodymium/util/BufferWriter.java create mode 100644 src/main/java/makamys/neodymium/util/GuiHelper.java create mode 100644 src/main/java/makamys/neodymium/util/MCUtil.java create mode 100644 src/main/java/makamys/neodymium/util/SpriteUtil.java create mode 100644 src/main/java/makamys/neodymium/util/Util.java delete mode 100644 src/main/resources/lodmod.mixin.json create mode 100644 src/main/resources/neodymium.mixin.json (limited to 'src') 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 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 myTargets, Set otherTargets) { - // TODO Auto-generated method stub - - } - - @Override - public List getMixins() { - List 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 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 = "*", 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 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 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 nameList = (List) ((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 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 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> quadsByPlaneDir = new ArrayList<>(); // XY, XZ, YZ - for(int i = 0; i < 3; i++) { - quadsByPlaneDir.add(new ArrayList()); - } - 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 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 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 quads) { - int quadCount = 0; - for(MeshQuad quad : quads) { - if(!quad.deleted) { - quadCount++; - } - } - return quadCount; - } - - private NBTBase toNBT(List 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 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 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(), 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 getChunkMesh(int theX, int theY, int theZ) { - WorldRenderer wr = new WorldRenderer(Minecraft.getMinecraft().theWorld, new ArrayList(), 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 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 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 spriteList) { - this.x = nbt.getInteger("x"); - this.z = nbt.getInteger("z"); - - loadChunkMeshesNBT(nbt.getCompoundTag("chunkMeshes"), spriteList); - } - - private void loadChunkMeshesNBT(NBTTagCompound chunkMeshesCompound, List 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 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 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.lo