From 1cb15f76be86920af5dde287ca6403b5657145ea Mon Sep 17 00:00:00 2001 From: makamys Date: Thu, 9 Jun 2022 13:01:33 +0200 Subject: Rebrand pt.2: Rename things in code --- src/main/java/makamys/neodymium/LODMod.java | 239 ------- src/main/java/makamys/neodymium/Neodymium.java | 239 +++++++ .../makamys/neodymium/mixin/MixinChunkCache.java | 8 +- .../neodymium/mixin/MixinEntityRenderer.java | 10 +- .../makamys/neodymium/mixin/MixinRenderBlocks.java | 6 +- .../makamys/neodymium/mixin/MixinRenderGlobal.java | 8 +- .../mixin/MixinRenderGlobal_OptiFine.java | 4 +- .../neodymium/mixin/MixinWorldRenderer.java | 20 +- .../java/makamys/neodymium/renderer/ChunkMesh.java | 6 +- .../neodymium/renderer/GPUMemoryManager.java | 6 +- .../java/makamys/neodymium/renderer/LODChunk.java | 184 ------ .../java/makamys/neodymium/renderer/LODRegion.java | 195 ------ .../makamys/neodymium/renderer/LODRenderer.java | 730 --------------------- .../java/makamys/neodymium/renderer/NeoChunk.java | 184 ++++++ .../java/makamys/neodymium/renderer/NeoRegion.java | 195 ++++++ .../makamys/neodymium/renderer/NeoRenderer.java | 730 +++++++++++++++++++++ .../neodymium/renderer/SimpleChunkMesh.java | 6 +- src/main/java/makamys/neodymium/util/Util.java | 4 +- 18 files changed, 1387 insertions(+), 1387 deletions(-) delete mode 100644 src/main/java/makamys/neodymium/LODMod.java create mode 100644 src/main/java/makamys/neodymium/Neodymium.java delete mode 100644 src/main/java/makamys/neodymium/renderer/LODChunk.java delete mode 100644 src/main/java/makamys/neodymium/renderer/LODRegion.java delete mode 100644 src/main/java/makamys/neodymium/renderer/LODRenderer.java create mode 100644 src/main/java/makamys/neodymium/renderer/NeoChunk.java create mode 100644 src/main/java/makamys/neodymium/renderer/NeoRegion.java create mode 100644 src/main/java/makamys/neodymium/renderer/NeoRenderer.java (limited to 'src/main') diff --git a/src/main/java/makamys/neodymium/LODMod.java b/src/main/java/makamys/neodymium/LODMod.java deleted file mode 100644 index 47c948b..0000000 --- a/src/main/java/makamys/neodymium/LODMod.java +++ /dev/null @@ -1,239 +0,0 @@ -package makamys.neodymium; - -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.neodymium.renderer.LODRenderer; -import makamys.neodymium.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/neodymium/Neodymium.java b/src/main/java/makamys/neodymium/Neodymium.java new file mode 100644 index 0000000..236d85b --- /dev/null +++ b/src/main/java/makamys/neodymium/Neodymium.java @@ -0,0 +1,239 @@ +package makamys.neodymium; + +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.neodymium.renderer.NeoRenderer; +import makamys.neodymium.util.SpriteUtil; + +@Mod(modid = Neodymium.MODID, version = Neodymium.VERSION) +public class Neodymium +{ + public static final String MODID = "neodymium"; + public static final String VERSION = "0.0"; + + public static final Logger LOGGER = LogManager.getLogger("neodymium"); + + public static NeoRenderer 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 NeoRenderer(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/neodymium/mixin/MixinChunkCache.java b/src/main/java/makamys/neodymium/mixin/MixinChunkCache.java index b4a7368..331e3cf 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinChunkCache.java +++ b/src/main/java/makamys/neodymium/mixin/MixinChunkCache.java @@ -4,9 +4,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import makamys.neodymium.LODMod; +import makamys.neodymium.Neodymium; import makamys.neodymium.renderer.FarChunkCache; -import makamys.neodymium.renderer.LODRenderer; +import makamys.neodymium.renderer.NeoRenderer; import net.minecraft.world.ChunkCache; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -17,8 +17,8 @@ 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(Neodymium.isActive() && FarChunkCache.class.isInstance(this.getClass()) && chunk.isEmpty()) { + Chunk myChunk = Neodymium.renderer.getChunkFromChunkCoords(p1, p2); if(myChunk != null) { chunk = myChunk; } diff --git a/src/main/java/makamys/neodymium/mixin/MixinEntityRenderer.java b/src/main/java/makamys/neodymium/mixin/MixinEntityRenderer.java index 66d95ae..6e5cf7b 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinEntityRenderer.java +++ b/src/main/java/makamys/neodymium/mixin/MixinEntityRenderer.java @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import makamys.neodymium.LODMod; +import makamys.neodymium.Neodymium; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.entity.EntityLivingBase; @@ -21,15 +21,15 @@ abstract class MixinEntityRenderer { @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(); + if(Neodymium.isActive()) { + farPlaneDistance *= Neodymium.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); + if(Neodymium.isActive()) { + Neodymium.renderer.afterSetupFog(mode, alpha, farPlaneDistance); } } } diff --git a/src/main/java/makamys/neodymium/mixin/MixinRenderBlocks.java b/src/main/java/makamys/neodymium/mixin/MixinRenderBlocks.java index 0f8ff41..fdfbe65 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinRenderBlocks.java +++ b/src/main/java/makamys/neodymium/mixin/MixinRenderBlocks.java @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import makamys.neodymium.LODMod; +import makamys.neodymium.Neodymium; import makamys.neodymium.renderer.FarChunkCache; import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; @@ -19,8 +19,8 @@ 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); + if(Neodymium.isActive()) { + return Neodymium.renderer.shouldSideBeRendered(block, ba, x, y, z, w); } else { return block.shouldSideBeRendered(ba, x, y, z, w); } diff --git a/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal.java b/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal.java index dc561a2..03b8aac 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal.java +++ b/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal.java @@ -12,7 +12,7 @@ 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.neodymium.LODMod; +import makamys.neodymium.Neodymium; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.WorldRenderer; @@ -26,15 +26,15 @@ abstract class MixinRenderGlobal { @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()) { + if(Neodymium.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); + if(Neodymium.isActive()) { + Neodymium.renderer.preRenderSortedRenderers(renderPass, partialTickTime, sortedWorldRenderers); } } } diff --git a/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal_OptiFine.java b/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal_OptiFine.java index dad164c..d63e3ad 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal_OptiFine.java +++ b/src/main/java/makamys/neodymium/mixin/MixinRenderGlobal_OptiFine.java @@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import makamys.neodymium.LODMod; +import makamys.neodymium.Neodymium; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.RenderGlobal; @@ -17,7 +17,7 @@ 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()) { + if(Neodymium.shouldRenderVanillaWorld()) { GL11.glCallLists(buffer); } } diff --git a/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java b/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java index 47450c3..7d1ffd8 100644 --- a/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java +++ b/src/main/java/makamys/neodymium/mixin/MixinWorldRenderer.java @@ -12,12 +12,12 @@ 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.neodymium.LODMod; +import makamys.neodymium.Neodymium; import makamys.neodymium.ducks.IWorldRenderer; import makamys.neodymium.renderer.ChunkMesh; import makamys.neodymium.renderer.FarChunkCache; import makamys.neodymium.renderer.FarWorldRenderer; -import makamys.neodymium.renderer.LODRenderer; +import makamys.neodymium.renderer.NeoRenderer; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; @@ -71,7 +71,7 @@ abstract class MixinWorldRenderer implements IWorldRenderer { private void preUpdateRenderer(CallbackInfo ci) { saveDrawnStatus(); - if(LODMod.isActive()) { + if(Neodymium.isActive()) { if(needsUpdate) { if(chunkMeshes != null) { chunkMeshes.clear(); @@ -88,9 +88,9 @@ abstract class MixinWorldRenderer implements IWorldRenderer { private void postUpdateRenderer(CallbackInfo ci) { notifyIfDrawnStatusChanged(); - if(LODMod.isActive()) { + if(Neodymium.isActive()) { if(chunkMeshes != null) { - LODMod.renderer.onWorldRendererPost(WorldRenderer.class.cast(this)); + Neodymium.renderer.onWorldRendererPost(WorldRenderer.class.cast(this)); chunkMeshes.clear(); } } @@ -98,7 +98,7 @@ abstract class MixinWorldRenderer implements IWorldRenderer { @Inject(method = "postRenderBlocks", at = @At(value = "HEAD")) private void prePostRenderBlocks(int pass, EntityLivingBase entity, CallbackInfo ci) { - if(LODMod.isActive() && !LODMod.disableChunkMeshes) { + if(Neodymium.isActive() && !Neodymium.disableChunkMeshes) { if(chunkMeshes != null) { chunkMeshes.add(ChunkMesh.fromTessellator(pass, WorldRenderer.class.cast(this), Tessellator.instance)); } @@ -143,8 +143,8 @@ abstract class MixinWorldRenderer implements IWorldRenderer { @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); + if(Neodymium.isActive()) { + Neodymium.renderer.onWorldRendererChanged(WorldRenderer.class.cast(this), NeoRenderer.WorldRendererChange.DELETED); } } @@ -169,8 +169,8 @@ abstract class MixinWorldRenderer implements IWorldRenderer { 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); + if(Neodymium.isActive() && drawn != savedDrawnStatus) { + Neodymium.renderer.onWorldRendererChanged(WorldRenderer.class.cast(this), drawn ? NeoRenderer.WorldRendererChange.VISIBLE : NeoRenderer.WorldRendererChange.INVISIBLE); } } diff --git a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java index 6c4cd59..6d5dc2d 100644 --- a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java +++ b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java @@ -14,7 +14,7 @@ import java.util.stream.Collectors; import org.lwjgl.BufferUtils; -import makamys.neodymium.LODMod; +import makamys.neodymium.Neodymium; import makamys.neodymium.MixinConfigPlugin; import makamys.neodymium.ducks.IWorldRenderer; import makamys.neodymium.util.BufferWriter; @@ -78,12 +78,12 @@ public class ChunkMesh extends Mesh { int yOffset = wr.posY; int zOffset = wr.posZ; - boolean fr = MixinConfigPlugin.isOptiFinePresent() && LODMod.ofFastRender; + boolean fr = MixinConfigPlugin.isOptiFinePresent() && Neodymium.ofFastRender; int tessellatorXOffset = fr ? xOffset : 0; int tessellatorYOffset = fr ? yOffset : 0; int tessellatorZOffset = fr ? zOffset : 0; - boolean optimize = LODMod.optimizeChunkMeshes; + boolean optimize = Neodymium.optimizeChunkMeshes; ChunkMesh.Flags flags = new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals); diff --git a/src/main/java/makamys/neodymium/renderer/GPUMemoryManager.java b/src/main/java/makamys/neodymium/renderer/GPUMemoryManager.java index 75b1f64..1bb2623 100644 --- a/src/main/java/makamys/neodymium/renderer/GPUMemoryManager.java +++ b/src/main/java/makamys/neodymium/renderer/GPUMemoryManager.java @@ -6,7 +6,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; -import makamys.neodymium.LODMod; +import makamys.neodymium.Neodymium; import makamys.neodymium.renderer.Mesh.GPUStatus; import makamys.neodymium.util.GuiHelper; @@ -23,7 +23,7 @@ public class GPUMemoryManager { public GPUMemoryManager() { VBO = glGenBuffers(); - bufferSize = LODMod.VRAMSize * 1024 * 1024; + bufferSize = Neodymium.VRAMSize * 1024 * 1024; glBindBuffer(GL_ARRAY_BUFFER, VBO); @@ -109,7 +109,7 @@ public class GPUMemoryManager { 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; + Neodymium.renderer.destroyPending = true; // TODO restart renderer with more VRAM allocated when this happens. return; } diff --git a/src/main/java/makamys/neodymium/renderer/LODChunk.java b/src/main/java/makamys/neodymium/renderer/LODChunk.java deleted file mode 100644 index 5dd3762..0000000 --- a/src/main/java/makamys/neodymium/renderer/LODChunk.java +++ /dev/null @@ -1,184 +0,0 @@ -package makamys.neodymium.renderer; - -import java.util.List; - -import makamys.neodymium.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.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 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/neodymium/renderer/LODRegion.java b/src/main/java/makamys/neodymium/renderer/LODRegion.java deleted file mode 100644 index 22316f7..0000000 --- a/src/main/java/makamys/neodymium/renderer/LODRegion.java +++ /dev/null @@ -1,195 +0,0 @@ -package makamys.neodymium.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.neodymium.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 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 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) ((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/neodymium/renderer/LODRenderer.java b/src/main/java/makamys/neodymium/renderer/LODRenderer.java deleted file mode 100644 index 974c408..0000000 --- a/src/main/java/makamys/neodymium/renderer/LODRenderer.java +++ /dev/null @@ -1,730 +0,0 @@ -package makamys.neodymium.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.neodymium.LODMod; -import makamys.neodymium.ducks.IWorldRenderer; -import makamys.neodymium.renderer.Mesh.GPUStatus; -import makamys.neodymium.util.GuiHelper; -import makamys.neodymium.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[] sentMeshes = (List[])new ArrayList[] {new ArrayList(), new ArrayList()}; - GPUMemoryManager mem; - - List myChunks = new ArrayList(); - List pendingLODChunks = new ArrayList<>(); - - private boolean hasServerInited = false; - private Map loadedRegionsMap = new HashMap<>(); - - public World world; - - // TODO make these packets to make this work on dedicated servers - Queue farChunks = new ConcurrentLinkedQueue<>(); - - List 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 list : sentMeshes) { - list.sort(new MeshDistanceComparator(player.posX / 16, player.posY / 16, player.posZ / 16)); - } - } - - private void updateMeshes() { - for(List 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 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 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 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(sha