Compare commits
22 Commits
2.4.4b
...
dynamicFade
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a3c24f39e | |||
| 7b6fd03d78 | |||
| 1a540cf2bc | |||
| 20fc2efb46 | |||
| d8beba2498 | |||
| 9f0cb5a394 | |||
| df63401d11 | |||
| db95951ade | |||
| 1e020f93a6 | |||
| 7aee6dfb44 | |||
| 546a51a295 | |||
| ec7e791e9f | |||
| d60dec3d82 | |||
| 89a80103f0 | |||
| 8e14a7223c | |||
| 7cf1e901f5 | |||
| ba923fa829 | |||
| 505dbe2f62 | |||
| 48c5828e8f | |||
| eb2317934f | |||
| 60537cda1b | |||
| 508ff2b776 |
@@ -38,7 +38,7 @@ public final class ModInfo
|
|||||||
public static final String NAME = "DistantHorizons";
|
public static final String NAME = "DistantHorizons";
|
||||||
/** Human-readable version of NAME */
|
/** Human-readable version of NAME */
|
||||||
public static final String READABLE_NAME = "Distant Horizons";
|
public static final String READABLE_NAME = "Distant Horizons";
|
||||||
public static final String VERSION = "2.4.4-b";
|
public static final String VERSION = "2.4.6-b-dev";
|
||||||
/** Returns true if the current build is an unstable developer build, false otherwise. */
|
/** Returns true if the current build is an unstable developer build, false otherwise. */
|
||||||
public static final boolean IS_DEV_BUILD = VERSION.toLowerCase().contains("dev");
|
public static final boolean IS_DEV_BUILD = VERSION.toLowerCase().contains("dev");
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import com.seibel.distanthorizons.api.DhApi;
|
|||||||
import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||||
|
import com.seibel.distanthorizons.api.objects.DhApiResult;
|
||||||
import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState;
|
import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
||||||
@@ -31,14 +33,15 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.*;
|
import com.seibel.distanthorizons.core.render.renderer.*;
|
||||||
import com.seibel.distanthorizons.core.util.TimerUtil;
|
import com.seibel.distanthorizons.core.util.TimerUtil;
|
||||||
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import com.seibel.distanthorizons.core.util.objects.Pair;
|
import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||||
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
import com.seibel.distanthorizons.core.network.session.NetworkSession;
|
import com.seibel.distanthorizons.core.network.session.NetworkSession;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiDebugRendering;
|
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode;
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||||
@@ -52,11 +55,23 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapp
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This holds the methods that should be called
|
* This holds the methods that should be called
|
||||||
@@ -152,10 +167,10 @@ public class ClientApi
|
|||||||
|
|
||||||
if (Config.Common.Logging.Warning.showReplayWarningOnStartup.get())
|
if (Config.Common.Logging.Warning.showReplayWarningOnStartup.get())
|
||||||
{
|
{
|
||||||
MC_CLIENT.sendChatMessage("\u00A76" + "Distant Horizons: Replay detected." + "\u00A7r"); // gold color
|
MC_CLIENT.sendChatMessage(MinecraftTextFormat.ORANGE + "Distant Horizons: Replay detected." + MinecraftTextFormat.CLEAR_FORMATTING);
|
||||||
MC_CLIENT.sendChatMessage("DH may behave strangely or have missing functionality.");
|
MC_CLIENT.sendChatMessage("DH may behave strangely or have missing functionality.");
|
||||||
MC_CLIENT.sendChatMessage("In order to use pre-generated LODs, put your DH database(s) in:");
|
MC_CLIENT.sendChatMessage("In order to use pre-generated LODs, put your DH database(s) in:");
|
||||||
MC_CLIENT.sendChatMessage("\u00A77"+".Minecraft" + File.separator + ClientOnlySaveStructure.SERVER_DATA_FOLDER_NAME + File.separator + ClientOnlySaveStructure.REPLAY_SERVER_FOLDER_NAME + File.separator + "DIMENSION_NAME"+"\u00A7r"); // light gray color
|
MC_CLIENT.sendChatMessage(MinecraftTextFormat.GRAY +".Minecraft" + File.separator + ClientOnlySaveStructure.SERVER_DATA_FOLDER_NAME + File.separator + ClientOnlySaveStructure.REPLAY_SERVER_FOLDER_NAME + File.separator + "DIMENSION_NAME"+ MinecraftTextFormat.CLEAR_FORMATTING);
|
||||||
MC_CLIENT.sendChatMessage("This can be disabled in DH's config under Advanced -> Logging.");
|
MC_CLIENT.sendChatMessage("This can be disabled in DH's config under Advanced -> Logging.");
|
||||||
MC_CLIENT.sendChatMessage("");
|
MC_CLIENT.sendChatMessage("");
|
||||||
}
|
}
|
||||||
@@ -328,10 +343,27 @@ public class ClientApi
|
|||||||
*/
|
*/
|
||||||
public void pluginMessageReceived(@NotNull AbstractNetworkMessage message)
|
public void pluginMessageReceived(@NotNull AbstractNetworkMessage message)
|
||||||
{
|
{
|
||||||
NetworkSession networkSession = this.pluginChannelApi.networkSession;
|
@Nullable ThreadPoolExecutor executor = ThreadPoolUtil.networkClientHandlerExecutor();
|
||||||
if (networkSession != null)
|
if (executor == null)
|
||||||
{
|
{
|
||||||
networkSession.tryHandleMessage(message);
|
LOGGER.warn("warn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
executor.execute(() ->
|
||||||
|
{
|
||||||
|
NetworkSession networkSession = this.pluginChannelApi.networkSession;
|
||||||
|
if (networkSession != null)
|
||||||
|
{
|
||||||
|
networkSession.tryHandleMessage(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (RejectedExecutionException e)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Plugin message executor rejected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,10 +539,10 @@ public class ClientApi
|
|||||||
this.rendererDisabledBecauseOfExceptions = true;
|
this.rendererDisabledBecauseOfExceptions = true;
|
||||||
LOGGER.error("Unexpected Renderer error in render pass [" + renderPass + "]. Error: " + e.getMessage(), e);
|
LOGGER.error("Unexpected Renderer error in render pass [" + renderPass + "]. Error: " + e.getMessage(), e);
|
||||||
|
|
||||||
MC_CLIENT.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons renderer has encountered an exception!");
|
MC_CLIENT.sendChatMessage(MinecraftTextFormat.DARK_RED + "" + MinecraftTextFormat.BOLD + "ERROR: Distant Horizons renderer has encountered an exception!" + MinecraftTextFormat.CLEAR_FORMATTING);
|
||||||
MC_CLIENT.sendChatMessage("\u00A74Renderer disabled to try preventing GL state corruption.");
|
MC_CLIENT.sendChatMessage(MinecraftTextFormat.DARK_RED + "Renderer disabled to try preventing GL state corruption." + MinecraftTextFormat.CLEAR_FORMATTING);
|
||||||
MC_CLIENT.sendChatMessage("\u00A74Toggle DH rendering via the config UI to re-activate DH rendering.");
|
MC_CLIENT.sendChatMessage(MinecraftTextFormat.DARK_RED + "Toggle DH rendering via the config UI to re-activate DH rendering." + MinecraftTextFormat.CLEAR_FORMATTING);
|
||||||
MC_CLIENT.sendChatMessage("\u00A74Error: " + e);
|
MC_CLIENT.sendChatMessage(MinecraftTextFormat.DARK_RED + "Error: " + MinecraftTextFormat.CLEAR_FORMATTING + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -529,8 +561,11 @@ public class ClientApi
|
|||||||
* The first fade pass.
|
* The first fade pass.
|
||||||
* Called after MC finishes rendering the opaque passes.
|
* Called after MC finishes rendering the opaque passes.
|
||||||
*/
|
*/
|
||||||
public void renderFadeOpaque()
|
public void renderFadeOpaque() // TODO this is actually the transparent pass
|
||||||
{
|
{
|
||||||
|
DepthCalculator.INSTANCE.getMcTransparentDepthTexture();
|
||||||
|
DepthCalculator.INSTANCE.tryCalculateAsync();
|
||||||
|
|
||||||
// only fade when DH is rendering
|
// only fade when DH is rendering
|
||||||
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT
|
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT
|
||||||
&&
|
&&
|
||||||
@@ -551,8 +586,10 @@ public class ClientApi
|
|||||||
* Called after MC finishes rendering both opaque
|
* Called after MC finishes rendering both opaque
|
||||||
* and transparent passes.
|
* and transparent passes.
|
||||||
*/
|
*/
|
||||||
public void renderFadeTransparent()
|
public void renderFadeTransparent() // TODO this is actually the opaque pass
|
||||||
{
|
{
|
||||||
|
DepthCalculator.INSTANCE.getMcOpaqueDepthTexture();
|
||||||
|
|
||||||
// only fade when DH is rendering
|
// only fade when DH is rendering
|
||||||
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT)
|
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT)
|
||||||
{
|
{
|
||||||
@@ -581,27 +618,30 @@ public class ClientApi
|
|||||||
/** Trigger once on key press, with CLIENT PLAYER. */
|
/** Trigger once on key press, with CLIENT PLAYER. */
|
||||||
public void keyPressedEvent(int glfwKey)
|
public void keyPressedEvent(int glfwKey)
|
||||||
{
|
{
|
||||||
if (!Config.Client.Advanced.Debugging.enableDebugKeybindings.get())
|
//if (!Config.Client.Advanced.Debugging.enableDebugKeybindings.get())
|
||||||
{
|
//{
|
||||||
// keybindings are disabled
|
// // keybindings are disabled
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
if (glfwKey == GLFW.GLFW_KEY_F8)
|
if (glfwKey == GLFW.GLFW_KEY_F8)
|
||||||
{
|
{
|
||||||
Config.Client.Advanced.Debugging.debugRendering.set(EDhApiDebugRendering.next(Config.Client.Advanced.Debugging.debugRendering.get()));
|
DepthCalculator.INSTANCE.pause = true;
|
||||||
MC_CLIENT.sendChatMessage("F8: Set debug mode to " + Config.Client.Advanced.Debugging.debugRendering.get());
|
//Config.Client.Advanced.Debugging.debugRendering.set(EDhApiDebugRendering.next(Config.Client.Advanced.Debugging.debugRendering.get()));
|
||||||
|
//MC_CLIENT.sendChatMessage("F8: Set debug mode to " + Config.Client.Advanced.Debugging.debugRendering.get());
|
||||||
}
|
}
|
||||||
else if (glfwKey == GLFW.GLFW_KEY_F6)
|
else if (glfwKey == GLFW.GLFW_KEY_F6)
|
||||||
{
|
{
|
||||||
Config.Client.Advanced.Debugging.rendererMode.set(EDhApiRendererMode.next(Config.Client.Advanced.Debugging.rendererMode.get()));
|
DepthCalculator.INSTANCE.pause = true;
|
||||||
MC_CLIENT.sendChatMessage("F6: Set rendering to " + Config.Client.Advanced.Debugging.rendererMode.get());
|
//Config.Client.Advanced.Debugging.rendererMode.set(EDhApiRendererMode.next(Config.Client.Advanced.Debugging.rendererMode.get()));
|
||||||
|
//MC_CLIENT.sendChatMessage("F6: Set rendering to " + Config.Client.Advanced.Debugging.rendererMode.get());
|
||||||
}
|
}
|
||||||
else if (glfwKey == GLFW.GLFW_KEY_P)
|
else if (glfwKey == GLFW.GLFW_KEY_P)
|
||||||
{
|
{
|
||||||
prefLoggerEnabled = !prefLoggerEnabled;
|
DepthCalculator.INSTANCE.pause = true;
|
||||||
MC_CLIENT.sendChatMessage("P: Debug Pref Logger is " + (prefLoggerEnabled ? "enabled" : "disabled"));
|
//prefLoggerEnabled = !prefLoggerEnabled;
|
||||||
|
//MC_CLIENT.sendChatMessage("P: Debug Pref Logger is " + (prefLoggerEnabled ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,8 +695,7 @@ public class ClientApi
|
|||||||
|
|
||||||
// remind the user that this is a development build
|
// remind the user that this is a development build
|
||||||
String message =
|
String message =
|
||||||
// green text
|
MinecraftTextFormat.DARK_GREEN + "Distant Horizons: nightly/unstable build, version: [" + ModInfo.VERSION+"]." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"\u00A72" + "Distant Horizons: nightly/unstable build, version: [" + ModInfo.VERSION+"]." + "\u00A7r\n" +
|
|
||||||
"Issues may occur with this version.\n" +
|
"Issues may occur with this version.\n" +
|
||||||
"Here be dragons!\n";
|
"Here be dragons!\n";
|
||||||
MC_CLIENT.sendChatMessage(message);
|
MC_CLIENT.sendChatMessage(message);
|
||||||
@@ -680,7 +719,7 @@ public class ClientApi
|
|||||||
{
|
{
|
||||||
String message =
|
String message =
|
||||||
// orange text
|
// orange text
|
||||||
"\u00A76" + "Distant Horizons: Low memory detected." + "\u00A7r \n" +
|
MinecraftTextFormat.ORANGE + "Distant Horizons: Low memory detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"Stuttering or low FPS may occur. \n" +
|
"Stuttering or low FPS may occur. \n" +
|
||||||
"Please increase Minecraft's available memory to 4 GB or more. \n" +
|
"Please increase Minecraft's available memory to 4 GB or more. \n" +
|
||||||
"This warning can be disabled in DH's config under Advanced -> Logging. \n";
|
"This warning can be disabled in DH's config under Advanced -> Logging. \n";
|
||||||
@@ -702,15 +741,13 @@ public class ClientApi
|
|||||||
this.lastStaticWarningMessageSentMsTime = System.currentTimeMillis();
|
this.lastStaticWarningMessageSentMsTime = System.currentTimeMillis();
|
||||||
|
|
||||||
String message =
|
String message =
|
||||||
// yellow text
|
MinecraftTextFormat.YELLOW + "Distant Horizons: High vanilla render distance detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"\u00A7e" + "Distant Horizons: High vanilla render distance detected." + "\u00A7r \n" +
|
"Using a high vanilla render distance uses a lot of CPU power \n" +
|
||||||
"Using a high vanilla render distance uses a lot of CPU power \n" +
|
"and doesn't improve graphics much after about 12.\n" +
|
||||||
"and doesn't improve graphics much after about 12.\n" +
|
"Lowering your vanilla render distance will give you better FPS\n" +
|
||||||
"Lowing your vanilla render distance will give you better FPS\n" +
|
"and reduce stuttering at a similar visual quality.\n" +
|
||||||
"and reduce stuttering at a similar visual quality.\n" +
|
MinecraftTextFormat.GRAY + "A vanilla render distance of 8 is recommended." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
// gray text
|
"This message can be disabled in DH's config under Advanced -> Logging.\n";
|
||||||
"\u00A77" + "A vanilla render distance of 8 is recommended." + "\u00A7r \n" +
|
|
||||||
"This message can be disabled in DH's config under Advanced -> Logging.\n";
|
|
||||||
MC_CLIENT.sendChatMessage(message);
|
MC_CLIENT.sendChatMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.api.internal.chunkUpdating;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -105,6 +106,7 @@ public class ChunkPosQueue
|
|||||||
this.furthestQueue.remove(closest);
|
this.furthestQueue.remove(closest);
|
||||||
return this.updateDataByChunkPos.remove(closest);
|
return this.updateDataByChunkPos.remove(closest);
|
||||||
}
|
}
|
||||||
|
@Nullable
|
||||||
public ChunkUpdateData popFurthest()
|
public ChunkUpdateData popFurthest()
|
||||||
{
|
{
|
||||||
if (this.furthestQueue.isEmpty())
|
if (this.furthestQueue.isEmpty())
|
||||||
|
|||||||
+6
-4
@@ -1,12 +1,11 @@
|
|||||||
package com.seibel.distanthorizons.core.api.internal.chunkUpdating;
|
package com.seibel.distanthorizons.core.api.internal.chunkUpdating;
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.multiplayer.client.SyncOnLoadRequestQueue;
|
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.world.EWorldEnvironment;
|
import com.seibel.distanthorizons.core.world.EWorldEnvironment;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
@@ -94,7 +93,10 @@ public class ChunkUpdateQueueManager
|
|||||||
if (remainingSlots <= 0)
|
if (remainingSlots <= 0)
|
||||||
{
|
{
|
||||||
ChunkUpdateData removedData = queue.popFurthest();
|
ChunkUpdateData removedData = queue.popFurthest();
|
||||||
this.queuedChunkWrapperByChunkPos.remove(removedData.chunkWrapper.getChunkPos());
|
if (removedData != null)
|
||||||
|
{
|
||||||
|
this.queuedChunkWrapperByChunkPos.remove(removedData.chunkWrapper.getChunkPos());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.addItem(pos,updateData);
|
queue.addItem(pos,updateData);
|
||||||
@@ -116,7 +118,7 @@ public class ChunkUpdateQueueManager
|
|||||||
{
|
{
|
||||||
lastOverloadedLogMessageMsTime = System.currentTimeMillis();
|
lastOverloadedLogMessageMsTime = System.currentTimeMillis();
|
||||||
|
|
||||||
String message = "\u00A76" + "Distant Horizons overloaded, too many chunks queued for LOD processing. " + "\u00A7r" +
|
String message = MinecraftTextFormat.ORANGE + "Distant Horizons overloaded, too many chunks queued for LOD processing. " + MinecraftTextFormat.CLEAR_FORMATTING +
|
||||||
"\nThis may result in holes in your LODs. " +
|
"\nThis may result in holes in your LODs. " +
|
||||||
"\nFix: move through the world slower, decrease your vanilla render distance, slow down your world pre-generator (IE Chunky), or increase the Distant Horizons' CPU thread counts. " +
|
"\nFix: move through the world slower, decrease your vanilla render distance, slow down your world pre-generator (IE Chunky), or increase the Distant Horizons' CPU thread counts. " +
|
||||||
"\nMax queue count [" + SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.maxSize + "] ([" + SharedApi.MAX_UPDATING_CHUNK_COUNT_PER_THREAD_AND_PLAYER + "] per thread+players).";
|
"\nMax queue count [" + SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.maxSize + "] ([" + SharedApi.MAX_UPDATING_CHUNK_COUNT_PER_THREAD_AND_PLAYER + "] per thread+players).";
|
||||||
|
|||||||
@@ -118,6 +118,20 @@ public class Config
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static ConfigEntry<Boolean> dynamicFadeUseOpaqueMcDepth = new ConfigEntry.Builder<Boolean>()
|
||||||
|
.set(true)
|
||||||
|
.comment(""
|
||||||
|
+ "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public static ConfigEntry<String> dynamicFadeExportPath = new ConfigEntry.Builder<String>()
|
||||||
|
.set("C:/Users/James_Seibel/Desktop/")
|
||||||
|
.comment(""
|
||||||
|
+ "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class Advanced
|
public static class Advanced
|
||||||
{
|
{
|
||||||
// common config links need to have their destination
|
// common config links need to have their destination
|
||||||
@@ -457,6 +471,15 @@ public class Config
|
|||||||
+ "")
|
+ "")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
public static ConfigEntry<Boolean> expandDistantBeacons = new ConfigEntry.Builder<Boolean>()
|
||||||
|
.set(true)
|
||||||
|
.comment(""
|
||||||
|
+ "If true LOD beacon beams will be rendered wider at extreme distances, \n"
|
||||||
|
+ "making them easier to see. \n"
|
||||||
|
+ "If false all LOD beacon beams will only ever be 1 block wide. \n"
|
||||||
|
+ "")
|
||||||
|
.build();
|
||||||
|
|
||||||
public static ConfigEntry<Boolean> enableCloudRendering = new ConfigEntry.Builder<Boolean>()
|
public static ConfigEntry<Boolean> enableCloudRendering = new ConfigEntry.Builder<Boolean>()
|
||||||
.set(true)
|
.set(true)
|
||||||
.comment(""
|
.comment(""
|
||||||
|
|||||||
+10
-13
@@ -295,24 +295,21 @@ public class LodBufferContainer implements AutoCloseable
|
|||||||
{
|
{
|
||||||
this.buffersUploaded = false;
|
this.buffersUploaded = false;
|
||||||
|
|
||||||
GLProxy.queueRunningOnRenderThread(() ->
|
for (GLVertexBuffer buffer : this.vbos)
|
||||||
{
|
{
|
||||||
for (GLVertexBuffer buffer : this.vbos)
|
if (buffer != null)
|
||||||
{
|
{
|
||||||
if (buffer != null)
|
buffer.destroyAsync();
|
||||||
{
|
|
||||||
buffer.destroyAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (GLVertexBuffer buffer : this.vbosTransparent)
|
|
||||||
|
for (GLVertexBuffer buffer : this.vbosTransparent)
|
||||||
|
{
|
||||||
|
if (buffer != null)
|
||||||
{
|
{
|
||||||
if (buffer != null)
|
buffer.destroyAsync();
|
||||||
{
|
|
||||||
buffer.destroyAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.seibel.distanthorizons.core.enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
* might be deprecated in the future? in that case we'll probably want a wrapper
|
|
||||||
* function to handle colors for new MC versions
|
|
||||||
*
|
|
||||||
* source: https://minecraft.wiki/w/Formatting_codes
|
|
||||||
*/
|
|
||||||
public class EMinecraftColor
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.seibel.distanthorizons.core.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* might be deprecated in the future? in that case we'll probably want a wrapper
|
||||||
|
* function to handle colors for new MC versions
|
||||||
|
* <br><br>
|
||||||
|
* source: https://minecraft.wiki/w/Formatting_codes
|
||||||
|
*/
|
||||||
|
public class MinecraftTextFormat
|
||||||
|
{
|
||||||
|
public static final String BLACK = "\u00A70";
|
||||||
|
public static final String DARK_BLUE = "\u00A71";
|
||||||
|
public static final String DARK_GREEN = "\u00A72";
|
||||||
|
public static final String DARK_AQUA = "\u00A73";
|
||||||
|
public static final String DARK_RED = "\u00A74";
|
||||||
|
public static final String DARK_PURPLE = "\u00A75";
|
||||||
|
public static final String ORANGE = "\u00A76";
|
||||||
|
public static final String GRAY = "\u00A77";
|
||||||
|
public static final String DARK_GRAY = "\u00A78";
|
||||||
|
public static final String BLUE = "\u00A79";
|
||||||
|
public static final String GREEN = "\u00A7a";
|
||||||
|
public static final String AQUA = "\u00A7b";
|
||||||
|
public static final String RED = "\u00A7c";
|
||||||
|
public static final String LIGHT_PURPLE = "\u00A7d";
|
||||||
|
public static final String YELLOW = "\u00A7e";
|
||||||
|
public static final String WHITE = "\u00A7f";
|
||||||
|
|
||||||
|
public static final String OBFUSCATED = "\u00A7k";
|
||||||
|
public static final String BOLD = "\u00A7l";
|
||||||
|
public static final String STRIKETHROUGH = "\u00A7m";
|
||||||
|
public static final String UNDERLINE = "\u00A7n";
|
||||||
|
public static final String ITALIC = "\u00A7o";
|
||||||
|
public static final String CLEAR_FORMATTING = "\u00A7r";
|
||||||
|
|
||||||
|
}
|
||||||
+8
-11
@@ -44,6 +44,7 @@ import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
|
|||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -116,26 +117,22 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
|||||||
// events //
|
// events //
|
||||||
//========//
|
//========//
|
||||||
|
|
||||||
private void onWorldGenTaskComplete(DataSourceRetrievalResult genTaskResult, Throwable exception)
|
private void onWorldGenTaskComplete(@NotNull Long genPos, @Nullable DataSourceRetrievalResult genTaskResult, @Nullable Throwable exception)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (genTaskResult.state == ERetrievalResultState.FAIL)
|
|
||||||
{
|
|
||||||
LodUtil.assertTrue(genTaskResult.dataSource == null, "Errored retrieval object should not have a datasource.");
|
|
||||||
|
|
||||||
// don't log shutdown exceptions
|
// don't log shutdown exceptions
|
||||||
if (!ExceptionUtil.isInterruptOrReject(exception))
|
if (!ExceptionUtil.isInterruptOrReject(exception))
|
||||||
{
|
{
|
||||||
LOGGER.error("Uncaught Gen Task Exception at [" + genTaskResult.pos + "], error: [" + exception.getMessage() + "].", exception);
|
LOGGER.error("Uncaught Gen Task Exception at [" + genPos + "], error: [" + exception.getMessage() + "].", exception);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (genTaskResult.state == ERetrievalResultState.SUCCESS)
|
|
||||||
|
Objects.requireNonNull(genTaskResult);
|
||||||
|
if (genTaskResult.state == ERetrievalResultState.SUCCESS)
|
||||||
{
|
{
|
||||||
LodUtil.assertTrue(genTaskResult.dataSource != null, "Successful retrieval object should have a datasource.");
|
LodUtil.assertTrue(genTaskResult.dataSource != null, "Successful retrieval object should have a datasource.");
|
||||||
|
|
||||||
@@ -310,7 +307,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
|||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture<DataSourceRetrievalResult> worldGenFuture = worldGenQueue.submitRetrievalTask(genPos, (byte) (DhSectionPos.getDetailLevel(genPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL));
|
CompletableFuture<DataSourceRetrievalResult> worldGenFuture = worldGenQueue.submitRetrievalTask(genPos, (byte) (DhSectionPos.getDetailLevel(genPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL));
|
||||||
worldGenFuture.whenComplete(this::onWorldGenTaskComplete);
|
worldGenFuture.whenComplete((r, e) -> this.onWorldGenTaskComplete(genPos, r, e));
|
||||||
|
|
||||||
return worldGenFuture;
|
return worldGenFuture;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,9 +157,9 @@ public class PregenManager
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.fullDataSourceProvider.queuePositionForRetrieval(fullDataSource.getPos())
|
this.fullDataSourceProvider.queuePositionForRetrieval(fullDataSource.getPos())
|
||||||
.thenAccept((DataSourceRetrievalResult result) ->
|
.whenComplete((DataSourceRetrievalResult result, Throwable throwable) ->
|
||||||
{
|
{
|
||||||
if (result.state == ERetrievalResultState.FAIL)
|
if (throwable != null)
|
||||||
{
|
{
|
||||||
LOGGER.warn("Failed to generate section " + DhSectionPos.toString(result.pos));
|
LOGGER.warn("Failed to generate section " + DhSectionPos.toString(result.pos));
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -92,7 +92,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
|||||||
private int estimatedRemainingChunkCount = 0;
|
private int estimatedRemainingChunkCount = 0;
|
||||||
|
|
||||||
private final RollingAverage rollingAverageChunkGenTimeInMs = new RollingAverage(Runtime.getRuntime().availableProcessors() * 500);
|
private final RollingAverage rollingAverageChunkGenTimeInMs = new RollingAverage(Runtime.getRuntime().availableProcessors() * 500);
|
||||||
public RollingAverage getRollingAverageChunkGenTimeInMs() { return this.rollingAverageChunkGenTimeInMs; }
|
@Override public RollingAverage getRollingAverageChunkGenTimeInMs() { return this.rollingAverageChunkGenTimeInMs; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -128,7 +128,9 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
|||||||
// the generator is shutting down, don't add new tasks
|
// the generator is shutting down, don't add new tasks
|
||||||
if (this.generatorClosingFuture != null)
|
if (this.generatorClosingFuture != null)
|
||||||
{
|
{
|
||||||
return CompletableFuture.completedFuture(DataSourceRetrievalResult.CreateFail());
|
CompletableFuture<DataSourceRetrievalResult> f = new CompletableFuture<>();
|
||||||
|
f.completeExceptionally(new CancellationException());
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the existing task if present
|
// use the existing task if present
|
||||||
@@ -362,7 +364,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
|||||||
}
|
}
|
||||||
|
|
||||||
LodUtil.assertTrue(fullDataSource == null);
|
LodUtil.assertTrue(fullDataSource == null);
|
||||||
worldGenTask.future.complete(DataSourceRetrievalResult.CreateFail());
|
worldGenTask.future.completeExceptionally(exception);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
-1
@@ -40,7 +40,6 @@ public class DataSourceRetrievalResult
|
|||||||
//==============//
|
//==============//
|
||||||
|
|
||||||
public static DataSourceRetrievalResult CreateSplit() { return new DataSourceRetrievalResult(ERetrievalResultState.REQUIRES_SPLITTING, 0, null); }
|
public static DataSourceRetrievalResult CreateSplit() { return new DataSourceRetrievalResult(ERetrievalResultState.REQUIRES_SPLITTING, 0, null); }
|
||||||
public static DataSourceRetrievalResult CreateFail() { return new DataSourceRetrievalResult(ERetrievalResultState.FAIL, 0, null); }
|
|
||||||
public static DataSourceRetrievalResult CreateSuccess(long pos, FullDataSourceV2 generatedDataSource) { return new DataSourceRetrievalResult(ERetrievalResultState.SUCCESS, pos, generatedDataSource); }
|
public static DataSourceRetrievalResult CreateSuccess(long pos, FullDataSourceV2 generatedDataSource) { return new DataSourceRetrievalResult(ERetrievalResultState.SUCCESS, pos, generatedDataSource); }
|
||||||
private DataSourceRetrievalResult(ERetrievalResultState state, long pos, @Nullable FullDataSourceV2 dataSource)
|
private DataSourceRetrievalResult(ERetrievalResultState state, long pos, @Nullable FullDataSourceV2 dataSource)
|
||||||
{
|
{
|
||||||
|
|||||||
-2
@@ -3,7 +3,6 @@ package com.seibel.distanthorizons.core.generation.tasks;
|
|||||||
/**
|
/**
|
||||||
* SUCCESS <br>
|
* SUCCESS <br>
|
||||||
* REQUIRES_SPLITTING <br>
|
* REQUIRES_SPLITTING <br>
|
||||||
* FAIL <br>
|
|
||||||
*
|
*
|
||||||
* @see DataSourceRetrievalResult
|
* @see DataSourceRetrievalResult
|
||||||
*/
|
*/
|
||||||
@@ -11,5 +10,4 @@ public enum ERetrievalResultState
|
|||||||
{
|
{
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
REQUIRES_SPLITTING,
|
REQUIRES_SPLITTING,
|
||||||
FAIL,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class JarUtils
|
|||||||
*/
|
*/
|
||||||
public static InputStream accessFile(String resource)
|
public static InputStream accessFile(String resource)
|
||||||
{
|
{
|
||||||
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
final ClassLoader loader = JarUtils.class.getClassLoader();
|
||||||
// this is the path within the jar file
|
// this is the path within the jar file
|
||||||
InputStream input = loader.getResourceAsStream(resource);
|
InputStream input = loader.getResourceAsStream(resource);
|
||||||
if (input == null)
|
if (input == null)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.config.Config;
|
|||||||
import com.seibel.distanthorizons.core.config.listeners.IConfigListener;
|
import com.seibel.distanthorizons.core.config.listeners.IConfigListener;
|
||||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
@@ -302,32 +303,32 @@ public class DhLogger implements IConfigListener
|
|||||||
String prefix = "[" + ModInfo.READABLE_NAME + "] ";
|
String prefix = "[" + ModInfo.READABLE_NAME + "] ";
|
||||||
if (logLevel == Level.ERROR)
|
if (logLevel == Level.ERROR)
|
||||||
{
|
{
|
||||||
prefix += "\u00A74";
|
prefix += MinecraftTextFormat.DARK_RED;
|
||||||
}
|
}
|
||||||
else if (logLevel == Level.WARN)
|
else if (logLevel == Level.WARN)
|
||||||
{
|
{
|
||||||
prefix += "\u00A76";
|
prefix += MinecraftTextFormat.ORANGE;
|
||||||
}
|
}
|
||||||
else if (logLevel == Level.INFO)
|
else if (logLevel == Level.INFO)
|
||||||
{
|
{
|
||||||
prefix += "\u00A7f";
|
prefix += MinecraftTextFormat.AQUA;
|
||||||
}
|
}
|
||||||
else if (logLevel == Level.DEBUG)
|
else if (logLevel == Level.DEBUG)
|
||||||
{
|
{
|
||||||
prefix += "\u00A77";
|
prefix += MinecraftTextFormat.GREEN;
|
||||||
}
|
}
|
||||||
else if (logLevel == Level.TRACE)
|
else if (logLevel == Level.TRACE)
|
||||||
{
|
{
|
||||||
prefix += "\u00A78";
|
prefix += MinecraftTextFormat.DARK_GRAY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prefix += "\u00A7f";
|
prefix += MinecraftTextFormat.WHITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix += "\u00A7l\u00A7u";
|
prefix += MinecraftTextFormat.BOLD + "" + MinecraftTextFormat.WHITE;
|
||||||
prefix += logLevel.name();
|
prefix += logLevel.name();
|
||||||
prefix += ":\u00A7r ";
|
prefix += MinecraftTextFormat.CLEAR_FORMATTING + " ";
|
||||||
|
|
||||||
mc_client.sendChatMessage(prefix + message);
|
mc_client.sendChatMessage(prefix + message);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-7
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
|
|||||||
import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO;
|
import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.util.ratelimiting.SupplierBasedRateLimiter;
|
import com.seibel.distanthorizons.core.util.ratelimiting.SupplierBasedRateLimiter;
|
||||||
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.world.DhApiWorldProxy;
|
import com.seibel.distanthorizons.core.world.DhApiWorldProxy;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
|
||||||
@@ -139,9 +140,6 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
|||||||
break;
|
break;
|
||||||
case REQUIRES_SPLITTING:
|
case REQUIRES_SPLITTING:
|
||||||
break;
|
break;
|
||||||
case FAIL:
|
|
||||||
this.failedRequests.incrementAndGet();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -220,11 +218,18 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
|||||||
FullDataSourceResponseMessage.class
|
FullDataSourceResponseMessage.class
|
||||||
);
|
);
|
||||||
requestTask.networkDataSourceFuture = dataSourceNetworkFuture;
|
requestTask.networkDataSourceFuture = dataSourceNetworkFuture;
|
||||||
dataSourceNetworkFuture.handle((FullDataSourceResponseMessage response, Throwable throwable) ->
|
|
||||||
|
Executor networkCompressionExecutor = ThreadPoolUtil.getNetworkCompressionExecutor();
|
||||||
|
if (networkCompressionExecutor == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSourceNetworkFuture.handleAsync((FullDataSourceResponseMessage response, Throwable throwable) ->
|
||||||
{
|
{
|
||||||
this.handleNetResponse(requestTask, response, throwable);
|
this.handleNetResponse(requestTask, response, throwable);
|
||||||
return null;
|
return null;
|
||||||
});
|
}, networkCompressionExecutor);
|
||||||
}
|
}
|
||||||
private void handleNetResponse(NetRequestTask requestTask, FullDataSourceResponseMessage response, Throwable throwable)
|
private void handleNetResponse(NetRequestTask requestTask, FullDataSourceResponseMessage response, Throwable throwable)
|
||||||
{
|
{
|
||||||
@@ -269,7 +274,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
|||||||
catch (RequestRejectedException e)
|
catch (RequestRejectedException e)
|
||||||
{
|
{
|
||||||
LOGGER.info("Request rejected by the server, message: [" + e.getMessage() + "].");
|
LOGGER.info("Request rejected by the server, message: [" + e.getMessage() + "].");
|
||||||
requestTask.future.complete(DataSourceRetrievalResult.CreateFail());
|
requestTask.future.completeExceptionally(e);
|
||||||
}
|
}
|
||||||
catch (RateLimitedException e)
|
catch (RateLimitedException e)
|
||||||
{
|
{
|
||||||
@@ -298,7 +303,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
requestTask.future.complete(DataSourceRetrievalResult.CreateFail());
|
requestTask.future.completeExceptionally(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -1,8 +1,10 @@
|
|||||||
package com.seibel.distanthorizons.core.multiplayer.client;
|
package com.seibel.distanthorizons.core.multiplayer.client;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
|
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.multiplayer.config.SessionConfig;
|
import com.seibel.distanthorizons.core.multiplayer.config.SessionConfig;
|
||||||
@@ -95,6 +97,15 @@ public class ClientNetworkState implements Closeable
|
|||||||
|| Math.abs(event.protocolVersion - ModInfo.PROTOCOL_VERSION) < this.closestProtocolVersion)
|
|| Math.abs(event.protocolVersion - ModInfo.PROTOCOL_VERSION) < this.closestProtocolVersion)
|
||||||
{
|
{
|
||||||
this.closestProtocolVersion = event.protocolVersion;
|
this.closestProtocolVersion = event.protocolVersion;
|
||||||
|
|
||||||
|
if (ModInfo.PROTOCOL_VERSION < event.protocolVersion)
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.showChatMessageNextFrame(MinecraftTextFormat.ORANGE + "Distant Horizons: Your mod is outdated. Update to receive LODs on this server.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.showChatMessageNextFrame(MinecraftTextFormat.ORANGE + "Distant Horizons: The server's mod is outdated. Ask the server's owner to update.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+1
@@ -45,6 +45,7 @@ public class FullDataPayloadReceiver implements AutoCloseable
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.buffer.readerIndex(0);
|
||||||
composite.addComponent(message.buffer);
|
composite.addComponent(message.buffer);
|
||||||
composite.writerIndex(composite.writerIndex() + message.buffer.writerIndex());
|
composite.writerIndex(composite.writerIndex() + message.buffer.writerIndex());
|
||||||
LOGGER.debug("Updated full data buffer [" + message.bufferId + "]: [" + composite + "].");
|
LOGGER.debug("Updated full data buffer [" + message.bufferId + "]: [" + composite + "].");
|
||||||
|
|||||||
+2
-3
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.pooling;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||||
@@ -12,7 +13,6 @@ import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
|||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
|
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -178,8 +178,7 @@ public class PhantomArrayListPool
|
|||||||
{
|
{
|
||||||
lowMemoryWarningLogged = true;
|
lowMemoryWarningLogged = true;
|
||||||
|
|
||||||
// orange text
|
String message = MinecraftTextFormat.ORANGE + "Distant Horizons: Insufficient memory detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
String message = "\u00A76" + "Distant Horizons: Insufficient memory detected." + "\u00A7r \n" +
|
|
||||||
"This may cause stuttering or crashing. \n" +
|
"This may cause stuttering or crashing. \n" +
|
||||||
"Potential causes: \n" +
|
"Potential causes: \n" +
|
||||||
"1. your allocated memory isn't high enough \n" +
|
"1. your allocated memory isn't high enough \n" +
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
|||||||
*/
|
*/
|
||||||
private final ConcurrentLinkedQueue<Long> sectionsToReload = new ConcurrentLinkedQueue<>();
|
private final ConcurrentLinkedQueue<Long> sectionsToReload = new ConcurrentLinkedQueue<>();
|
||||||
private final IDhClientLevel level;
|
private final IDhClientLevel level;
|
||||||
|
/**
|
||||||
|
* Note: this doesn't lock all operations as some other threads/operations
|
||||||
|
* that may traverse the tree while it's being modified.
|
||||||
|
* IE {@link RenderBufferHandler} will walk through the tree each frame.
|
||||||
|
*/
|
||||||
private final ReentrantLock treeLock = new ReentrantLock();
|
private final ReentrantLock treeLock = new ReentrantLock();
|
||||||
|
|
||||||
private ArrayList<LodRenderSection> debugRenderSections = new ArrayList<>();
|
private ArrayList<LodRenderSection> debugRenderSections = new ArrayList<>();
|
||||||
@@ -166,7 +171,8 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// don't traverse the tree if it is being modified
|
// don't tick the tree if a modification is still going
|
||||||
|
// TODO is this lock necessary for anything beyond this tick method?
|
||||||
if (this.treeLock.tryLock())
|
if (this.treeLock.tryLock())
|
||||||
{
|
{
|
||||||
// this shouldn't be updated while the tree is being iterated through
|
// this shouldn't be updated while the tree is being iterated through
|
||||||
@@ -508,28 +514,23 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
// the section only needs to be updated if a buffer is currently present
|
||||||
|
LodRenderSection renderSection = this.tryGetValue(pos);
|
||||||
|
if (renderSection != null)
|
||||||
{
|
{
|
||||||
// the section only needs to be updated if a buffer is currently present
|
if (renderSection.canRender())
|
||||||
LodRenderSection renderSection = this.getValue(pos);
|
|
||||||
if (renderSection != null)
|
|
||||||
{
|
{
|
||||||
if (renderSection.canRender())
|
if (renderSection.gpuUploadInProgress()
|
||||||
|
|| !renderSection.uploadRenderDataToGpuAsync())
|
||||||
{
|
{
|
||||||
if (renderSection.gpuUploadInProgress()
|
// if a section is already loading or failed to start upload
|
||||||
|| !renderSection.uploadRenderDataToGpuAsync())
|
// we need to wait to trigger it again
|
||||||
{
|
// if we don't trigger it again the LOD will be out of date
|
||||||
// if a section is already loading or failed to start upload
|
// and may be invisible/missing
|
||||||
// we need to wait to trigger it again
|
positionsToRequeue.add(pos);
|
||||||
// if we don't trigger it again the LOD will be out of date
|
|
||||||
// and may be invisible/missing
|
|
||||||
positionsToRequeue.add(pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e)
|
|
||||||
{ /* the section is now out of bounds, it doesn't need to be reloaded */ }
|
|
||||||
}
|
}
|
||||||
this.sectionsToReload.addAll(positionsToRequeue);
|
this.sectionsToReload.addAll(positionsToRequeue);
|
||||||
}
|
}
|
||||||
@@ -622,12 +623,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
|||||||
// task finished
|
// task finished
|
||||||
this.queuedGenerationPosSet.remove(missingPos);
|
this.queuedGenerationPosSet.remove(missingPos);
|
||||||
|
|
||||||
// if the task failed re-queue so we can try again
|
if (result.state == ERetrievalResultState.REQUIRES_SPLITTING)
|
||||||
if (result.state == ERetrievalResultState.FAIL)
|
|
||||||
{
|
|
||||||
this.missingGenerationPosSet.add(missingPos);
|
|
||||||
}
|
|
||||||
else if (result.state == ERetrievalResultState.REQUIRES_SPLITTING)
|
|
||||||
{
|
{
|
||||||
DhSectionPos.forEachChild(missingPos, (long childPos) ->
|
DhSectionPos.forEachChild(missingPos, (long childPos) ->
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
|||||||
* contains the list of beacons currently being rendered in this section
|
* contains the list of beacons currently being rendered in this section
|
||||||
* if this list is modified the {@link LodRenderSection#beaconRenderHandler} should be updated to match.
|
* if this list is modified the {@link LodRenderSection#beaconRenderHandler} should be updated to match.
|
||||||
*/
|
*/
|
||||||
private final List<BeaconBeamDTO> activeBeaconList = new ArrayList<>();
|
private final ArrayList<BeaconBeamDTO> activeBeaconList = new ArrayList<>();
|
||||||
@Nullable
|
@Nullable
|
||||||
public final BeaconRenderHandler beaconRenderHandler;
|
public final BeaconRenderHandler beaconRenderHandler;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -446,20 +446,15 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
|||||||
|
|
||||||
|
|
||||||
// stop rendering current beacons
|
// stop rendering current beacons
|
||||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
this.beaconRenderHandler.stopRenderingBeacons(this.activeBeaconList);
|
||||||
{
|
|
||||||
this.beaconRenderHandler.stopRenderingBeaconAtPos(beam.blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// swap old and new active beacon list
|
// swap old and new active beacon list
|
||||||
this.activeBeaconList.clear();
|
this.activeBeaconList.clear();
|
||||||
this.activeBeaconList.addAll(activeBeacons);
|
this.activeBeaconList.addAll(activeBeacons);
|
||||||
|
|
||||||
// start rendering new beacon list
|
// start rendering new beacon list
|
||||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
byte absoluteDetailLevel = (byte)(DhSectionPos.getDetailLevel(this.pos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
|
||||||
{
|
this.beaconRenderHandler.startRenderingBeacons(this.activeBeaconList, absoluteDetailLevel);
|
||||||
this.beaconRenderHandler.startRenderingBeacon(beam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,10 +469,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
|||||||
|
|
||||||
synchronized (this.activeBeaconList)
|
synchronized (this.activeBeaconList)
|
||||||
{
|
{
|
||||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
this.beaconRenderHandler.stopRenderingBeacons(this.activeBeaconList);
|
||||||
{
|
|
||||||
this.beaconRenderHandler.stopRenderingBeaconAtPos(beam.blockPos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,10 +484,8 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
|||||||
|
|
||||||
synchronized (this.activeBeaconList)
|
synchronized (this.activeBeaconList)
|
||||||
{
|
{
|
||||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
byte absoluteDetailLevel = (byte)(DhSectionPos.getDetailLevel(this.pos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
|
||||||
{
|
this.beaconRenderHandler.startRenderingBeacons(this.activeBeaconList, absoluteDetailLevel);
|
||||||
this.beaconRenderHandler.startRenderingBeacon(beam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+444
@@ -0,0 +1,444 @@
|
|||||||
|
package com.seibel.distanthorizons.core.render.renderer;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class DepthCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
public static DepthCalculator INSTANCE = new DepthCalculator();
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
|
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||||
|
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||||
|
|
||||||
|
|
||||||
|
private float[] mcOpaqueDepthTextureValues = new float[1];
|
||||||
|
private float[] mcTransparentDepthTextureValues = new float[1];
|
||||||
|
private float[] dhDepthTextureValues = new float[1];
|
||||||
|
private float[] outDepthTextureValues = new float[1];
|
||||||
|
private float lastClosestDhDepth = 1.0f;
|
||||||
|
|
||||||
|
public float actualMcBlockDistance = 8 * 16; // needs to be non-zero to start DH rendering
|
||||||
|
@Deprecated // Replace with thread pool and an AtomicBool for running state
|
||||||
|
public Thread thread = null;
|
||||||
|
public boolean pause = false;
|
||||||
|
|
||||||
|
private boolean gotDhDepthThisFrame = false;
|
||||||
|
private boolean gotMcDepthThisFrame = false;
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
private DepthCalculator() { }
|
||||||
|
|
||||||
|
|
||||||
|
//======//
|
||||||
|
// test //
|
||||||
|
//======//
|
||||||
|
|
||||||
|
public void getMcOpaqueDepthTexture() { this.gotMcDepthThisFrame = this.trySetDepthTexture(MC_RENDER.getDepthTextureId(), this.mcOpaqueDepthTextureValues); }
|
||||||
|
public void getMcTransparentDepthTexture() { this.gotMcDepthThisFrame = this.trySetDepthTexture(MC_RENDER.getDepthTextureId(), this.mcTransparentDepthTextureValues); }
|
||||||
|
public void trySetDhDepthTexture() { this.gotDhDepthThisFrame = this.trySetDepthTexture(LodRenderer.INSTANCE.getActiveDepthTextureId(), this.dhDepthTextureValues); }
|
||||||
|
private boolean trySetDepthTexture(int id, float[] outputRef)
|
||||||
|
{
|
||||||
|
// don't change the texture if a process is already running
|
||||||
|
if (this.thread != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resizeTexturesIfNeeded();
|
||||||
|
if (id == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME this is slow and causes frame stuttering
|
||||||
|
GL46.glGetTextureImage(id, 0, GL32.GL_DEPTH_COMPONENT, GL32.GL_FLOAT, outputRef);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private void resizeTexturesIfNeeded()
|
||||||
|
{
|
||||||
|
int width = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||||
|
int height = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||||
|
int elementCount = width * height;
|
||||||
|
if (this.dhDepthTextureValues.length != elementCount)
|
||||||
|
{
|
||||||
|
this.mcOpaqueDepthTextureValues = new float[width * height];
|
||||||
|
this.mcTransparentDepthTextureValues = new float[width * height];
|
||||||
|
|
||||||
|
this.dhDepthTextureValues = new float[width * height];
|
||||||
|
this.outDepthTextureValues = new float[width * height];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void tryCalculateAsync()
|
||||||
|
{
|
||||||
|
if (this.thread != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!this.gotDhDepthThisFrame
|
||||||
|
// || !this.gotMcDepthThisFrame)
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (this.pause)
|
||||||
|
{
|
||||||
|
int k = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.thread = new Thread(() ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.calculateDepth();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOGGER.error("async test: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.thread = null;
|
||||||
|
this.pause = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.thread.start();
|
||||||
|
}
|
||||||
|
public void calculateDepth()
|
||||||
|
{
|
||||||
|
int width = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||||
|
int height = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||||
|
int elementCount = width * height;
|
||||||
|
|
||||||
|
|
||||||
|
// used to calculate the DH render matrices
|
||||||
|
RenderParams renderParams =
|
||||||
|
new RenderParams(
|
||||||
|
EDhApiRenderPass.OPAQUE,
|
||||||
|
ClientApi.RENDER_STATE.frameTime,
|
||||||
|
ClientApi.RENDER_STATE.mcProjectionMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper
|
||||||
|
);
|
||||||
|
|
||||||
|
Mat4f dhInvProj = new Mat4f(renderParams.dhProjectionMatrix);
|
||||||
|
dhInvProj.invert();
|
||||||
|
Matrix4f dhInvProjJoml = dhInvProj.createJomlMatrix();
|
||||||
|
|
||||||
|
Mat4f dhInvMvm = new Mat4f(renderParams.dhModelViewMatrix);
|
||||||
|
dhInvMvm.invert();
|
||||||
|
Matrix4f dhInvMvmJoml = dhInvMvm.createJomlMatrix(); // TODO can we use JOML for MC 1.16?
|
||||||
|
|
||||||
|
|
||||||
|
float[] sampledDistances = new float[9];
|
||||||
|
|
||||||
|
// find the closest depth value MC hasn't drawn to
|
||||||
|
float closestDhDepth = 1.0f; float closestDhDistance = Float.MAX_VALUE;
|
||||||
|
int closeUIndex = 0; int closeVIndex = 0;
|
||||||
|
for (int u = 0; u < width; u++) // x
|
||||||
|
{
|
||||||
|
for (int v = 0; v < height; v++) // y
|
||||||
|
{
|
||||||
|
int invertedV = height - 1 - v;
|
||||||
|
int i = (invertedV * width) + u;
|
||||||
|
|
||||||
|
|
||||||
|
this.outDepthTextureValues[i] = 0.0f;
|
||||||
|
|
||||||
|
float mcDepth = Config.Client.dynamicFadeUseOpaqueMcDepth.get()
|
||||||
|
? this.mcOpaqueDepthTextureValues[i]
|
||||||
|
: this.mcTransparentDepthTextureValues[i];
|
||||||
|
if (mcDepth < 1.0f) // ignore positions MC has drawn to
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dhDepth = this.dhDepthTextureValues[i];
|
||||||
|
if (dhDepth == 1.0f) // ignore positions DH has NOT drawn to
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.outDepthTextureValues[i] = dhDepth;
|
||||||
|
|
||||||
|
|
||||||
|
// calculate this point's distance from the camera
|
||||||
|
float ndcU = u / (float)width;
|
||||||
|
float ndcV = invertedV / (float)height;
|
||||||
|
float dist = convertDepthToBlockDistance(ndcU, ndcV, dhInvProjJoml, dhInvMvmJoml, dhDepth);
|
||||||
|
|
||||||
|
//// sample the 9 surrounding pixels to account for off-by-one errors between the MC and DH depth textures
|
||||||
|
//int sampleIndex = 0;
|
||||||
|
//for (int relU = -1; relU < 1; relU++)
|
||||||
|
//{
|
||||||
|
// for (int relV = -1; relV < 1; relV++)
|
||||||
|
// {
|
||||||
|
// invertedV = height - 1 - v + relV;
|
||||||
|
// i = (invertedV * width) + u + relU;
|
||||||
|
// dhDepth = this.dhDepthTextureValues[i];
|
||||||
|
//
|
||||||
|
// if (v + relV < 0 || v + relV > height
|
||||||
|
// || u + relU < 0 || u + relU > width)
|
||||||
|
// {
|
||||||
|
// sampledDistances[sampleIndex] = 0.0f;
|
||||||
|
// sampleIndex++;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // calculate this point's distance from the camera
|
||||||
|
// float ndcU = u / (float)width;
|
||||||
|
// float ndcV = invertedV / (float)height;
|
||||||
|
// float dist = convertDepthToBlockDistance(ndcU, ndcV, dhInvProjJoml, dhInvMvmJoml, dhDepth);
|
||||||
|
//
|
||||||
|
// sampledDistances[sampleIndex] = dist;
|
||||||
|
// sampleIndex++;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//Arrays.sort(sampledDistances);
|
||||||
|
//// return the median element
|
||||||
|
//float dist = sampledDistances[sampledDistances.length / 2];
|
||||||
|
//if (dist == 0.0f)
|
||||||
|
//{
|
||||||
|
// // the median was 0, return the smallest non-zero element
|
||||||
|
// for (sampleIndex = 0; sampleIndex < sampledDistances.length; sampleIndex++)
|
||||||
|
// {
|
||||||
|
// if (sampledDistances[sampleIndex] != 0.0f)
|
||||||
|
// {
|
||||||
|
// dist = sampledDistances[sampleIndex];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (dist < closestDhDistance)
|
||||||
|
{
|
||||||
|
closestDhDepth = dhDepth;
|
||||||
|
closestDhDistance = dist;
|
||||||
|
|
||||||
|
closeUIndex = u;
|
||||||
|
closeVIndex = invertedV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (this.lastClosestDhDepth != closestDhDepth)
|
||||||
|
{
|
||||||
|
NumberFormat numForm = NumberFormat.getNumberInstance();
|
||||||
|
ClientApi.INSTANCE.showChatMessageNextFrame(
|
||||||
|
"closest: ["+numForm.format(closestDhDepth)+"]-b["+numForm.format(closestDhDistance)+"]c["+numForm.format(closestDhDistance/16)+"] ("+(closeUIndex)+","+(closeVIndex)+")" +
|
||||||
|
"");
|
||||||
|
|
||||||
|
this.actualMcBlockDistance = closestDhDistance;
|
||||||
|
}
|
||||||
|
this.lastClosestDhDepth = closestDhDepth;
|
||||||
|
|
||||||
|
|
||||||
|
if (this.pause)
|
||||||
|
{
|
||||||
|
// find the range of depth values used by both textures for clearer exporting
|
||||||
|
float closestMcDepth = 1.0f; float furthestMcDepth = 0.0f;
|
||||||
|
float minDhDepth = 1.0f; float maxDhDepth = 0.0f;
|
||||||
|
for (int i = 0; i < elementCount; i++)
|
||||||
|
{
|
||||||
|
float mcDepth = this.mcOpaqueDepthTextureValues[i];
|
||||||
|
if (mcDepth != 0.0f && mcDepth != 1.0f)
|
||||||
|
{
|
||||||
|
if (mcDepth < closestMcDepth)
|
||||||
|
{
|
||||||
|
closestMcDepth = mcDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mcDepth > furthestMcDepth)
|
||||||
|
{
|
||||||
|
furthestMcDepth = mcDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float dhDepth = this.dhDepthTextureValues[i];
|
||||||
|
if (dhDepth != 0.0f && dhDepth != 1.0f)
|
||||||
|
{
|
||||||
|
if (dhDepth < minDhDepth)
|
||||||
|
{
|
||||||
|
minDhDepth = dhDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dhDepth > maxDhDepth)
|
||||||
|
{
|
||||||
|
maxDhDepth = dhDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String exportPath = Config.Client.dynamicFadeExportPath.get();
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.showChatMessageNextFrame("exporting debug textures to: ["+exportPath+"]...");
|
||||||
|
|
||||||
|
// mc opaque
|
||||||
|
createImg(
|
||||||
|
this.mcOpaqueDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
(Float depth) -> { return null; },
|
||||||
|
width, height, closestMcDepth, furthestMcDepth,
|
||||||
|
exportPath+"mc-opaque_depth.png");
|
||||||
|
|
||||||
|
// mc transparent
|
||||||
|
createImg(
|
||||||
|
this.mcTransparentDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
(Float depth) -> { return null; },
|
||||||
|
width, height, closestMcDepth, furthestMcDepth,
|
||||||
|
exportPath+"mc-tran_depth.png");
|
||||||
|
|
||||||
|
// dh
|
||||||
|
Function<Float, Color> customColorFunc = (Float depth) ->
|
||||||
|
{
|
||||||
|
if (depth == this.lastClosestDhDepth)
|
||||||
|
{
|
||||||
|
return Color.RED;
|
||||||
|
}
|
||||||
|
//else if (depth <= (lastClosestDhDepth + 0.01f))
|
||||||
|
//{
|
||||||
|
// return Color.ORANGE;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
createImg(
|
||||||
|
this.dhDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
customColorFunc,
|
||||||
|
width, height, minDhDepth, maxDhDepth,
|
||||||
|
exportPath+"dh_depth.png");
|
||||||
|
|
||||||
|
// temp
|
||||||
|
|
||||||
|
createImg(
|
||||||
|
this.outDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
(Float depth) -> { return null; },
|
||||||
|
width, height, minDhDepth, maxDhDepth,
|
||||||
|
exportPath+"temp_depth.png");
|
||||||
|
|
||||||
|
int breakPoint = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** NDC (Normalized Device Coordinates) must be between 0.0 and 1.0 (inclusive) */
|
||||||
|
private static float convertDepthToBlockDistance(float ndcU, float ndcV, Matrix4f invProj, Matrix4f invMvm, float depth)
|
||||||
|
{
|
||||||
|
// This assumes depth is scaled to [0, 1]
|
||||||
|
// Transform depth to clip space Z value
|
||||||
|
float z = depth * 2.0f - 1.0f;
|
||||||
|
|
||||||
|
// Create a vector in clip space
|
||||||
|
Vector4f clipSpacePosition = new Vector4f(ndcU, ndcV, z, 1.0f);
|
||||||
|
|
||||||
|
// Transform to world space
|
||||||
|
Vector4f worldSpacePosition = clipSpacePosition.mul(invProj);
|
||||||
|
worldSpacePosition.div(worldSpacePosition.w); // Perform perspective divide
|
||||||
|
|
||||||
|
// Finally apply the inverse model-view matrix to get world space coordinates
|
||||||
|
worldSpacePosition = worldSpacePosition.mul(invMvm);
|
||||||
|
|
||||||
|
// calculate distance from the camera
|
||||||
|
float distance = worldSpacePosition.distance(0, 0, 0, 0);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
private static void createImg(
|
||||||
|
float[] tex,
|
||||||
|
int nearestU, int nearestV,
|
||||||
|
Function<Float, Color> customColorFunc,
|
||||||
|
int width, int height,
|
||||||
|
float minDepth, float maxDepth,
|
||||||
|
String filePath)
|
||||||
|
{
|
||||||
|
// Create a BufferedImage
|
||||||
|
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
|
for (int u = 0; u < width; u++)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < height; v++)
|
||||||
|
{
|
||||||
|
int invertedY = height - 1 - v;
|
||||||
|
|
||||||
|
// Normalize the depth value to a grayscale pixel
|
||||||
|
float depthValue = tex[(invertedY * width) + u];
|
||||||
|
Color color = customColorFunc.apply(depthValue);
|
||||||
|
if (color == null)
|
||||||
|
{
|
||||||
|
float normalizedDepth = (depthValue - minDepth) / (maxDepth - minDepth); // Normalize to 0.0 to 1.0
|
||||||
|
normalizedDepth = Math.max(0.0f, Math.min(1.0f, normalizedDepth)); // Clamp to valid range
|
||||||
|
|
||||||
|
int gray = (int) (normalizedDepth * 255); // Map to 0-255
|
||||||
|
gray = Math.max(0, Math.min(255, gray)); // Clamp to valid range
|
||||||
|
color = new Color(gray, gray, gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthValue == 1.0f)
|
||||||
|
{
|
||||||
|
color = new Color(0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u == nearestU)
|
||||||
|
{
|
||||||
|
color = Color.MAGENTA;
|
||||||
|
}
|
||||||
|
else if (invertedY == nearestV)
|
||||||
|
{
|
||||||
|
color = Color.ORANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
image.setRGB(u, v, color.getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the image to a file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ImageIO.write(image, "png", new File(filePath));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
LOGGER.error("Unable to write texture to file, error: ["+e.getMessage()+"].", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+7
-7
@@ -204,17 +204,17 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade
|
|||||||
this.setUniform(this.uIsWhiteWorld, Config.Client.Advanced.Debugging.enableWhiteWorld.get());
|
this.setUniform(this.uIsWhiteWorld, Config.Client.Advanced.Debugging.enableWhiteWorld.get());
|
||||||
|
|
||||||
// Clip Uniform
|
// Clip Uniform
|
||||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocksForFading(renderParameters.partialTicks);
|
float dhNearClipDistance = 0.1f;//RenderUtil.getNearClipPlaneInBlocksForFading(renderParameters.partialTicks);
|
||||||
if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
//if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
{
|
//{
|
||||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
// // this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||||
dhNearClipDistance += 16f;
|
// dhNearClipDistance += 16f;
|
||||||
}
|
//}
|
||||||
// if the player is very high up and the near clip plane has been modified, disable the distance clipping
|
// if the player is very high up and the near clip plane has been modified, disable the distance clipping
|
||||||
// we're high enough that nothing will render on top of the player and this can cause issues otherwise
|
// we're high enough that nothing will render on top of the player and this can cause issues otherwise
|
||||||
if (RenderUtil.getHeightBasedNearClipOverride() != -1)
|
if (RenderUtil.getHeightBasedNearClipOverride() != -1)
|
||||||
{
|
{
|
||||||
dhNearClipDistance = 1.0f;
|
dhNearClipDistance = 1.0f; // TODO does this actually disable anything?
|
||||||
}
|
}
|
||||||
this.setUniform(this.uClipDistance, dhNearClipDistance);
|
this.setUniform(this.uClipDistance, dhNearClipDistance);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,8 @@ public class LodRenderer
|
|||||||
profiler.popPush("LOD Opaque");
|
profiler.popPush("LOD Opaque");
|
||||||
this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ true);
|
this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ true);
|
||||||
|
|
||||||
|
DepthCalculator.INSTANCE.trySetDhDepthTexture();
|
||||||
|
|
||||||
// custom objects with SSAO
|
// custom objects with SSAO
|
||||||
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
|
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
|
||||||
{
|
{
|
||||||
@@ -434,7 +436,7 @@ public class LodRenderer
|
|||||||
|
|
||||||
// resize the textures if needed
|
// resize the textures if needed
|
||||||
if (MC_RENDER.getTargetFramebufferViewportWidth() != this.textureWidth
|
if (MC_RENDER.getTargetFramebufferViewportWidth() != this.textureWidth
|
||||||
|| MC_RENDER.getTargetFramebufferViewportHeight() != this.textureHeight)
|
|| MC_RENDER.getTargetFramebufferViewportHeight() != this.textureHeight)
|
||||||
{
|
{
|
||||||
// just resizing the textures doesn't work when Optifine is present,
|
// just resizing the textures doesn't work when Optifine is present,
|
||||||
// so recreate the textures with the new size instead
|
// so recreate the textures with the new size instead
|
||||||
@@ -536,7 +538,7 @@ public class LodRenderer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "deprecation" )
|
@SuppressWarnings( "deprecation" ) // done to ignore DhApiColorDepthTextureCreatedEvent
|
||||||
private void createAndBindTextures()
|
private void createAndBindTextures()
|
||||||
{
|
{
|
||||||
int oldWidth = this.textureWidth;
|
int oldWidth = this.textureWidth;
|
||||||
|
|||||||
+99
-12
@@ -28,6 +28,7 @@ import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShad
|
|||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
@@ -39,8 +40,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@@ -54,6 +54,8 @@ public class BeaconRenderHandler
|
|||||||
/** how often should we check if a beacon should be culled? */
|
/** how often should we check if a beacon should be culled? */
|
||||||
private static final int MAX_CULLING_FREQUENCY_IN_MS = 1_000;
|
private static final int MAX_CULLING_FREQUENCY_IN_MS = 1_000;
|
||||||
|
|
||||||
|
private static final Comparator<BeaconBeamDTO> NEGATIVE_BLOCKPOS_COMPARATOR = new NegativeInfiniteBlockPosComparator();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final ReentrantLock updateLock = new ReentrantLock();
|
private final ReentrantLock updateLock = new ReentrantLock();
|
||||||
@@ -89,20 +91,74 @@ public class BeaconRenderHandler
|
|||||||
// render handling //
|
// render handling //
|
||||||
//=================//
|
//=================//
|
||||||
|
|
||||||
public void startRenderingBeacon(BeaconBeamDTO beacon)
|
public void startRenderingBeacons(ArrayList<BeaconBeamDTO> beaconList, byte detailLevel)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.updateLock.lock();
|
this.updateLock.lock();
|
||||||
|
|
||||||
if (this.beaconBlockPosSet.add(beacon.blockPos))
|
|
||||||
|
// how wide should each beacon be?
|
||||||
|
int beaconBlockWidth = 1;
|
||||||
|
if (Config.Client.Advanced.Graphics.GenericRendering.expandDistantBeacons.get())
|
||||||
{
|
{
|
||||||
|
beaconBlockWidth = DhSectionPos.getBlockWidth(detailLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<BeaconBeamDTO> sortedBeaconList = new ArrayList<>(beaconList);
|
||||||
|
|
||||||
|
// merge distant beams if requested
|
||||||
|
if (Config.Client.Advanced.Graphics.GenericRendering.expandDistantBeacons.get())
|
||||||
|
{
|
||||||
|
// sort beacons from neg inf -> pos inf
|
||||||
|
// so we can consistently merge adjacent beacons
|
||||||
|
sortedBeaconList.sort(NEGATIVE_BLOCKPOS_COMPARATOR);
|
||||||
|
|
||||||
|
// go through each beacon...
|
||||||
|
for (int outerIndex = 0; outerIndex < sortedBeaconList.size(); outerIndex++)
|
||||||
|
{
|
||||||
|
BeaconBeamDTO outerBeacon = sortedBeaconList.get(outerIndex);
|
||||||
|
DhBlockPos outerBlockPos = outerBeacon.blockPos;
|
||||||
|
|
||||||
|
// ...and remove any beacons that are within the block width to prevent overlaps
|
||||||
|
for (int mergeIndex = outerIndex + 1; mergeIndex < sortedBeaconList.size(); mergeIndex++)
|
||||||
|
{
|
||||||
|
BeaconBeamDTO beaconToMerge = sortedBeaconList.get(mergeIndex);
|
||||||
|
DhBlockPos mergeBlockPos = beaconToMerge.blockPos;
|
||||||
|
|
||||||
|
int xDiff = mergeBlockPos.getX() - outerBlockPos.getX();
|
||||||
|
int zDiff = mergeBlockPos.getZ() - outerBlockPos.getZ();
|
||||||
|
|
||||||
|
// merge (remove) this beacon if
|
||||||
|
// it's close to the outer beacon
|
||||||
|
if (xDiff < beaconBlockWidth
|
||||||
|
&& zDiff < beaconBlockWidth)
|
||||||
|
{
|
||||||
|
sortedBeaconList.remove(mergeIndex);
|
||||||
|
mergeIndex--; // minus 1 so we don't go past the end of the array when incrementing in the for loop up top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// add each beacon to the renderer
|
||||||
|
for (int i = 0; i < sortedBeaconList.size(); i++)
|
||||||
|
{
|
||||||
|
BeaconBeamDTO beacon = sortedBeaconList.get(i);
|
||||||
|
if (!this.beaconBlockPosSet.add(beacon.blockPos))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int maxBeaconBeamHeight = Config.Client.Advanced.Graphics.GenericRendering.beaconRenderHeight.get();
|
int maxBeaconBeamHeight = Config.Client.Advanced.Graphics.GenericRendering.beaconRenderHeight.get();
|
||||||
DhApiRenderableBox beaconBox = new DhApiRenderableBox(
|
DhApiRenderableBox beaconBox = new DhApiRenderableBox(
|
||||||
new DhApiVec3d(beacon.blockPos.getX(), beacon.blockPos.getY() + 1, beacon.blockPos.getZ()),
|
new DhApiVec3d(beacon.blockPos.getX(), beacon.blockPos.getY() + 1, beacon.blockPos.getZ()),
|
||||||
new DhApiVec3d(beacon.blockPos.getX() + 1, maxBeaconBeamHeight, beacon.blockPos.getZ() + 1),
|
new DhApiVec3d(beacon.blockPos.getX() + beaconBlockWidth, maxBeaconBeamHeight, beacon.blockPos.getZ() + beaconBlockWidth),
|
||||||
beacon.color,
|
beacon.color,
|
||||||
EDhApiBlockMaterial.ILLUMINATED
|
EDhApiBlockMaterial.ILLUMINATED
|
||||||
);
|
);
|
||||||
|
|
||||||
this.beaconBoxGroup.add(beaconBox);
|
this.beaconBoxGroup.add(beaconBox);
|
||||||
@@ -116,19 +172,26 @@ public class BeaconRenderHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopRenderingBeaconAtPos(DhBlockPos beaconPos)
|
public void stopRenderingBeacons(ArrayList<BeaconBeamDTO> beaconList)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.updateLock.lock();
|
this.updateLock.lock();
|
||||||
|
|
||||||
if (this.beaconBlockPosSet.remove(beaconPos))
|
for (int i = 0; i < beaconList.size(); i++)
|
||||||
{
|
{
|
||||||
|
BeaconBeamDTO beacon = beaconList.get(i);
|
||||||
|
DhBlockPos beaconPos = beacon.blockPos;
|
||||||
|
if (!this.beaconBlockPosSet.remove(beaconPos))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Predicate<DhApiRenderableBox> removePredicate = (DhApiRenderableBox box) ->
|
Predicate<DhApiRenderableBox> removePredicate = (DhApiRenderableBox box) ->
|
||||||
{
|
{
|
||||||
return box.minPos.x == beaconPos.getX()
|
return box.minPos.x == beaconPos.getX()
|
||||||
&& box.minPos.y == beaconPos.getY() + 1 // plus 1 because the beam starts above the beacon
|
&& box.minPos.y == beaconPos.getY() + 1 // plus 1 because the beam starts above the beacon
|
||||||
&& box.minPos.z == beaconPos.getZ();
|
&& box.minPos.z == beaconPos.getZ();
|
||||||
};
|
};
|
||||||
this.beaconBoxGroup.removeIf(removePredicate);
|
this.beaconBoxGroup.removeIf(removePredicate);
|
||||||
this.fullBeaconBoxList.removeIf(removePredicate);
|
this.fullBeaconBoxList.removeIf(removePredicate);
|
||||||
@@ -255,4 +318,28 @@ public class BeaconRenderHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
private static class NegativeInfiniteBlockPosComparator implements Comparator<BeaconBeamDTO>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int compare(BeaconBeamDTO beacon1, BeaconBeamDTO beacon2)
|
||||||
|
{
|
||||||
|
DhBlockPos blockPos1 = beacon1.blockPos;
|
||||||
|
DhBlockPos blockPos2 = beacon2.blockPos;
|
||||||
|
|
||||||
|
// sort by X, then by Z
|
||||||
|
if (blockPos1.getX() != blockPos2.getX())
|
||||||
|
{
|
||||||
|
return Integer.compare(blockPos1.getX(), blockPos2.getX());
|
||||||
|
}
|
||||||
|
return Integer.compare(blockPos1.getZ(), blockPos2.getZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -493,7 +493,7 @@ public class CloudRenderHandler
|
|||||||
|
|
||||||
private static boolean[][] getCloudsFromTexture() throws FileNotFoundException, IOException
|
private static boolean[][] getCloudsFromTexture() throws FileNotFoundException, IOException
|
||||||
{
|
{
|
||||||
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
final ClassLoader loader = CloudRenderHandler.class.getClassLoader();
|
||||||
|
|
||||||
boolean[][] whitePixels = null;
|
boolean[][] whitePixels = null;
|
||||||
try(InputStream imageInputStream = loader.getResourceAsStream(CLOUD_RESOURCE_TEXTURE_PATH))
|
try(InputStream imageInputStream = loader.getResourceAsStream(CLOUD_RESOURCE_TEXTURE_PATH))
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||||
@@ -114,7 +115,7 @@ public class VanillaFadeShader extends AbstractShaderRenderer
|
|||||||
|
|
||||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocksForFading(partialTicks);
|
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocksForFading(partialTicks);
|
||||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||||
dhNearClipDistance += 16f;
|
//dhNearClipDistance += 16f;
|
||||||
|
|
||||||
// measured in blocks
|
// measured in blocks
|
||||||
// these multipliers in James' tests should provide a fairly smooth transition
|
// these multipliers in James' tests should provide a fairly smooth transition
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public class DatabaseUpdater
|
|||||||
/** @throws NullPointerException if any of the script files failed to be read. */
|
/** @throws NullPointerException if any of the script files failed to be read. */
|
||||||
private static ArrayList<SqlScript> getAutoUpdateScripts() throws NullPointerException, IOException
|
private static ArrayList<SqlScript> getAutoUpdateScripts() throws NullPointerException, IOException
|
||||||
{
|
{
|
||||||
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
final ClassLoader loader = DatabaseUpdater.class.getClassLoader();
|
||||||
|
|
||||||
|
|
||||||
// get the script list
|
// get the script list
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ public class BeaconBeamDTO implements IBaseDTO<DhBlockPos>, INetworkObject
|
|||||||
public void close()
|
public void close()
|
||||||
{ /* no closing needed */ }
|
{ /* no closing needed */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() { return this.blockPos + " " + this.color; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.core.util;
|
package com.seibel.distanthorizons.core.util;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.render.renderer.DepthCalculator;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -127,13 +129,16 @@ public class RenderUtil
|
|||||||
}
|
}
|
||||||
public static float getNearClipPlaneInBlocksForFading(float partialTicks)
|
public static float getNearClipPlaneInBlocksForFading(float partialTicks)
|
||||||
{
|
{
|
||||||
float overdraw = getAutoOverdrawPrevention();
|
//float overdraw = getAutoOverdrawPrevention();
|
||||||
return getNearClipPlaneDistanceInBlocks(partialTicks, overdraw);
|
//return getNearClipPlaneDistanceInBlocks(partialTicks, overdraw);
|
||||||
|
|
||||||
|
return DepthCalculator.INSTANCE.actualMcBlockDistance;
|
||||||
}
|
}
|
||||||
private static float getNearClipPlaneDistanceInBlocks(float partialTicks, float overdrawPreventionPercent)
|
private static float getNearClipPlaneDistanceInBlocks(float partialTicks, float overdrawPreventionPercent)
|
||||||
{
|
{
|
||||||
int chunkRenderDistance = MC_RENDER.getRenderDistance();
|
int chunkRenderDistance = MC_RENDER.getRenderDistance();
|
||||||
int vanillaBlockRenderedDistance = chunkRenderDistance * LodUtil.CHUNK_WIDTH;
|
//float chunkRenderDistance = ClientApi.actualMcBlockDistance / 16.0f;
|
||||||
|
float vanillaBlockRenderedDistance = chunkRenderDistance * LodUtil.CHUNK_WIDTH;
|
||||||
|
|
||||||
float nearClipPlane;
|
float nearClipPlane;
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
|
|||||||
+36
-50
@@ -31,12 +31,10 @@ import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
|||||||
import com.seibel.distanthorizons.core.util.gridList.MovableGridRingList;
|
import com.seibel.distanthorizons.core.util.gridList.MovableGridRingList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
|
import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
|
||||||
import it.unimi.dsi.fastutil.longs.LongIterator;
|
import it.unimi.dsi.fastutil.longs.LongIterator;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.LongConsumer;
|
import java.util.function.LongConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,9 +96,27 @@ public class QuadTree<T>
|
|||||||
// getters and setters //
|
// getters and setters //
|
||||||
//=====================//
|
//=====================//
|
||||||
|
|
||||||
|
/** @return the value at the given section position. Null will be returned if the value is missing or the position is out of bounds. */
|
||||||
|
@Nullable
|
||||||
|
public final T tryGetValue(long pos)
|
||||||
|
{
|
||||||
|
QuadNode<T> node = this.tryGetNode(pos);
|
||||||
|
if (node != null)
|
||||||
|
{
|
||||||
|
return node.value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return the node at the given section position, null if out of bounds */
|
||||||
|
@Nullable
|
||||||
|
public final QuadNode<T> tryGetNode(long pos) { return this.getOrSetNode(pos, false, null, false); }
|
||||||
|
|
||||||
|
|
||||||
/** @return the node at the given section position */
|
/** @return the node at the given section position */
|
||||||
@Nullable
|
@Nullable
|
||||||
public final QuadNode<T> getNode(long pos) throws IndexOutOfBoundsException { return this.getOrSetNode(pos, false, null, true); }
|
public final QuadNode<T> getNode(long pos) throws IndexOutOfBoundsException { return this.getOrSetNode(pos, false, null, true); }
|
||||||
|
|
||||||
/** @return the value at the given section position */
|
/** @return the value at the given section position */
|
||||||
@Nullable
|
@Nullable
|
||||||
public final T getValue(long pos) throws IndexOutOfBoundsException
|
public final T getValue(long pos) throws IndexOutOfBoundsException
|
||||||
@@ -122,16 +138,24 @@ public class QuadTree<T>
|
|||||||
return previousValue;
|
return previousValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param runBoundaryChecks should only ever be set to true internally for removing out of bound nodes */
|
/** @param throwIfOutOfBounds if false returns null */
|
||||||
@Nullable
|
@Nullable
|
||||||
protected final QuadNode<T> getOrSetNode(long pos, boolean setNewValue, T newValue, boolean runBoundaryChecks) throws IndexOutOfBoundsException
|
protected final QuadNode<T> getOrSetNode(long pos, boolean setNewValue, T newValue, boolean throwIfOutOfBounds) throws IndexOutOfBoundsException
|
||||||
{
|
{
|
||||||
if (runBoundaryChecks && !this.isSectionPosInBounds(pos))
|
if (!this.isSectionPosInBounds(pos))
|
||||||
{
|
{
|
||||||
int radius = this.diameterInBlocks() / 2;
|
// how should out-of-bounds positions be handled?
|
||||||
DhBlockPos2D minPos = this.getCenterBlockPos().add(new DhBlockPos2D(-radius, -radius));
|
if (throwIfOutOfBounds)
|
||||||
DhBlockPos2D maxPos = this.getCenterBlockPos().add(new DhBlockPos2D(radius, radius));
|
{
|
||||||
throw new IndexOutOfBoundsException("QuadTree GetOrSet failed. Position out of bounds, min pos: " + minPos + ", max pos: " + maxPos + ", min detail level: " + this.treeLeafDetailLevel + ", max detail level: " + this.treeRootDetailLevel + ". Given Position: [" + DhSectionPos.toString(pos) + "] = block pos: " + DhSectionPos.convertToDetailLevel(pos, LodUtil.BLOCK_DETAIL_LEVEL));
|
int radius = this.diameterInBlocks() / 2;
|
||||||
|
DhBlockPos2D minBlockPos = this.getCenterBlockPos().add(new DhBlockPos2D(-radius, -radius));
|
||||||
|
DhBlockPos2D maxBlockPos = this.getCenterBlockPos().add(new DhBlockPos2D(radius, radius));
|
||||||
|
throw new IndexOutOfBoundsException("QuadTree GetOrSet failed. Position out of bounds, min block pos: [" + minBlockPos + "], max block pos: [" + maxBlockPos + "], leaf detail level: [" + this.treeLeafDetailLevel + "], root detail level: [" + this.treeRootDetailLevel + "]. Requested section pos: [" + DhSectionPos.toString(pos) + "].");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -278,46 +302,6 @@ public class QuadTree<T>
|
|||||||
removedItemConsumer.accept(quadNode.value);
|
removedItemConsumer.accept(quadNode.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// // remove out of bound nodes and clean up empty nodes
|
|
||||||
// // Note: this will iterate over a lot of unnecessary nodes, hopefully speed won't be an issue
|
|
||||||
// Iterator<DhSectionPos> rootNodePosIterator = this.rootNodePosIterator();
|
|
||||||
// while (rootNodePosIterator.hasNext())
|
|
||||||
// {
|
|
||||||
// // get the root node (regular nodeIterators won't return them if they are out of bounds)
|
|
||||||
// DhSectionPos rootPos = rootNodePosIterator.next();
|
|
||||||
// QuadNode<T> rootNode = this.getOrSetNode(rootPos, false, null, false);
|
|
||||||
// if (rootNode == null)
|
|
||||||
// {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // remove any child nodes that are out of bounds
|
|
||||||
// Iterator<QuadNode<T>> nodeIterator = this.nodeIterator();
|
|
||||||
// while (nodeIterator.hasNext())
|
|
||||||
// {
|
|
||||||
// QuadNode<T> node = nodeIterator.next();
|
|
||||||
// if(!this.isSectionPosInBounds(node.sectionPos))
|
|
||||||
// {
|
|
||||||
// // node is out of bounds
|
|
||||||
//
|
|
||||||
// // FIXME(?) this appears to potentially return large nodes that are partially or entirely in bounds
|
|
||||||
//
|
|
||||||
// if (node.getNonNullChildCount() == 0)
|
|
||||||
// {
|
|
||||||
// // no child nodes, can be safely removed
|
|
||||||
// nodeIterator.remove();
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// // node can't be removed, but its value can be set to null
|
|
||||||
// node.value = null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final DhBlockPos2D getCenterBlockPos() { return this.centerBlockPos; }
|
public final DhBlockPos2D getCenterBlockPos() { return this.centerBlockPos; }
|
||||||
@@ -544,7 +528,9 @@ public class QuadTree<T>
|
|||||||
&& this.rootNodeIterator.hasNext())
|
&& this.rootNodeIterator.hasNext())
|
||||||
{
|
{
|
||||||
long sectionPos = this.rootNodeIterator.nextLong();
|
long sectionPos = this.rootNodeIterator.nextLong();
|
||||||
QuadNode<T> rootNode = QuadTree.this.getNode(sectionPos);
|
|
||||||
|
// try-get to prevent concurrency errors if the tree is being moved while we walk through it
|
||||||
|
QuadNode<T> rootNode = QuadTree.this.tryGetNode(sectionPos);
|
||||||
if (rootNode != null)
|
if (rootNode != null)
|
||||||
{
|
{
|
||||||
nodeIterator = this.onlyReturnLeaves ? rootNode.getLeafNodeIterator() : rootNode.getNodeIterator(this.stopIteratingFunc);
|
nodeIterator = this.onlyReturnLeaves ? rootNode.getLeafNodeIterator() : rootNode.getNodeIterator(this.stopIteratingFunc);
|
||||||
|
|||||||
+5
-6
@@ -30,7 +30,7 @@ import java.util.function.Consumer;
|
|||||||
public class QuadTreeNodeIterator<T> implements Iterator<QuadNode<T>>
|
public class QuadTreeNodeIterator<T> implements Iterator<QuadNode<T>>
|
||||||
{
|
{
|
||||||
/** lowest numerical value, inclusive */
|
/** lowest numerical value, inclusive */
|
||||||
private final byte highestDetailLevel;
|
private final byte leafDetailLevel;
|
||||||
|
|
||||||
|
|
||||||
private final Queue<QuadNode<T>> validNodesForDetailLevel = new ArrayDeque<>();
|
private final Queue<QuadNode<T>> validNodesForDetailLevel = new ArrayDeque<>();
|
||||||
@@ -48,8 +48,7 @@ public class QuadTreeNodeIterator<T> implements Iterator<QuadNode<T>>
|
|||||||
{
|
{
|
||||||
this.onlyReturnLeafValues = onlyReturnLeafValues;
|
this.onlyReturnLeafValues = onlyReturnLeafValues;
|
||||||
this.stopIteratingFunc = stopIteratingFunc;
|
this.stopIteratingFunc = stopIteratingFunc;
|
||||||
// TODO the naming conversion for these are flipped in a lot of places
|
this.leafDetailLevel = rootNode.parentTreeLeafDetailLevel;
|
||||||
this.highestDetailLevel = rootNode.parentTreeLeafDetailLevel;
|
|
||||||
this.iteratorDetailLevel = DhSectionPos.getDetailLevel(rootNode.sectionPos);
|
this.iteratorDetailLevel = DhSectionPos.getDetailLevel(rootNode.sectionPos);
|
||||||
|
|
||||||
|
|
||||||
@@ -110,9 +109,9 @@ public class QuadTreeNodeIterator<T> implements Iterator<QuadNode<T>>
|
|||||||
@Override
|
@Override
|
||||||
public QuadNode<T> next()
|
public QuadNode<T> next()
|
||||||
{
|
{
|
||||||
if (this.iteratorDetailLevel < this.highestDetailLevel)
|
if (this.iteratorDetailLevel < this.leafDetailLevel)
|
||||||
{
|
{
|
||||||
throw new NoSuchElementException("Highest detail level reached [" + this.highestDetailLevel + "].");
|
throw new NoSuchElementException("Leaf detail level reached [" + this.leafDetailLevel + "].");
|
||||||
}
|
}
|
||||||
if (this.iteratorNodeQueue.size() == 0)
|
if (this.iteratorNodeQueue.size() == 0)
|
||||||
{
|
{
|
||||||
@@ -133,7 +132,7 @@ public class QuadTreeNodeIterator<T> implements Iterator<QuadNode<T>>
|
|||||||
|
|
||||||
this.iteratorDetailLevel--;
|
this.iteratorDetailLevel--;
|
||||||
// only continue if we can go down farther
|
// only continue if we can go down farther
|
||||||
if (this.iteratorDetailLevel >= this.highestDetailLevel)
|
if (this.iteratorDetailLevel >= this.leafDetailLevel)
|
||||||
{
|
{
|
||||||
Queue<QuadNode<T>> parentNodes = new LinkedList<>(this.validNodesForDetailLevel);
|
Queue<QuadNode<T>> parentNodes = new LinkedList<>(this.validNodesForDetailLevel);
|
||||||
this.validNodesForDetailLevel.clear();
|
this.validNodesForDetailLevel.clear();
|
||||||
|
|||||||
+7
-1
@@ -69,10 +69,14 @@ public class ThreadPoolUtil
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static ThreadPoolExecutor getBeaconCullingExecutor() { return beaconCullingThreadPool; }
|
public static ThreadPoolExecutor getBeaconCullingExecutor() { return beaconCullingThreadPool; }
|
||||||
|
|
||||||
|
// The main distinction between these thread pools is that one for compression has multiple threads and client handler is single-threaded
|
||||||
private static PriorityTaskPicker.Executor networkCompressionThreadPool;
|
private static PriorityTaskPicker.Executor networkCompressionThreadPool;
|
||||||
@Nullable
|
@Nullable
|
||||||
public static PriorityTaskPicker.Executor getNetworkCompressionExecutor() { return networkCompressionThreadPool; }
|
public static PriorityTaskPicker.Executor getNetworkCompressionExecutor() { return networkCompressionThreadPool; }
|
||||||
|
|
||||||
|
private static ThreadPoolExecutor networkClientHandlerThreadPool;
|
||||||
|
@Nullable
|
||||||
|
public static ThreadPoolExecutor networkClientHandlerExecutor() { return networkClientHandlerThreadPool; }
|
||||||
|
|
||||||
|
|
||||||
public static final String FULL_DATA_MIGRATION_THREAD_NAME = "Full Data Migration";
|
public static final String FULL_DATA_MIGRATION_THREAD_NAME = "Full Data Migration";
|
||||||
@@ -103,7 +107,8 @@ public class ThreadPoolUtil
|
|||||||
}
|
}
|
||||||
taskPicker = new PriorityTaskPicker();
|
taskPicker = new PriorityTaskPicker();
|
||||||
|
|
||||||
networkCompressionThreadPool = taskPicker.createExecutor("Network");
|
networkCompressionThreadPool = taskPicker.createExecutor("Network Compression");
|
||||||
|
networkClientHandlerThreadPool = ThreadUtil.makeSingleThreadPool("Network Client Handler");
|
||||||
fileHandlerThreadPool = taskPicker.createExecutor("IO");
|
fileHandlerThreadPool = taskPicker.createExecutor("IO");
|
||||||
renderSectionLoadThreadPool = taskPicker.createExecutor("Render Loader");
|
renderSectionLoadThreadPool = taskPicker.createExecutor("Render Loader");
|
||||||
chunkToLodBuilderThreadPool = taskPicker.createExecutor("LOD Builder");
|
chunkToLodBuilderThreadPool = taskPicker.createExecutor("LOD Builder");
|
||||||
@@ -133,6 +138,7 @@ public class ThreadPoolUtil
|
|||||||
public static void shutdownThreadPools()
|
public static void shutdownThreadPools()
|
||||||
{
|
{
|
||||||
// standalone threads
|
// standalone threads
|
||||||
|
networkClientHandlerThreadPool.shutdownNow();
|
||||||
taskPicker.shutdownNow();
|
taskPicker.shutdownNow();
|
||||||
beaconCullingThreadPool.shutdown();
|
beaconCullingThreadPool.shutdown();
|
||||||
fullDataMigrationThreadPool.shutdown();
|
fullDataMigrationThreadPool.shutdown();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package com.seibel.distanthorizons.core.world;
|
package com.seibel.distanthorizons.core.world;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.level.DhClientServerLevel;
|
import com.seibel.distanthorizons.core.level.DhClientServerLevel;
|
||||||
import com.seibel.distanthorizons.core.util.TimerUtil;
|
import com.seibel.distanthorizons.core.util.TimerUtil;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
@@ -82,7 +83,7 @@ public class DhClientServerWorld extends AbstractDhServerWorld<DhClientServerLev
|
|||||||
LOGGER.fatal("Failed to load client-server level, error: ["+e.getMessage()+"].", e);
|
LOGGER.fatal("Failed to load client-server level, error: ["+e.getMessage()+"].", e);
|
||||||
|
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
|
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
|
||||||
"\u00A7c" + "Distant Horizons: ClientServer level loading failed." + "\u00A7r \n" +
|
MinecraftTextFormat.RED + "Distant Horizons: ClientServer level loading failed." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"Unable to load level ["+levelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
|
"Unable to load level ["+levelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package com.seibel.distanthorizons.core.world;
|
package com.seibel.distanthorizons.core.world;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
||||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||||
@@ -94,9 +95,9 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld
|
|||||||
{
|
{
|
||||||
LOGGER.fatal("Failed to load client level, error: ["+e.getMessage()+"].", e);
|
LOGGER.fatal("Failed to load client level, error: ["+e.getMessage()+"].", e);
|
||||||
|
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
|
ClientApi.INSTANCE.showChatMessageNextFrame(
|
||||||
"\u00A7c" + "Distant Horizons: Client level loading failed." + "\u00A7r \n" +
|
MinecraftTextFormat.RED + "Distant Horizons: Client level loading failed." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"Unable to load level ["+clientLevelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
|
"Unable to load level ["+clientLevelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package com.seibel.distanthorizons.core.world;
|
package com.seibel.distanthorizons.core.world;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.level.DhServerLevel;
|
import com.seibel.distanthorizons.core.level.DhServerLevel;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||||
@@ -62,9 +63,9 @@ public class DhServerWorld extends AbstractDhServerWorld<DhServerLevel>
|
|||||||
{
|
{
|
||||||
LOGGER.fatal("Failed to load server level, error: ["+e.getMessage()+"].", e);
|
LOGGER.fatal("Failed to load server level, error: ["+e.getMessage()+"].", e);
|
||||||
|
|
||||||
ClientApi.INSTANCE.showChatMessageNextFrame(// red text
|
ClientApi.INSTANCE.showChatMessageNextFrame(
|
||||||
"\u00A7c" + "Distant Horizons: Server level loading failed." + "\u00A7r \n" +
|
MinecraftTextFormat.RED + "Distant Horizons: Server level loading failed." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||||
"Unable to load level ["+serverLevelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
|
"Unable to load level ["+serverLevelWrapper.getDhIdentifier()+"], LODs may not appear. See log for more information.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -63,7 +63,9 @@ public interface IMinecraftRenderWrapper extends IBindable
|
|||||||
/** @return -1 if no valid framebuffer is available yet */
|
/** @return -1 if no valid framebuffer is available yet */
|
||||||
int getTargetFramebuffer(); // Note: Iris is now hooking onto this for DH + Iris compat, try not to change (unless we wanna deal with some annoyances)
|
int getTargetFramebuffer(); // Note: Iris is now hooking onto this for DH + Iris compat, try not to change (unless we wanna deal with some annoyances)
|
||||||
// Iris commit: https://github.com/IrisShaders/Iris/commit/a76a240527e93780bbcba57c09bef377419d47a7#diff-7b9ded0c79bbcdb130010373387756a28ee8d3640d522c0a5b7acd0abbfc20aeR16
|
// Iris commit: https://github.com/IrisShaders/Iris/commit/a76a240527e93780bbcba57c09bef377419d47a7#diff-7b9ded0c79bbcdb130010373387756a28ee8d3640d522c0a5b7acd0abbfc20aeR16
|
||||||
|
/** @return -1 if there was an issue or no texture exists */
|
||||||
int getDepthTextureId();
|
int getDepthTextureId();
|
||||||
|
/** @return -1 if there was an issue or no texture exists */
|
||||||
int getColorTextureId();
|
int getColorTextureId();
|
||||||
int getTargetFramebufferViewportWidth();
|
int getTargetFramebufferViewportWidth();
|
||||||
int getTargetFramebufferViewportHeight();
|
int getTargetFramebufferViewportHeight();
|
||||||
|
|||||||
@@ -84,7 +84,13 @@
|
|||||||
"Show The Options Button",
|
"Show The Options Button",
|
||||||
"distanthorizons.config.client.optionsButton.@tooltip":
|
"distanthorizons.config.client.optionsButton.@tooltip":
|
||||||
"Show the config button to the left of the fov button",
|
"Show the config button to the left of the fov button",
|
||||||
|
|
||||||
|
"distanthorizons.config.client.dynamicFadeUseOpaqueMcDepth":
|
||||||
|
"Dynamic Fade Use MC Opaque Depth",
|
||||||
|
"distanthorizons.config.client.dynamicFadeExportPath":
|
||||||
|
"Dynamic Fade Export Path",
|
||||||
|
"distanthorizons.config.client.dynamicFadeExportPath.@tooltip":
|
||||||
|
"Press 'p' to export the depth textures for troubleshooting",
|
||||||
|
|
||||||
|
|
||||||
"distanthorizons.config.client.advanced":
|
"distanthorizons.config.client.advanced":
|
||||||
@@ -227,6 +233,10 @@
|
|||||||
"Beacon render height",
|
"Beacon render height",
|
||||||
"distanthorizons.config.client.advanced.graphics.genericRendering.beaconRenderHeight.@tooltip":
|
"distanthorizons.config.client.advanced.graphics.genericRendering.beaconRenderHeight.@tooltip":
|
||||||
"Sets the maximum height at which beacons will render. \nThis will only affect new beacons coming into LOD render distance. \nBeacons currently visible in LOD chunks will not be affected.",
|
"Sets the maximum height at which beacons will render. \nThis will only affect new beacons coming into LOD render distance. \nBeacons currently visible in LOD chunks will not be affected.",
|
||||||
|
"distanthorizons.config.client.advanced.graphics.genericRendering.expandDistantBeacons":
|
||||||
|
"Expand Distant Beacons",
|
||||||
|
"distanthorizons.config.client.advanced.graphics.genericRendering.expandDistantBeacons.@tooltip":
|
||||||
|
"If true LOD beacon beams will be rendered wider at extreme distances, \nmaking them easier to see. \nIf false all LOD beacon beams will only ever be 1 block wide.",
|
||||||
"distanthorizons.config.client.advanced.graphics.genericRendering.enableBeaconRendering.@tooltip":
|
"distanthorizons.config.client.advanced.graphics.genericRendering.enableBeaconRendering.@tooltip":
|
||||||
"If true LOD beacon beams will be rendered.",
|
"If true LOD beacon beams will be rendered.",
|
||||||
"distanthorizons.config.client.advanced.graphics.genericRendering.enableCloudRendering":
|
"distanthorizons.config.client.advanced.graphics.genericRendering.enableCloudRendering":
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
Reference in New Issue
Block a user