aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/makamys/lodmod/LODMod.java55
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinChunkCache.java5
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java25
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinMinecraftServer.java30
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java4
-rw-r--r--src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java19
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODChunk.java13
-rw-r--r--src/main/java/makamys/lodmod/renderer/MeshQuad.java5
-rw-r--r--src/main/java/makamys/lodmod/renderer/MyRenderer.java430
-rw-r--r--src/main/java/makamys/lodmod/util/SpriteUtil.java55
-rw-r--r--src/main/java/makamys/lodmod/util/Util.java26
-rw-r--r--src/main/resources/lodmod.mixin.json1
12 files changed, 275 insertions, 393 deletions
diff --git a/src/main/java/makamys/lodmod/LODMod.java b/src/main/java/makamys/lodmod/LODMod.java
index ab4fb07..e018832 100644
--- a/src/main/java/makamys/lodmod/LODMod.java
+++ b/src/main/java/makamys/lodmod/LODMod.java
@@ -1,29 +1,19 @@
package makamys.lodmod;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.OpenGlHelper;
-import net.minecraft.client.renderer.texture.TextureManager;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.init.Blocks;
-import net.minecraft.launchwrapper.Launch;
-import net.minecraft.util.MathHelper;
-import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.world.WorldEvent;
-import java.nio.IntBuffer;
-
-import org.lwjgl.BufferUtils;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GL12;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
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.ClientTickEvent;
+import cpw.mods.fml.common.gameevent.TickEvent;
+import makamys.lodmod.renderer.MyRenderer;
+import makamys.lodmod.util.SpriteUtil;
@Mod(modid = LODMod.MODID, version = LODMod.VERSION)
public class LODMod
@@ -31,14 +21,45 @@ 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 MyRenderer renderer;
+
@EventHandler
public void init(FMLInitializationEvent event)
{
FMLCommonHandler.instance().bus().register(this);
+ MinecraftForge.EVENT_BUS.register(this);
+ }
+
+ @SubscribeEvent
+ public void onWorldLoad(WorldEvent.Load event) {
+ if(!event.world.isRemote) return;
+
+ SpriteUtil.init();
+ if(renderer != null) {
+ LOGGER.warn("Renderer didn't get destroyed last time");
+ renderer.destroy();
+ }
+ renderer = new MyRenderer();
}
@SubscribeEvent
- public void onClientTick(ClientTickEvent event) {
+ public void onWorldUnload(WorldEvent.Unload event) {
+ if(!event.world.isRemote) return;
+ renderer.destroy();
+ renderer = null;
+ }
+
+ public static boolean isActive() {
+ return renderer != null;
+ }
+
+ @SubscribeEvent
+ public void onWorldUnload(TickEvent.ServerTickEvent event) {
+ if(isActive()) {
+ renderer.serverTick();
+ }
}
}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java b/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java
index bbfcca1..c5b6f33 100644
--- a/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java
+++ b/src/main/java/makamys/lodmod/mixin/MixinChunkCache.java
@@ -4,6 +4,7 @@ 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.MyRenderer;
import net.minecraft.world.ChunkCache;
@@ -16,8 +17,8 @@ abstract class MixinChunkCache {
@Redirect(method = "<init>*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getChunkFromChunkCoords(II)Lnet/minecraft/world/chunk/Chunk;"))
private Chunk redirectGetChunkFromChunkCoords(World world, int p1, int p2) {
Chunk chunk = world.getChunkFromChunkCoords(p1, p2);
- if(FarChunkCache.class.isInstance(this.getClass()) && chunk.isEmpty()) {
- Chunk myChunk = MyRenderer.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;
}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java b/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java
index 544d131..4fe081c 100644
--- a/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java
+++ b/src/main/java/makamys/lodmod/mixin/MixinEntityRenderer.java
@@ -8,6 +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.lodmod.LODMod;
import makamys.lodmod.renderer.MyRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
@@ -22,23 +23,29 @@ abstract class MixinEntityRenderer {
@Inject(method = "setupCameraTransform", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/EntityRenderer;farPlaneDistance:F", shift = At.Shift.AFTER, args = "log=true", ordinal = 0))
private void onConstructed(CallbackInfo ci) {
- farPlaneDistance *= 4;
+ if(LODMod.isActive()) {
+ farPlaneDistance *= 4;
+ }
}
@Inject(method = "renderWorld", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glAlphaFunc(IF)V", shift = At.Shift.AFTER, ordinal = 1))
private void afterSortAndRender(float alpha, long something, CallbackInfo ci) {
- Minecraft.getMinecraft().entityRenderer.enableLightmap((double)alpha);
- MyRenderer.beforeRenderTerrain();
- Minecraft.getMinecraft().entityRenderer.disableLightmap((double)alpha);
+ if(LODMod.isActive()) {
+ Minecraft.getMinecraft().entityRenderer.enableLightmap((double)alpha);
+ LODMod.renderer.beforeRenderTerrain();
+ Minecraft.getMinecraft().entityRenderer.disableLightmap((double)alpha);
+ }
}
@Redirect(method = "setupFog", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/GL11;glFogf(IF)V"))
private void afterSetupFog(int pname, float param, int mode, float alpha) {
- EntityLivingBase var3 = Minecraft.getMinecraft().renderViewEntity;
- if(pname == GL11.GL_FOG_START && mode != 999 && mode != -1 && !var3.isPotionActive(Potion.blindness) && !Minecraft.getMinecraft().theWorld.provider.doesXZShowFog((int)var3.posX, (int)var3.posZ)) {
- GL11.glFogf(pname, farPlaneDistance * 0.2f);
- } else {
- GL11.glFogf(pname, param);
+ if(LODMod.isActive()) {
+ EntityLivingBase var3 = Minecraft.getMinecraft().renderViewEntity;
+ if(pname == GL11.GL_FOG_START && mode != 999 && mode != -1 && !var3.isPotionActive(Potion.blindness) && !Minecraft.getMinecraft().theWorld.provider.doesXZShowFog((int)var3.posX, (int)var3.posZ)) {
+ GL11.glFogf(pname, farPlaneDistance * 0.2f);
+ } else {
+ GL11.glFogf(pname, param);
+ }
}
}
}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinMinecraftServer.java b/src/main/java/makamys/lodmod/mixin/MixinMinecraftServer.java
deleted file mode 100644
index 747cbb8..0000000
--- a/src/main/java/makamys/lodmod/mixin/MixinMinecraftServer.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package makamys.lodmod.mixin;
-
-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.callback.CallbackInfo;
-
-import makamys.lodmod.renderer.MyRenderer;
-import net.minecraft.server.MinecraftServer;
-
-@Mixin(MinecraftServer.class)
-abstract class MixinMinecraftServer {
-
- @Shadow
- boolean worldIsBeingDeleted;
-
- @Inject(method = "stopServer", at = @At("HEAD"))
- public void stopServer(CallbackInfo ci) {
- if(!worldIsBeingDeleted) {
- MyRenderer.onStopServer();
- }
- }
-
- @Inject(method = "updateTimeLightAndEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkSystem;networkTick()V"))
- public void preServerTick(CallbackInfo ci) {
- MyRenderer.serverTick();
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java b/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java
index f2b89fd..18f95a6 100644
--- a/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java
+++ b/src/main/java/makamys/lodmod/mixin/MixinRenderGlobal.java
@@ -4,7 +4,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
-import makamys.lodmod.renderer.MyRenderer;
+import makamys.lodmod.LODMod;
import net.minecraft.client.renderer.RenderGlobal;
@Mixin(RenderGlobal.class)
@@ -12,7 +12,7 @@ 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(MyRenderer.renderWorld) {
+ if(LODMod.isActive() && LODMod.renderer.renderWorld) {
thiz.renderAllRenderLists(p1, p2);
}
}
diff --git a/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java b/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
index abfcc4e..988b478 100644
--- a/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
+++ b/src/main/java/makamys/lodmod/mixin/MixinWorldRenderer.java
@@ -11,6 +11,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.lodmod.LODMod;
import makamys.lodmod.ducks.ITessellator;
import makamys.lodmod.ducks.IWorldRenderer;
import makamys.lodmod.renderer.ChunkMesh;
@@ -55,18 +56,24 @@ abstract class MixinWorldRenderer implements IWorldRenderer {
@Inject(method = "updateRenderer", at = @At(value = "HEAD"))
private void preUpdateRenderer(CallbackInfo ci) {
- chunkMeshes.clear();
+ if(LODMod.isActive()) {
+ chunkMeshes.clear();
+ }
}
@Inject(method = "updateRenderer", at = @At(value = "TAIL"))
private void postUpdateRenderer(CallbackInfo ci) {
- MyRenderer.onWorldRendererPost(WorldRenderer.class.cast(this));
- chunkMeshes.clear();
+ if(LODMod.isActive()) {
+ LODMod.renderer.onWorldRendererPost(WorldRenderer.class.cast(this));
+ chunkMeshes.clear();
+ }
}
@Inject(method = "postRenderBlocks", at = @At(value = "HEAD"))
private void prePostRenderBlocks(CallbackInfo ci) {
- chunkMeshes.add(((ITessellator)Tessellator.instance).toChunkMesh());
+ if(LODMod.isActive()) {
+ chunkMeshes.add(((ITessellator)Tessellator.instance).toChunkMesh());
+ }
}
@Redirect(method = "postRenderBlocks", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/Tessellator;draw()I"))
@@ -107,7 +114,9 @@ abstract class MixinWorldRenderer implements IWorldRenderer {
@Inject(method = "setDontDraw", at = @At(value = "HEAD"))
private void preSetDontDraw(CallbackInfo ci) {
- MyRenderer.onDontDraw(WorldRenderer.class.cast(this));
+ if(LODMod.isActive()) {
+ LODMod.renderer.onDontDraw(WorldRenderer.class.cast(this));
+ }
}
@Override
diff --git a/src/main/java/makamys/lodmod/renderer/LODChunk.java b/src/main/java/makamys/lodmod/renderer/LODChunk.java
index bae235c..4d8dbff 100644
--- a/src/main/java/makamys/lodmod/renderer/LODChunk.java
+++ b/src/main/java/makamys/lodmod/renderer/LODChunk.java
@@ -2,6 +2,7 @@ package makamys.lodmod.renderer;
import java.util.List;
+import makamys.lodmod.LODMod;
import net.minecraft.entity.Entity;
import net.minecraft.world.chunk.Chunk;
@@ -16,6 +17,8 @@ public class LODChunk {
SimpleChunkMesh simpleMesh;
ChunkMesh[] chunkMeshes = new ChunkMesh[32];
+ MyRenderer renderer = LODMod.renderer;
+
public LODChunk(int x, int z) {
this.x = x;
this.z = z;
@@ -33,14 +36,14 @@ public class LODChunk {
public void putChunkMeshes(int cy, List<ChunkMesh> newChunkMeshes) {
for(int i = 0; i < 2; i++) {
if(chunkMeshes[cy * 2 + i] != null) {
- MyRenderer.setMeshVisible(chunkMeshes[cy * 2 + i], false);
+ renderer.setMeshVisible(chunkMeshes[cy * 2 + i], false);
chunkMeshes[cy * 2 + i] = null;
}
}
for(int i = 0; i < newChunkMeshes.size(); i++) {
chunkMeshes[cy * 2 + i] = newChunkMeshes.get(i);
- MyRenderer.sendMeshToGPU(newChunkMeshes.get(i));
+ renderer.sendMeshToGPU(newChunkMeshes.get(i));
}
}
@@ -56,11 +59,11 @@ public class LODChunk {
public void tick(Entity player) {
double distSq = distSq(player);
if(distSq < Math.pow(32 * 16, 2)) {
- MyRenderer.setLOD(this, 2);
+ renderer.setLOD(this, 2);
} else if(distSq < Math.pow(64 * 16, 2)) {
- MyRenderer.setLOD(this, 1);
+ renderer.setLOD(this, 1);
} else {
- MyRenderer.setVisible(this, false);
+ renderer.setVisible(this, false);
}
}
diff --git a/src/main/java/makamys/lodmod/renderer/MeshQuad.java b/src/main/java/makamys/lodmod/renderer/MeshQuad.java
index a48815d..dfd5f0d 100644
--- a/src/main/java/makamys/lodmod/renderer/MeshQuad.java
+++ b/src/main/java/makamys/lodmod/renderer/MeshQuad.java
@@ -7,6 +7,7 @@ import java.util.Locale;
import java.util.Map;
import makamys.lodmod.renderer.MeshQuad.QuadPlaneComparator;
+import makamys.lodmod.util.SpriteUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
@@ -80,8 +81,8 @@ public class MeshQuad {
TextureAtlasSprite sprite = null;
Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
- spriteIndex = MyRenderer.getSpriteIndexForUV(avgU, avgV);
- sprite = MyRenderer.getSprite(spriteIndex);
+ spriteIndex = SpriteUtil.getSpriteIndexForUV(avgU, avgV);
+ sprite = SpriteUtil.getSprite(spriteIndex);
if(sprite == null) {
System.out.println("Error: couldn't find sprite");
diff --git a/src/main/java/makamys/lodmod/renderer/MyRenderer.java b/src/main/java/makamys/lodmod/renderer/MyRenderer.java
index a1ce086..3a23a25 100644
--- a/src/main/java/makamys/lodmod/renderer/MyRenderer.java
+++ b/src/main/java/makamys/lodmod/renderer/MyRenderer.java
@@ -3,149 +3,148 @@ package makamys.lodmod.renderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.texture.ITextureObject;
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.tileentity.TileEntity;
-import net.minecraft.util.ChunkCoordinates;
-import net.minecraft.util.ResourceLocation;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.ChunkProviderServer;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
-import java.nio.file.Files;
-import java.nio.file.Paths;
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.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.SynchronousQueue;
-import java.util.stream.Collectors;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.BufferUtils;
-import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.ARBDebugOutputCallback;
-import org.lwjgl.opengl.ARBShaderObjects;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GLContext;
import org.lwjgl.util.vector.Matrix4f;
import makamys.lodmod.ducks.IWorldRenderer;
import makamys.lodmod.util.Util;
-import static org.lwjgl.opengl.ARBBufferObject.*;
-import static org.lwjgl.opengl.ARBVertexBufferObject.*;
import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
-import static org.lwjgl.util.glu.GLU.*;
public class MyRenderer {
- private static boolean hasInited = false;
-
- private static boolean[] wasDown = new boolean[256];
- private static int renderQuads = 0;
-
- public static boolean renderWorld = true;
- public static boolean renderLOD = true;
-
- //private static int[] spriteIndexMap;
- public static List<TextureAtlasSprite> sprites;
-
- static private Map<Long, Integer> uv2spriteIndex = new HashMap<>();
-
- //static ChunkMesh mesh;
-
- private static void destroy() {
- glDeleteProgram(shaderProgram);
+ private boolean hasInited = false;
+
+ private boolean[] wasDown = new boolean[256];
+ private int renderQuads = 0;
+
+ public boolean renderWorld = true;
+ public boolean renderLOD = true;
+
+ private static int BUFFER_SIZE = 1024 * 1024 * 1024;
+ private static int MAX_MESHES = 100000;
+
+ private int VAO, VBO, EBO, shaderProgram;
+ private IntBuffer piFirst, piCount;
+
+ List<Chunk> myChunks = new ArrayList<Chunk>();
+ List<LODChunk> pendingLODChunks = new ArrayList<>();
+
+ private boolean hasServerInited = false;
+ private HashMap<ChunkCoordIntPair, LODRegion> loadedRegionsMap = new HashMap<>();
+
+ // TODO make these packets to make this work on dedicated servers
+ Queue<Chunk> farChunks = new ConcurrentLinkedQueue<>();
+
+ List<ChunkCoordIntPair> serverChunkLoadQueue = new ArrayList<>();
+
+ private double lastSortX = Double.NaN;
+ private double lastSortY = Double.NaN;
+ private double lastSortZ = Double.NaN;
+
+ public MyRenderer(){
+ hasInited = init();
+ }
+
+ public void beforeRenderTerrain() {
+ if(hasInited) {
+ mainLoop();
+ handleKeyboard();
+ if(renderLOD) {
+ render();
+ }
+ }
+ }
+
+ private void mainLoop() {
+ while(!farChunks.isEmpty()) {
+ LODChunk lodChunk = receiveFarChunk(farChunks.remove());
+ sendChunkToGPU(lodChunk);
+ }
+
+ List<Object> players = Minecraft.getMinecraft().getIntegratedServer().getConfigurationManager().playerEntityList;
+ if(!players.isEmpty()) {
+ Entity player = (Entity)players.get(0);
+
+ List<ChunkCoordIntPair> newServerChunkLoadQueue = new ArrayList<>();
+
+ if(Double.isNaN(lastSortX) || getLastSortDistanceSq(player) > 16 * 16) {
+ int centerX = (int)Math.floor(player.posX / 16.0);
+ int centerZ = (int)Math.floor(player.posZ / 16.0);
+
+ int range = 64;
+ for(int x = -range; x <= range; x++) {
+ for(int z = -range; z <= range; z++) {
+ int chunkX = centerX + x;
+ int chunkZ = centerZ + z;
+
+ if(getLODChunk(chunkX, chunkZ).chunk == null) {
+ newServerChunkLoadQueue.add(new ChunkCoordIntPair(chunkX, chunkZ));
+ }
+ }
+ }
+ Collections.sort(newServerChunkLoadQueue, new ChunkCoordDistanceComparator(player));
+ setServerChunkLoadQueue(newServerChunkLoadQueue);
+
+ lastSortX = player.posX;
+ lastSortY = player.posY;
+ lastSortZ = player.posZ;
+
+ loadedRegionsMap.forEach((k, v) -> v.tick(player));
+ }
+ }
+ }
+
+ public void destroy() {
+ /*glDeleteProgram(shaderProgram);
glDeleteVertexArrays(VAO);
- glDeleteBuffers(VBO);
+ glDeleteBuffers(VBO);*/
}
- private static void mainLoop() {
+ private void handleKeyboard() {
if(Keyboard.isKeyDown(Keyboard.KEY_F) && !wasDown[Keyboard.KEY_F]) {
renderLOD = !renderLOD;
}
if(Keyboard.isKeyDown(Keyboard.KEY_V) && !wasDown[Keyboard.KEY_V]) {
renderWorld = !renderWorld;
}
- if(hasInited) {
- /*if(Keyboard.isKeyDown(Keyboard.KEY_X) && !wasDown[Keyboard.KEY_X]) {
- renderQuads--;
- if(renderQuads < 0) {
- renderQuads = 0;
- }
- }
- if(Keyboard.isKeyDown(Keyboard.KEY_C) && !wasDown[Keyboard.KEY_C]) {
- renderQuads++;
- if(renderQuads > mesh.quadCount) {
- renderQuads = mesh.quadCount;
- }
- }*/
- }
-
for(int i = 0; i < 256; i++) {
wasDown[i] = Keyboard.isKeyDown(i);
}
}
- private static void render() {
+ private void render() {
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
- //GL11.glDisable(GL11.GL_CULL_FACE);
- //GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
- //GL11.glColor4f(0, 1, 0, 1); // change this for your colour
- //GL11.glLineWidth(9.0F);
- //GL11.glDepthMask(false);
- float z = 0;
-
- /*GL11.glBegin(GL11.GL_TRIANGLES);
- GL11.glVertex3f(-0.9f,-0.9f,0);
- GL11.glVertex3f(0.9f,0.9f,0);
- GL11.glVertex3f(-0.9f,0.9f,0);
- GL11.glEnd();*/
-
- //glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
@@ -166,7 +165,6 @@ public class MyRenderer {
FloatBuffer projBuf = BufferUtils.createFloatBuffer(16);
glGetFloat(GL_PROJECTION_MATRIX, projBuf);
- //modelView.flip();
IntBuffer viewportBuf = BufferUtils.createIntBuffer(16);
glGetInteger(GL_VIEWPORT, viewportBuf);
@@ -192,7 +190,6 @@ public class MyRenderer {
glUniformMatrix4(u_modelView, false, modelView);
glUniformMatrix4(u_proj, false, projBuf);
glUniformMatrix4(u_projInv, false, projInvBuf);
- //glUniform4(u_viewport, viewportBuf);
glUniform4f(u_viewport, viewportBuf.get(0),viewportBuf.get(1),viewportBuf.get(2),viewportBuf.get(3));
glUniform4(u_fogColor, fogColorBuf);
glUniform2(u_fogStartEnd, fogStartEnd);
@@ -207,15 +204,8 @@ public class MyRenderer {
}
glBindVertexArray(VAO);
- //glEnableVertexAttribArray(0);
- //glDrawArrays(GL_TRIANGLES, 0, 3);
- //glActiveTexture(GL_TEXTURE1);
- //ITextureObject hmm = Minecraft.getMinecraft().getTextureManager().getTexture(new ResourceLocation("dynamic/lightMap_1"));
- //glBindTexture(GL_TEXTURE_2D, hmm.getGlTextureId());
- //glDrawArrays(GL_TRIANGLES, 0, 6*renderQuads);
glMultiDrawArrays(GL_TRIANGLES, piFirst, piCount);
- //glDisableVertexAttribArray(0);
glBindVertexArray(0);
glUseProgram(0);
@@ -225,71 +215,13 @@ public class MyRenderer {
}
- private static int VAO, VBO, EBO, shaderProgram;
- private static IntBuffer piFirst, piCount;
-
- private static String readFile(String path){
- try {
- return new String(Files.readAllBytes(Util.getResourcePath(path)));
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
-
- private static byte[] byteBufferToArray(ByteBuffer buffer) {
- byte[] dst = new byte[buffer.remaining()];
- buffer.get(dst);
- buffer.flip();
- return dst;
- }
-
- private static int[] intBufferToArray(IntBuffer buffer) {
- int[] dst = new int[buffer.remaining()];
- buffer.get(dst);
- buffer.flip();
- return dst;
- }
-
- private static int findSpriteIndexForUV(float u, float v) {
- Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
-
- int spriteIndex = 0;
- for(TextureAtlasSprite tas : uploadedSprites.values()) {
- if(tas.getMinU() <= u && u <= tas.getMaxU() && tas.getMinV() <= v && v <= tas.getMaxV()) {
- break;
- }
- spriteIndex++;
- }
- return spriteIndex;
- }
-
- public static int getSpriteIndexForUV(float u, float v){
- long key = ChunkCoordIntPair.chunkXZ2Int((int)(u * Integer.MAX_VALUE), (int)(v * Integer.MAX_VALUE));
- int index = uv2spriteIndex.getOrDefault(key, -1);
- if(index == -1) {
- index = findSpriteIndexForUV(u, v);
- uv2spriteIndex.put(key, index);
- }
- return index;
- }
-
- public static TextureAtlasSprite getSprite(int i){
- if(i >= 0 && i < sprites.size()) {
- return sprites.get(i);
- } else {
- return null;
- }
- }
-
- private static boolean init() {
+ public boolean init() {
Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
- sprites = uploadedSprites.values().stream().collect(Collectors.toList());
int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertexShader, readFile("shaders/chunk.vert"));
+ glShaderSource(vertexShader, Util.readFile("shaders/chunk.vert"));
glCompileShader(vertexShader);
if(glGetShaderi(vertexShader, GL_COMPILE_STATUS) == 0) {
@@ -299,7 +231,7 @@ public class MyRenderer {
int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragmentShader, readFile("shaders/chunk.frag"));
+ glShaderSource(fragmentShader, Util.readFile("shaders/chunk.frag"));
glCompileShader(fragmentShader);
if(glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == 0) {
@@ -326,60 +258,6 @@ public class MyRenderer {
EBO = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- boolean rough = false;
-
- /*
- List<Integer> chunkCoords = new ArrayList<>();*/
- /*chunkCoords.add(-19);
- chunkCoords.add(4);
- chunkCoords.add(15);*/
- /*List<Mesh> meshes = new ArrayList<Mesh>();
- for(Chunk chunk : myChunks) {
- Entity player = Minecraft.getMinecraft().thePlayer;
- int minRadius = 0;
- int radius = 10;
- if(minRadius <= Math.abs(chunk.xPosition - player.chunkCoordX) && Math.abs(chunk.xPosition - player.chunkCoordX) < radius && minRadius <= Math.abs(chunk.zPosition - player.chunkCoordZ) && Math.abs(chunk.zPosition - player.chunkCoordZ) < radius) {
- if(!rough) {
- for(int y = 0; y < 16; y++) {
- chunkCoords.add(chunk.xPosition);
- chunkCoords.add(y);
- chunkCoords.add(chunk.zPosition);
- }
- } else {
- meshes.add(new SimpleChunkMesh(chunk));
- }
- }
-
- }
- long t0 = System.nanoTime();
- if(!rough) {
- ChunkMesh.saveChunks(chunkCoords);
-
- meshes.addAll(ChunkMesh.loadAll());
- }
- System.out.println("loaded " + meshes.size() + " cchunks in " + ((System.nanoTime() - t0) / 1000000000f) + "s");
- //meshes = meshes.subList(2, 3);
- int bufferSize = 0;
- int quadCount = 0;
- Mesh firstMesh = meshes.get(0);
- int stride = -1;
- for(Mesh mesh : meshes) {
- bufferSize += mesh.buffer.limit();
- quadCount += mesh.quadCount;
- }
-
- if(Runtime.getRuntime().freeMemory() < BUFFER_SIZE) {
- System.out.println("not enough memory");
- // TODO optimize memory usage
- return false;
- }
- ByteBuffer buffer = BufferUtils.createByteBuffer(BUFFER_SIZE);
-
- for(Mesh mesh : meshes) {
- int verticesSoFar = buffer.position() / firstMesh.getStride();
- buffer.put(mesh.buffer);
- }
- buffer.flip();*/
glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, GL_STATIC_DRAW);
@@ -395,52 +273,24 @@ public class MyRenderer {
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
- //renderQuads = quadCount;
-
- int nextTri = 0;
piFirst = BufferUtils.createIntBuffer(MAX_MESHES);
piFirst.flip();
piCount = BufferUtils.createIntBuffer(MAX_MESHES);
piCount.flip();
- /*for(int i = 0; i < meshes.size(); i++) {
- Mesh mesh = meshes.get(i);
-
- piFirst.put(nextTri);
- piCount.put(mesh.quadCount * 6);
- nextTri += mesh.quadCount * 6;
- }*/
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
- //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return true;
}
- public static boolean doRender = true;
- private static boolean hasInited2 = false;
-
- private static int BUFFER_SIZE = 1024 * 1024 * 1024;
- private static int MAX_MESHES = 100000;
-
- public static void beforeRenderTerrain() {
- init2();
-
- if(doRender) {
- mainLoop();
- if(hasInited && renderLOD) {
- render();
- }
- }
- }
-
- public static void onWorldRendererPost(WorldRenderer wr) {
+ public void onWorldRendererPost(WorldRenderer wr) {
LODChunk lodChunk = getLODChunk(Math.floorDiv(wr.posX, 16), Math.floorDiv(wr.posZ, 16));
lodChunk.putChunkMeshes(Math.floorDiv(wr.posY, 16), ((IWorldRenderer)wr).getChunkMeshes());
setVisible(lodChunk, false);
}
- public static void onDontDraw(WorldRenderer wr) {
+ public void onDontDraw(WorldRenderer wr) {
int chunkX = Math.floorDiv(wr.posX, 16);
int chunkY = Math.floorDiv(wr.posY, 16);
int chunkZ = Math.floorDiv(wr.posZ, 16);
@@ -454,89 +304,29 @@ public class MyRenderer {
setVisible(lodChunk, true);
}
- private static void init2() {
- if(!hasInited2) {
- hasInited = init();
- hasInited2 = true;
- } else {
- while(!farChunks.isEmpty()) {
- LODChunk lodChunk = receiveFarChunk(farChunks.remove());
- sendChunkToGPU(lodChunk);
- }
-
- List<Object> players = Minecraft.getMinecraft().getIntegratedServer().getConfigurationManager().playerEntityList;
- if(!players.isEmpty()) {
- Entity player = (Entity)players.get(0);
-
- List<ChunkCoordIntPair> newServerChunkLoadQueue = new ArrayList<>();
-
- if(Double.isNaN(lastSortX) || getLastSortDistanceSq(player) > 16 * 16) {
- int centerX = (int)Math.floor(player.posX / 16.0);
- int centerZ = (int)Math.floor(player.posZ / 16.0);
-
- int range = 64;
- for(int x = -range; x <= range; x++) {
- for(int z = -range; z <= range; z++) {
- int chunkX = centerX + x;
- int chunkZ = centerZ + z;
-
- if(getLODChunk(chunkX, chunkZ).chunk == null) {
- newServerChunkLoadQueue.add(new ChunkCoordIntPair(chunkX, chunkZ));
- }
- }
- }
- Collections.sort(newServerChunkLoadQueue, new ChunkCoordDistanceComparator(player));
- setServerChunkLoadQueue(newServerChunkLoadQueue);
- hasInited2 = true;
-
- lastSortX = player.posX;
- lastSortY = player.posY;
- lastSortZ = player.posZ;
-
- loadedRegionsMap.forEach((k, v) -> v.tick(player));
- }
- }
- }
- }
-
- private static double getLastSortDistanceSq(Entity player) {
+ private double getLastSortDistanceSq(Entity player) {
return Math.pow(lastSortX - player.posX, 2) + Math.pow(lastSortZ - player.posZ, 2);
}
- private static synchronized void setServerChunkLoadQueue(List<ChunkCoordIntPair> coords) {
+ private synchronized void setServerChunkLoadQueue(List<ChunkCoordIntPair> coords) {
serverChunkLoadQueue = coords;
}
- private static LODChunk receiveFarChunk(Chunk chunk) {
+ private LODChunk receiveFarChunk(Chunk chunk) {
LODRegion region = getRegionContaining(chunk.xPosition, chunk.zPosition);
myChunks.add(chunk);
return region.putChunk(chunk);
}
- private static LODChunk getLODChunk(int chunkX, int chunkZ) {
+ private LODChunk getLODChunk(int chunkX, int chunkZ) {
return getRegionContaining(chunkX, chunkZ).getChunkAbsolute(chunkX, chunkZ);
}
- static List<Chunk> myChunks = new ArrayList<Chunk>();
- static List<LODChunk> pendingLODChunks = new ArrayList<>();
-
- private static boolean hasServerInited = false;
- private static HashMap<ChunkCoordIntPair, LODRegion> loadedRegionsMap = new HashMap<>();
-
- // TODO make these packets to make this work on dedicated servers
- static Queue<Chunk> farChunks = new ConcurrentLinkedQueue<>();
-
- static List<ChunkCoordIntPair> serverChunkLoadQueue = new ArrayList<>();
-
- private static double lastSortX = Double.NaN;
- private static double lastSortY = Double.NaN;
- private static double lastSortZ = Double.NaN;
-
- public static void onStopServer() {
+ public void onStopServer() {
}
- public static synchronized void serverTick() {
+ public synchronized void serverTick() {
int chunkLoadsRemaining = 64;
while(!serverChunkLoadQueue.isEmpty() && chunkLoadsRemaining-- > 0) {
ChunkCoordIntPair coords = serverChunkLoadQueue.remove(0);
@@ -546,7 +336,7 @@ public class MyRenderer {
}
}
- private static LODRegion getRegionContaining(int chunkX, int chunkZ) {
+ private LODRegion getRegionContaining(int chunkX, int chunkZ) {
ChunkCoordIntPair key = new ChunkCoordIntPair(Math.floorDiv(chunkX , 32), Math.floorDiv(chunkZ, 32));
LODRegion region = loadedRegionsMap.get(key);
if(region == null) {
@@ -556,7 +346,7 @@ public class MyRenderer {
return region;
}
- private static void loadChunk(int chunkX, int chunkZ) {
+ private void loadChunk(int chunkX, int chunkZ) {
LODRegion region = getRegionContaining(chunkX, chunkZ);
LODChunk lodChunk = region.getChunkAbsolute(chunkX, chunkZ);
if(lodChunk == null) {
@@ -579,7 +369,7 @@ public class MyRenderer {
sendChunkToGPU(lodChunk);
}
- private static void sendChunkToGPU(LODChunk lodChunk) {
+ private void sendChunkToGPU(LODChunk lodChunk) {
lodChunk.simpleMesh = new SimpleChunkMesh(lodChunk.chunk);
/*for(int cy = 0; cy < 16; cy++) {
lodChunk.chunkMeshes[cy] = ChunkMesh.getChunkMesh(lodChunk.x, cy, lodChunk.z);
@@ -594,21 +384,21 @@ public class MyRenderer {
setVisible(lodChunk, true);
}
- public static void setLOD(LODChunk lodChunk, int lod) {
+ public void setLOD(LODChunk lodChunk, int lod) {
if(lod == lodChunk.lod) return;
lodChunk.lod = lod;
lodChunkChanged(lodChunk);
}
- public static void setVisible(LODChunk lodChunk, boolean visible) {
+ public void setVisible(LODChunk lodChunk, boolean visible) {
if(visible == lodChunk.visible) return;
lodChunk.visible = visible;
lodChunkChanged(lodChunk);
}
- public static void lodChunkChanged(LODChunk lodChunk) {
+ public void lodChunkChanged(LODChunk lodChunk) {
int newLOD = (!lodChunk.hasChunkMeshes() && lodChunk.lod == 2) ? 1 : lodChunk.lod;
if(lodChunk.simpleMesh != null) {
if(lodChunk.visible && newLOD == 1) {
@@ -636,11 +426,11 @@ public class MyRenderer {
}
}
- private static int nextTri;
- private static int nextMeshOffset;
- private static int nextMesh;
+ private int nextTri;
+ private int nextMeshOffset;
+ private int nextMesh;
- protected static void sendMeshToGPU(Mesh mesh) {
+ protected void sendMeshToGPU(Mesh mesh) {
if(mesh == null) {
return;
}
@@ -658,7 +448,7 @@ public class MyRenderer {
glBindVertexArray(0);
}
- protected static void setMeshVisible(Mesh mesh, boolean visible) {
+ protected void setMeshVisible(Mesh mesh, boolean visible) {
if(mesh == null) return;
if(mesh.visible != visible) {
@@ -693,7 +483,7 @@ public class MyRenderer {
}
}
- public static Chunk getChunkFromChunkCoords(int x, int z) {
+ public Chunk getChunkFromChunkCoords(int x, int z) {
for(Chunk chunk : myChunks) {
if(chunk.xPosition == x && chunk.zPosition == z) {
return chunk;
diff --git a/src/main/java/makamys/lodmod/util/SpriteUtil.java b/src/main/java/makamys/lodmod/util/SpriteUtil.java
new file mode 100644
index 0000000..34bc544
--- /dev/null
+++ b/src/main/java/makamys/lodmod/util/SpriteUtil.java
@@ -0,0 +1,55 @@
+package makamys.lodmod.util;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.renderer.texture.TextureMap;
+import net.minecraft.world.ChunkCoordIntPair;
+
+public class SpriteUtil {
+
+ private static int[] spriteIndexMap;
+ public static List<TextureAtlasSprite> sprites;
+
+ private static Map<Long, Integer> uv2spriteIndex = new HashMap<>();
+
+ private static int findSpriteIndexForUV(float u, float v) {
+ Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
+
+ int spriteIndex = 0;
+ for(TextureAtlasSprite tas : uploadedSprites.values()) {
+ if(tas.getMinU() <= u && u <= tas.getMaxU() && tas.getMinV() <= v && v <= tas.getMaxV()) {
+ break;
+ }
+ spriteIndex++;
+ }
+ return spriteIndex;
+ }
+
+ public static int getSpriteIndexForUV(float u, float v){
+ long key = ChunkCoordIntPair.chunkXZ2Int((int)(u * Integer.MAX_VALUE), (int)(v * Integer.MAX_VALUE));
+ int index = uv2spriteIndex.getOrDefault(key, -1);
+ if(index == -1) {
+ index = findSpriteIndexForUV(u, v);
+ uv2spriteIndex.put(key, index);
+ }
+ return index;
+ }
+
+ public static TextureAtlasSprite getSprite(int i){
+ if(i >= 0 && i < sprites.size()) {
+ return sprites.get(i);
+ } else {
+ return null;
+ }
+ }
+
+ public static void init() {
+ Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites;
+ sprites = uploadedSprites.values().stream().collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/makamys/lodmod/util/Util.java b/src/main/java/makamys/lodmod/util/Util.java
index 92cc5cd..6964e9e 100644
--- a/src/main/java/makamys/lodmod/util/Util.java
+++ b/src/main/java/makamys/lodmod/util/Util.java
@@ -4,7 +4,10 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
import java.nio.file.FileSystems;
+import java.nio.file.Files;
import java.nio.file.Path;
public class Util {
@@ -27,4 +30,27 @@ public class Util {
return null;
}
}
+
+ public static String readFile(String path){
+ try {
+ return new String(Files.readAllBytes(Util.getResourcePath(path)));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public static byte[] byteBufferToArray(ByteBuffer buffer) {
+ byte[] dst = new byte[buffer.remaining()];
+ buffer.get(dst);
+ buffer.flip();
+ return dst;
+ }
+
+ public static int[] intBufferToArray(IntBuffer buffer) {
+ int[] dst = new int[buffer.remaining()];
+ buffer.get(dst);
+ buffer.flip();
+ return dst;
+ }
}
diff --git a/src/main/resources/lodmod.mixin.json b/src/main/resources/lodmod.mixin.json
index d8bfed1..65e6dd4 100644
--- a/src/main/resources/lodmod.mixin.json
+++ b/src/main/resources/lodmod.mixin.json
@@ -7,7 +7,6 @@
"mixins": [
"MixinChunkCache",
"MixinEntityRenderer",
- "MixinMinecraftServer",
"MixinRenderGlobal",
"MixinSoundManager",
"MixinSoundManager",