Merge for SubDim

This commit is contained in:
James Seibel
2022-03-26 11:39:17 -05:00
35 changed files with 664 additions and 258 deletions
@@ -20,7 +20,7 @@
package com.seibel.lod.core.api;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.objects.lod.LodWorld;
import org.apache.logging.log4j.LogManager;
@@ -49,12 +49,10 @@ public class ApiShared
/** Signal whether a world is shutting down */
public static volatile boolean isShuttingDown = false;
private ApiShared()
{
}
}
@@ -19,19 +19,18 @@
package com.seibel.lod.core.api;
import java.lang.ref.WeakReference;
import java.time.Duration;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.logging.ConfigBasedSpamLogger;
import org.apache.logging.log4j.Level;
import com.seibel.lod.core.handlers.LodDimensionFinder;
import org.lwjgl.glfw.GLFW;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.objects.opengl.builders.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.lod.LodDimension;
@@ -39,7 +38,7 @@ import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.render.GLProxy;
import com.seibel.lod.core.render.LodRenderer;
import com.seibel.lod.core.util.DetailDistanceUtil;
import com.seibel.lod.core.util.SpamReducedLogger;
import com.seibel.lod.core.logging.SpamReducedLogger;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
@@ -59,8 +58,6 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
public class ClientApi
{
public static boolean prefLoggerEnabled = false;
public static final List<WeakReference<SpamReducedLogger>> spamReducedLoggers
= Collections.synchronizedList(new LinkedList<WeakReference<SpamReducedLogger>>());
public static final ClientApi INSTANCE = new ClientApi();
@@ -101,7 +98,7 @@ public class ClientApi
private boolean configOverrideReminderPrinted = false;
public boolean rendererDisabledBecauseOfExceptions = false;
@@ -112,18 +109,26 @@ public class ClientApi
{
}
private void flushSpamLoggersState() {
synchronized(spamReducedLoggers) {
spamReducedLoggers.removeIf((logger) -> logger.get()==null);
spamReducedLoggers.forEach((logger) -> {
SpamReducedLogger l = logger.get();
if (l!=null) l.reset();
});
public static void logToChat(Level logLevel, String str) {
String prefix = "["+ModInfo.READABLE_NAME+"] ";
if (logLevel == Level.ERROR) {
prefix += "\u00A74";
} else if (logLevel == Level.WARN) {
prefix += "\u00A76";
} else if (logLevel == Level.INFO) {
prefix += "\u00A7f";
} else if (logLevel == Level.DEBUG) {
prefix += "\u00A77";
} else if (logLevel == Level.TRACE) {
prefix += "\u00A78";
} else {
prefix += "\u00A7f";
}
prefix += "\u00A7l\u00A7u";
prefix += logLevel.name();
prefix += ":\u00A7r ";
if (MC != null) MC.sendChatMessage(prefix + str);
}
private final ConcurrentHashMap.KeySetView<Long,Boolean> generating = ConcurrentHashMap.newKeySet();
@@ -149,10 +154,13 @@ public class ClientApi
try
{
if (System.nanoTime() - lastFlush >= SPAM_LOGGER_FLUSH_NS) {
boolean doFlush = System.nanoTime() - lastFlush >= SPAM_LOGGER_FLUSH_NS;
if (doFlush) {
lastFlush = System.nanoTime();
flushSpamLoggersState();
SpamReducedLogger.flushAll();
}
ConfigBasedLogger.updateAll();
ConfigBasedSpamLogger.updateAll(doFlush);
if (ApiShared.previousVertQual != CONFIG.client().graphics().quality().getVerticalQuality()) {
ApiShared.previousVertQual = CONFIG.client().graphics().quality().getVerticalQuality();
@@ -20,8 +20,8 @@
package com.seibel.lod.core.api;
import com.seibel.lod.core.api.ClientApi.LagSpikeCatcher;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.opengl.builders.worldGeneration.BatchGenerator;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.worldGeneration.BatchGenerator;
import com.seibel.lod.core.enums.WorldType;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.lod.LodDimension;
@@ -17,16 +17,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.objects.opengl.builders.lodBuilding;
package com.seibel.lod.core.builders.lodBuilding;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.config.BlocksToAvoid;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.LodRegion;
import com.seibel.lod.core.objects.lod.LodWorld;
@@ -56,7 +56,9 @@ public class LodBuilder
{
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class);
private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final ConfigBasedLogger EVENT_LOGGER = new ConfigBasedLogger(() -> config.client().advanced().debugging().debugSwitch().getLogLodBuilderEvent());
/** This cannot be final! Different world have different height, and in menu, this causes Null Exceptions*/
//public static final short MIN_WORLD_HEIGHT = MC.getWrappedClientWorld().getMinHeight();
@@ -68,7 +70,6 @@ public class LodBuilder
private final ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(
new LodThreadFactory(this.getClass().getSimpleName(), Thread.NORM_PRIORITY-1));
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
@@ -134,7 +135,7 @@ public class LodBuilder
}
catch (RuntimeException e)
{
ApiShared.LOGGER.error("LodBuilder Thread Uncaught Exception: ", e);
EVENT_LOGGER.error("LodBuilder Thread Uncaught Exception: ", e);
// if the world changes while LODs are being generated
// they will throw errors as they try to access things that no longer
// exist.
@@ -199,7 +200,7 @@ public class LodBuilder
return writePartialLodNodeData(lodDim, region, chunk.getChunkPosX(), chunk.getChunkPosZ(), data, config, override);
}
} catch (RuntimeException e) {
ApiShared.LOGGER.error("LodBuilder encountered an error on building lod: ", e);
EVENT_LOGGER.error("LodBuilder encountered an error on building lod: ", e);
return false;
}
}
@@ -216,7 +217,7 @@ public class LodBuilder
try {
if (region.getMinDetailLevel()!= 0) {
if (!LodUtil.checkRamUsage(0.05, 16)) {
ApiShared.LOGGER.debug("LodBuilder: Not enough RAM avalible for loading files to build lods! Returning...");
EVENT_LOGGER.debug("LodBuilder: Not enough RAM avalible for loading files to build lods! Returning...");
return false;
}
@@ -271,7 +272,7 @@ public class LodBuilder
for (int i=0; i<data.length; i+=vertQual) {
if (!DataPointUtil.doesItExist(data[i]) ||
DataPointUtil.getGenerationMode(data[i]) != config.distanceGenerationMode.complexity) {
ApiShared.LOGGER.error("NULL data at {}, detail {}, vertQual {}, lodCount {}, chunkPos [{},{}]\n"
EVENT_LOGGER.error("NULL data at {}, detail {}, vertQual {}, lodCount {}, chunkPos [{},{}]\n"
+ "Data: {}",
i, targetLevel, vertQual, lodCount, chunkX, chunkZ, DataPointUtil.toString(data[i]));
throw new RuntimeException("Null data!");
@@ -296,7 +297,7 @@ public class LodBuilder
config.distanceGenerationMode))
throw new RuntimeException("data at detail "+ targetLevel+" is still null after writes to it!");
} catch (Exception e) {
ApiShared.LOGGER.error("LodBuilder encountered an error on writePartialLodNodeData: ", e);
EVENT_LOGGER.error("LodBuilder encountered an error on writePartialLodNodeData: ", e);
} finally {
region.isWriting.decrementAndGet();
}
@@ -325,7 +326,7 @@ public class LodBuilder
boolean topBlock = true;
if (y < chunk.getMinBuildHeight())
dataToMerge[0] = DataPointUtil.createVoidDataPoint(generation);
int maxConnectedLods = this.config.client().graphics().quality().getVerticalQuality().maxVerticalData[0];
int maxConnectedLods = LodBuilder.config.client().graphics().quality().getVerticalQuality().maxVerticalData[0];
while (y >= chunk.getMinBuildHeight()) {
int height = determineHeightPointFrom(chunk, config, x, y, z);
// If the lod is at the default height, it must be void data
@@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.objects.opengl.builders.lodBuilding;
package com.seibel.lod.core.builders.lodBuilding;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
@@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.objects.opengl.builders.bufferBuilding;
package com.seibel.lod.core.builders.lodBuilding.bufferBuilding;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.rendering.DebugMode;
@@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.objects.opengl.builders.bufferBuilding;
package com.seibel.lod.core.builders.lodBuilding.bufferBuilding;
import java.time.Duration;
import java.util.concurrent.*;
@@ -25,6 +25,7 @@ import java.util.concurrent.locks.ReentrantLock;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.SpamReducedLogger;
import com.seibel.lod.core.objects.Pos2D;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.RegionPos;
@@ -17,10 +17,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.objects.opengl.builders.worldGeneration;
package com.seibel.lod.core.builders.worldGeneration;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
@@ -0,0 +1,25 @@
package com.seibel.lod.core.enums.config;
import org.apache.logging.log4j.Level;
public enum LoggerMode {
DISABLED(Level.OFF, Level.OFF),
LOG_ALL_TO_FILE(Level.ALL, Level.OFF),
LOG_ERROR_TO_CHAT(Level.ALL, Level.ERROR),
LOG_WARNING_TO_CHAT(Level.ALL, Level.WARN),
LOG_INFO_TO_CHAT(Level.ALL, Level.INFO),
LOG_DEBUG_TO_CHAT(Level.ALL, Level.DEBUG),
LOG_ALL_TO_CHAT(Level.ALL, Level.ALL),
LOG_ERROR_TO_CHAT_AND_FILE(Level.ERROR, Level.ERROR),
LOG_WARNING_TO_CHAT_AND_FILE(Level.WARN, Level.WARN),
LOG_INFO_TO_CHAT_AND_FILE(Level.INFO, Level.INFO),
LOG_DEBUG_TO_CHAT_AND_FILE(Level.DEBUG, Level.DEBUG),
LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE(Level.INFO, Level.WARN),
LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE(Level.INFO, Level.ERROR),
;
public final Level levelForFile;
public final Level levelForChat;
LoggerMode(Level levelForFile, Level levelForChat) {
this.levelForFile = levelForFile;
this.levelForChat = levelForChat;
}
}
@@ -64,6 +64,8 @@ public enum VerticalQuality
{
switch (mode)
{
case ULTRA:
return VerticalQuality.HIGH;
case HIGH:
return VerticalQuality.MEDIUM;
case MEDIUM:
@@ -84,6 +86,8 @@ public enum VerticalQuality
case LOW:
return VerticalQuality.MEDIUM;
case HIGH:
return VerticalQuality.ULTRA;
case ULTRA:
default:
return null;
}
@@ -22,6 +22,7 @@ package com.seibel.lod.core.handlers;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.Signature;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
@@ -33,6 +34,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.api.ClientApi;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
@@ -46,10 +50,8 @@ import com.seibel.lod.core.objects.lod.RegionPos;
import com.seibel.lod.core.objects.lod.VerticalLevelContainer;
import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.SpamReducedLogger;
import com.seibel.lod.core.logging.SpamReducedLogger;
import com.seibel.lod.core.util.UnitBytes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
@@ -63,7 +65,8 @@ import org.apache.logging.log4j.Logger;
*/
public class LodDimensionFileHandler
{
public static final Logger LOGGER = LogManager.getLogger("LodDimensionFileHandler");
private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(() -> config.client().advanced().debugging().debugSwitch().getLogFileReadWriteEvent());
public static final boolean ENABLE_SAVE_THREAD_LOGGING = true;
public static final boolean ENABLE_SAVE_REGION_LOGGING = false;
@@ -242,7 +245,7 @@ public class LodDimensionFileHandler
// close the reader and delete the file.
inputStream.close();
file.delete();
LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ")"
LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ")[" + tempDetailLevel + "]"
+ " version found: " + fileVersion
+ ", version requested: " + LOD_SAVE_FILE_VERSION
+ ". File has been deleted.");
@@ -255,7 +258,7 @@ public class LodDimensionFileHandler
// close the reader and ignore the file, we don't
// want to accidentally delete anything the user may want.
inputStream.close();
LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ")"
LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ")[" + tempDetailLevel + "]"
+ " version found: " + fileVersion
+ ", version requested: " + LOD_SAVE_FILE_VERSION
+ " this region will not be written to in order to protect the newer file.");
@@ -264,7 +267,7 @@ public class LodDimensionFileHandler
}
else if (fileVersion < LOD_SAVE_FILE_VERSION)
{
LOGGER.debug("Old LOD region file for region: (" + regionX + "," + regionZ + ")"
LOGGER.info("Old LOD region file for region: (" + regionX + "," + regionZ + ")[" + tempDetailLevel + "]"
+ " version found: " + fileVersion
+ ", version requested: " + LOD_SAVE_FILE_VERSION
+ ". File will be loaded and updated to new format in next save.");
@@ -277,6 +280,7 @@ public class LodDimensionFileHandler
}
else
{
LOGGER.debug("Loading LOD region file for region: (" + regionX + "," + regionZ + ")[" + tempDetailLevel + "]");
// this file is a readable version,
// read and add the data to our region
DataInputStream dataStream = new DataInputStream(inputStream);
@@ -371,7 +375,7 @@ public class LodDimensionFileHandler
LevelContainer[] container = r.debugGetDataContainers().clone();
if (container == null || container.length != LodUtil.DETAIL_OPTIONS)
{
LOGGER.warn("DumpRamUsage encountered an invalid region!");
LOGGER.error("DumpRamUsage encountered an invalid region!");
continue;
}
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++)
@@ -1,21 +1,25 @@
package com.seibel.lod.core.handlers;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.handlers.dimensionFinder.PlayerData;
import com.seibel.lod.core.handlers.dimensionFinder.SubDimCompare;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilderConfig;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.LodRegion;
import com.seibel.lod.core.objects.lod.RegionPos;
import com.seibel.lod.core.util.DataPointUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
@@ -33,7 +37,9 @@ import java.util.UUID;
public class LodDimensionFinder
{
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class);
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(() -> CONFIG.client().advanced().debugging().debugSwitch().getLogFileSubDimEvent());
/** Increasing this will increase accuracy but increase calculation time */
private static final VerticalQuality VERTICAL_QUALITY_TO_TEST_WITH = VerticalQuality.LOW;
@@ -149,14 +155,15 @@ public class LodDimensionFinder
newlyLoadedDim.regions.set(playerRegionPos.x, playerRegionPos.z, new LodRegion(LodUtil.BLOCK_DETAIL_LEVEL, playerRegionPos, VERTICAL_QUALITY_TO_TEST_WITH));
// generate a LOD to test against
LOGGER.debug("Generating LOD for testing...");
boolean lodGenerated = ApiShared.lodBuilder.generateLodNodeFromChunk(newlyLoadedDim, newlyLoadedChunk, new LodBuilderConfig(DistanceGenerationMode.FULL), true, true);
if (!lodGenerated)
return null;
// log the start of this attempt
ApiShared.LOGGER.info("Attempting to determine sub-dimension for [" + MC.getCurrentDimension().getDimensionName() + "]");
ApiShared.LOGGER.info("First seen player block pos in dimension: [" + firstSeenPlayerData.playerBlockPos.getX() + "," + firstSeenPlayerData.playerBlockPos.getY() + "," + firstSeenPlayerData.playerBlockPos.getZ() + "]");
LOGGER.info("Attempting to determine sub-dimension for [" + MC.getCurrentDimension().getDimensionName() + "]");
LOGGER.info("First seen player block pos in dimension: [" + firstSeenPlayerData.playerBlockPos.getX() + "," + firstSeenPlayerData.playerBlockPos.getY() + "," + firstSeenPlayerData.playerBlockPos.getZ() + "]");
// new chunk data
@@ -169,7 +176,7 @@ public class LodDimensionFinder
newChunkData[x][z] = array;
}
}
boolean newChunkHasData = isDataEmpty(newChunkData);
boolean newChunkHasData = !isDataEmpty(newChunkData);
// check if the chunk is actually empty
if (!newChunkHasData)
@@ -179,16 +186,14 @@ public class LodDimensionFinder
// the chunk isn't empty but the LOD is...
String message = "Error: the chunk at (" + playerChunkPos.getX() + "," + playerChunkPos.getZ() + ") has a height of [" + newlyLoadedChunk.getHeight() + "] but the LOD generated is empty!";
MC.sendChatMessage(message);
ApiShared.LOGGER.error(message);
return null;
LOGGER.error(message);
}
else
{
String message = "Warning: The chunk at (" + playerChunkPos.getX() + "," + playerChunkPos.getZ() + ") is empty.";
// MC.sendChatMessage(message);
ApiShared.LOGGER.warn(message);
LOGGER.warn(message);
}
return null;
}
@@ -212,11 +217,11 @@ public class LodDimensionFinder
// compare each world with the newly loaded one
SubDimCompare mostSimilarSubDim = null;
ApiShared.LOGGER.info("Known Sub Dimensions: [" + dimensionFolder.listFiles().length + "]");
LOGGER.info("Known Sub Dimensions: [" + dimensionFolder.listFiles().length + "]");
for (File testDimFolder : dimensionFolder.listFiles())
{
ApiShared.LOGGER.info("Testing sub dimension: [" + LodUtil.shortenString(testDimFolder.getName(), 8) + "]");
LOGGER.info("Testing sub dimension: [" + LodUtil.shortenString(testDimFolder.getName(), 8) + "]");
// get a LOD from this dimension folder
LodDimension tempLodDim = new LodDimension(null, 1, null, false);
@@ -237,7 +242,7 @@ public class LodDimensionFinder
// get the player data for this dimension folder
PlayerData testPlayerData = new PlayerData(testDimFolder);
ApiShared.LOGGER.info("Last known player pos: [" + testPlayerData.playerBlockPos.getX() + "," + testPlayerData.playerBlockPos.getY() + "," + testPlayerData.playerBlockPos.getZ() + "]");
LOGGER.info("Last known player pos: [" + testPlayerData.playerBlockPos.getX() + "," + testPlayerData.playerBlockPos.getY() + "," + testPlayerData.playerBlockPos.getZ() + "]");
// check if the block positions are close
int playerBlockDist = testPlayerData.playerBlockPos.getManhattanDistance(firstSeenPlayerData.playerBlockPos);
@@ -245,11 +250,10 @@ public class LodDimensionFinder
// check if the chunk is actually empty
if (!isDataEmpty(newChunkData))
if (isDataEmpty(testChunkData))
{
String message = "The test chunk for dimension folder [" + LodUtil.shortenString(testDimFolder.getName(), 8) + "] and chunk pos (" + playerChunkPos.getX() + "," + playerChunkPos.getZ() + ") is empty. Is that correct?";
// MC.sendChatMessage(message);
ApiShared.LOGGER.info(message);
LOGGER.info(message);
continue;
}
@@ -268,6 +272,9 @@ public class LodDimensionFinder
equalDataPoints++;
}
totalDataPointCount++;
if (!DataPointUtil.doesItExist(newChunkData[x][z][y]) || !DataPointUtil.doesItExist(testChunkData[x][z][y]))
break;
}
}
}
@@ -281,8 +288,7 @@ public class LodDimensionFinder
}
String message = "Sub dimension [" + LodUtil.shortenString(testDimFolder.getName(), 8) + "...] is current dimension probability: " + LodUtil.shortenString(subDimCompare.getPercentEqual() + "", 5) + " (" + equalDataPoints + "/" + totalDataPointCount + ")";
MC.sendChatMessage(message);
ApiShared.LOGGER.info(message);
LOGGER.info(message);
}
// the first seen player data is no longer needed, the sub dimension has been determined
@@ -294,8 +300,7 @@ public class LodDimensionFinder
// we found a world folder that is similar, use it
String message = "Sub Dimension set to: [" + LodUtil.shortenString(mostSimilarSubDim.folder.getName(), 8) + "...] with an equality of [" + mostSimilarSubDim.getPercentEqual() + "]";
MC.sendChatMessage(message);
ApiShared.LOGGER.info(message);
LOGGER.info(message);
return mostSimilarSubDim.folder;
}
else
@@ -306,8 +311,7 @@ public class LodDimensionFinder
String newId = UUID.randomUUID().toString();
String message = "No suitable sub dimension found. The highest equality was [" + LodUtil.shortenString(highestEqualityPercent + "", 5) + "]. Creating a new sub dimension with ID: " + LodUtil.shortenString(newId, 8) + "...";
MC.sendChatMessage(message);
ApiShared.LOGGER.info(message);
LOGGER.info(message);
return GetDimensionFolder(newlyLoadedDim.dimension, newId);
}
}
@@ -340,7 +344,7 @@ public class LodDimensionFinder
}
catch (IOException e)
{
ApiShared.LOGGER.error("Unable to get dimension folder for dimension [" + newDimensionType.getDimensionName() + "]", e);
LOGGER.error("Unable to get dimension folder for dimension [" + newDimensionType.getDimensionName() + "]", e);
return null;
}
}
@@ -365,13 +369,13 @@ public class LodDimensionFinder
{
if (dataPoint != 0)
{
return true;
return false;
}
}
}
}
return false;
return true;
}
@@ -401,7 +405,7 @@ public class LodDimensionFinder
}
catch (IOException e)
{
ApiShared.LOGGER.error("Unable to save player dimension data for world folder [" + worldFolder.getPath() + "].", e);
LOGGER.error("Unable to save player dimension data for world folder [" + worldFolder.getPath() + "].", e);
return;
}
}
@@ -0,0 +1,70 @@
package com.seibel.lod.core.logging;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.config.LoggerMode;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.message.Message;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Supplier;
public class ConfigBasedLogger {
public static final List<WeakReference<ConfigBasedLogger>> loggers
= Collections.synchronizedList(new LinkedList<WeakReference<ConfigBasedLogger>>());
public static synchronized void updateAll() {
loggers.removeIf((logger) -> logger.get()==null);
loggers.forEach((logger) -> {
ConfigBasedLogger l = logger.get();
if (l!=null) l.update();
});
}
LoggerMode mode;
final Supplier<LoggerMode> getter;
public ConfigBasedLogger(Supplier<LoggerMode> configQuery) {
getter = configQuery;
mode = getter.get();
loggers.add(new WeakReference<>(this));
}
public void update() {
mode = getter.get();
}
public boolean canMaybeLog() {return mode != LoggerMode.DISABLED;}
public void log(Level level, String str, Object... param) {
Message msg = ApiShared.LOGGER.getMessageFactory().newMessage(str, param);
String msgStr = msg.getFormattedMessage();
if (mode.levelForFile.isLessSpecificThan(level)) {
Level logLevel = level.isLessSpecificThan(Level.INFO) ? Level.INFO : level;
if (param.length > 0 && param[param.length-1] instanceof Throwable)
ApiShared.LOGGER.atLevel(logLevel).withLocation().withThrowable((Throwable)param[param.length-1]).log(msgStr);
else ApiShared.LOGGER.atLevel(logLevel).withLocation().log(msgStr);
}
if (mode.levelForChat.isLessSpecificThan(level)) {
if (param.length > 0 && param[param.length-1] instanceof Throwable)
ClientApi.logToChat(level, msgStr + "\nat\n" + ((Throwable) param[param.length-1]).getStackTrace().toString());
ClientApi.logToChat(level, msgStr);
}
}
public void error(String str, Object... param) {
log(Level.ERROR, str, param);
}
public void warn(String str, Object... param) {
log(Level.WARN, str, param);
}
public void info(String str, Object... param) {
log(Level.INFO, str, param);
}
public void debug(String str, Object... param) {
log(Level.DEBUG, str, param);
}
public void trace(String str, Object... param) {
log(Level.TRACE, str, param);
}
}
@@ -0,0 +1,115 @@
package com.seibel.lod.core.logging;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.config.LoggerMode;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.message.Message;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
public class ConfigBasedSpamLogger {
public static final List<WeakReference<ConfigBasedSpamLogger>> loggers
= Collections.synchronizedList(new LinkedList<WeakReference<ConfigBasedSpamLogger>>());
public static synchronized void updateAll(boolean flush) {
loggers.removeIf((logger) -> logger.get()==null);
loggers.forEach((logger) -> {
ConfigBasedSpamLogger l = logger.get();
if (l!=null) l.update();
if (l!=null && flush) l.reset();
});
}
LoggerMode mode;
final Supplier<LoggerMode> getter;
private final int maxLogCount;
private final AtomicInteger logTries = new AtomicInteger(0);
public ConfigBasedSpamLogger(Supplier<LoggerMode> configQuery, int maxLogPerSec) {
getter = configQuery;
mode = getter.get();
maxLogCount = maxLogPerSec;
loggers.add(new WeakReference<>(this));
}
public void reset() {logTries.set(0);}
public boolean canMaybeLog() {return mode != LoggerMode.DISABLED && logTries.get() < maxLogCount;}
public void update() {
mode = getter.get();
}
public void log(Level level, String str, Object... param) {
if (logTries.get() >= maxLogCount) return;
Message msg = ApiShared.LOGGER.getMessageFactory().newMessage(str, param);
String msgStr = msg.getFormattedMessage();
if (mode.levelForFile.isLessSpecificThan(level)) {
Level logLevel = level.isLessSpecificThan(Level.INFO) ? Level.INFO : level;
if (param.length > 0 && param[param.length-1] instanceof Throwable)
ApiShared.LOGGER.atLevel(logLevel).withLocation().withThrowable((Throwable)param[param.length-1]).log(msgStr);
else ApiShared.LOGGER.atLevel(logLevel).withLocation().log(msgStr);
}
if (mode.levelForChat.isLessSpecificThan(level)) {
if (param.length > 0 && param[param.length-1] instanceof Throwable)
ClientApi.logToChat(level, msgStr + "\nat\n" + ((Throwable) param[param.length-1]).getStackTrace().toString());
ClientApi.logToChat(level, msgStr);
}
}
public void error(String str, Object... param) {
log(Level.ERROR, str, param);
}
public void warn(String str, Object... param) {
log(Level.WARN, str, param);
}
public void info(String str, Object... param) {
log(Level.INFO, str, param);
}
public void debug(String str, Object... param) {
log(Level.DEBUG, str, param);
}
public void trace(String str, Object... param) {
log(Level.TRACE, str, param);
}
public void incLogTries() {
logTries.getAndIncrement();
}
public void logInc(Level level, String str, Object... param) {
if (logTries.getAndIncrement() >= maxLogCount) return;
Message msg = ApiShared.LOGGER.getMessageFactory().newMessage(str, param);
String msgStr = msg.getFormattedMessage();
if (mode.levelForFile.isLessSpecificThan(level)) {
Level logLevel = level.isLessSpecificThan(Level.INFO) ? Level.INFO : level;
if (param.length > 0 && param[param.length-1] instanceof Throwable)
ApiShared.LOGGER.atLevel(logLevel).withLocation().withThrowable((Throwable)param[param.length-1]).log(msgStr);
else ApiShared.LOGGER.atLevel(logLevel).withLocation().log(msgStr);
}
if (mode.levelForChat.isLessSpecificThan(level)) {
if (param.length > 0 && param[param.length-1] instanceof Throwable)
ClientApi.logToChat(level, msgStr + "\nat\n" + Arrays.toString(((Throwable) param[param.length - 1]).getStackTrace()));
ClientApi.logToChat(level, msgStr);
}
}
public void errorInc(String str, Object... param) {
logInc(Level.ERROR, str, param);
}
public void warnInc(String str, Object... param) {
logInc(Level.WARN, str, param);
}
public void infoInc(String str, Object... param) {
logInc(Level.INFO, str, param);
}
public void debugInc(String str, Object... param) {
logInc(Level.DEBUG, str, param);
}
public void traceInc(String str, Object... param) {
logInc(Level.TRACE, str, param);
}
}
@@ -0,0 +1,78 @@
package com.seibel.lod.core.logging;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.seibel.lod.core.api.ApiShared;
import org.apache.logging.log4j.Level;
public class SpamReducedLogger {
public static final List<WeakReference<SpamReducedLogger>> loggers
= Collections.synchronizedList(new LinkedList<WeakReference<SpamReducedLogger>>());
public static synchronized void flushAll() {
loggers.removeIf((logger) -> logger.get()==null);
loggers.forEach((logger) -> {
SpamReducedLogger l = logger.get();
if (l!=null) l.reset();
});
}
private final int maxLogCount;
private final AtomicInteger logTries = new AtomicInteger(0);
public SpamReducedLogger(int maxLogPerSec) {
maxLogCount = maxLogPerSec;
loggers.add(new WeakReference<SpamReducedLogger>(this));
}
public void reset() {logTries.set(0);}
public boolean canMaybeLog() {return logTries.get() < maxLogCount;}
public void log(Level level, String str, Object... param) {
if (logTries.get() >= maxLogCount) return;
ApiShared.LOGGER.log(level.isLessSpecificThan(Level.INFO) ? Level.INFO : level, str, param);
}
public void error(String str, Object... param) {
log(Level.ERROR, str, param);
}
public void warn(String str, Object... param) {
log(Level.WARN, str, param);
}
public void info(String str, Object... param) {
log(Level.INFO, str, param);
}
public void debug(String str, Object... param) {
log(Level.DEBUG, str, param);
}
public void trace(String str, Object... param) {
log(Level.TRACE, str, param);
}
public void incLogTries() {
logTries.getAndIncrement();
}
public void logInc(Level level, String str, Object... param) {
if (logTries.getAndIncrement() >= maxLogCount) return;
ApiShared.LOGGER.log(level.isLessSpecificThan(Level.INFO) ? Level.INFO : level, str, param);
}
public void errorInc(String str, Object... param) {
logInc(Level.ERROR, str, param);
}
public void warnInc(String str, Object... param) {
logInc(Level.WARN, str, param);
}
public void infoInc(String str, Object... param) {
logInc(Level.INFO, str, param);
}
public void debugInc(String str, Object... param) {
logInc(Level.DEBUG, str, param);
}
public void traceInc(String str, Object... param) {
logInc(Level.TRACE, str, param);
}
}
@@ -27,6 +27,7 @@ import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.handlers.LodDimensionFileHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.SpamReducedLogger;
import com.seibel.lod.core.objects.Pos2D;
import com.seibel.lod.core.objects.PosToGenerateContainer;
import com.seibel.lod.core.util.*;
@@ -6,8 +6,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.LodDirection.Axis;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
@@ -16,6 +15,8 @@ import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER;
public class LodQuadBuilder {
static final int MAX_BUFFER_SIZE = (1024 * 1024 * 1);
static final int QUAD_BYTE_SIZE = (12 * 6);
@@ -108,7 +109,7 @@ public class LodQuadBuilder {
return false;
if (z + w0 > o.z)
{
ApiShared.LOGGER.warn("Overlapping quads detected!");
EVENT_LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
@@ -127,7 +128,7 @@ public class LodQuadBuilder {
return false;
if (x + w0 > o.x)
{
ApiShared.LOGGER.warn("Overlapping quads detected!");
EVENT_LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
@@ -146,7 +147,7 @@ public class LodQuadBuilder {
return false;
if (x + w0 > o.x)
{
ApiShared.LOGGER.warn("Overlapping quads detected!");
EVENT_LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
@@ -177,7 +178,7 @@ public class LodQuadBuilder {
return false;
if (y + w1 > o.y)
{
ApiShared.LOGGER.warn("Overlapping quads detected!");
EVENT_LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
@@ -195,7 +196,7 @@ public class LodQuadBuilder {
return false;
if (z + w1 > o.z)
{
ApiShared.LOGGER.warn("Overlapping quads detected!");
EVENT_LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
@@ -213,7 +214,7 @@ public class LodQuadBuilder {
return false;
if (y + w1 > o.y)
{
ApiShared.LOGGER.warn("Overlapping quads detected!");
EVENT_LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
@@ -392,7 +393,7 @@ public class LodQuadBuilder {
}
long postQuadsCount = getCurrentQuadsCount();
//if (mergeCount != 0)
// ApiShared.LOGGER.info("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount/(double)preQuadsCount);
EVENT_LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount/(double)preQuadsCount);
}
public Iterator<ByteBuffer> makeVertexBuffers() {
@@ -25,7 +25,6 @@ import com.seibel.lod.core.api.ApiShared;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GL44;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.enums.rendering.GLProxyContext;
import com.seibel.lod.core.render.GLProxy;
@@ -78,10 +77,12 @@ public class LodVertexBuffer implements AutoCloseable
private void _uploadBufferStorage(ByteBuffer bb) {
if (!isBufferStorage) throw new IllegalStateException("Buffer is not bufferStorage but its trying to use bufferStorage upload method!");
int bbSize = bb.limit() - bb.position();
GL32.glDeleteBuffers(id);
id = GL32.glGenBuffers();
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, id);
GL44.glBufferStorage(GL32.GL_ARRAY_BUFFER, bb, 0);
size = bbSize;
}
// bufferData
@@ -7,10 +7,9 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.objects.opengl.builders.bufferBuilding.CubicLodTemplate;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.CubicLodTemplate;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.enums.rendering.DebugMode;
@@ -34,11 +33,10 @@ import com.seibel.lod.core.util.gridList.PosArrayGridList;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER;
public class RenderRegion implements AutoCloseable
{
public static final boolean ENABLE_EVENT_LOGGING = false;
public static final boolean ENABLE_EVENT_STEP_LOGGING = false;
public static final boolean ENABLE_VERBOSE_LOGGING = false;
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/** stores if the region at the given x and z index needs to be regenerated */
@@ -83,22 +81,22 @@ public class RenderRegion implements AutoCloseable
BackState state = backState.get();
if (state != BackState.Unused) {
if (ENABLE_VERBOSE_LOGGING) ApiShared.LOGGER.info("{}: UpdateStatus rejected. Cause: BackState is {}", regionPos, state);
EVENT_LOGGER.trace("{}: UpdateStatus rejected. Cause: BackState is {}", regionPos, state);
return Optional.empty();
}
LodRegion r = lodDim.getRegion(regionPos.x, regionPos.z);
if (r==null) {
if (ENABLE_VERBOSE_LOGGING) ApiShared.LOGGER.info("{}: UpdateStatus rejected. Cause: Region is null", regionPos);
EVENT_LOGGER.trace("{}: UpdateStatus rejected. Cause: Region is null", regionPos);
return Optional.empty();
}
if (needRegen.get() == 0) {
if (ENABLE_VERBOSE_LOGGING) ApiShared.LOGGER.info("{}: UpdateStatus rejected. Cause: Region doesn't need regen", regionPos);
EVENT_LOGGER.trace("{}: UpdateStatus rejected. Cause: Region doesn't need regen", regionPos);
return Optional.empty();
}
if (!backState.compareAndSet(BackState.Unused, BackState.Building)) {
if (ENABLE_VERBOSE_LOGGING) ApiShared.LOGGER.info("{}: UpdateStatus rejected. Cause: CAS on BackState failed: ", backState.get());
EVENT_LOGGER.trace("{}: UpdateStatus rejected. Cause: CAS on BackState failed: ", backState.get());
return Optional.empty();
}
needRegen.decrementAndGet();
@@ -117,7 +115,7 @@ public class RenderRegion implements AutoCloseable
BackState state = backState.get();
if (state == BackState.Complete) {
if (renderBufferBack != null) {
if (ENABLE_EVENT_LOGGING) ApiShared.LOGGER.info("RenderRegion swap @ {}", regionPos);
EVENT_LOGGER.debug("RenderRegion swap @ {}", regionPos);
boolean shouldKeep = renderBufferFront != null && renderBufferFront.onSwapToBack();
RenderBuffer temp = shouldKeep ? renderBufferFront : null;
renderBufferFront = renderBufferBack;
@@ -125,7 +123,7 @@ public class RenderRegion implements AutoCloseable
if (renderBufferFront != null) renderBufferFront.onSwapToFront();
}
if (!backState.compareAndSet(BackState.Complete, BackState.Unused)) {
ApiShared.LOGGER.error("RenderRegion.render() got illegal state on swapping buffer!");
EVENT_LOGGER.error("RenderRegion.render() got illegal state on swapping buffer!");
}
}
if (renderBufferFront == null) return false;
@@ -150,7 +148,7 @@ public class RenderRegion implements AutoCloseable
}
private CompletableFuture<Void> startBuid(Executor bufferUploader, Executor bufferBuilder, LodRegion region, LodDimension lodDim, int playerPosX, int playerPosZ) {
if (ENABLE_EVENT_LOGGING) ApiShared.LOGGER.info("RenderRegion startBuild @ {}", regionPos);
EVENT_LOGGER.trace("RenderRegion startBuild @ {}", regionPos);
LodRegion[] adjRegions = new LodRegion[4];
try {
if (renderBufferBack != null) renderBufferBack.onReuse();
@@ -160,7 +158,7 @@ public class RenderRegion implements AutoCloseable
} catch (Throwable t) {
setNeedRegen();
if (!backState.compareAndSet(BackState.Building, BackState.Unused)) {
ApiShared.LOGGER.error("\"Lod Builder Starter\""
EVENT_LOGGER.error("\"Lod Builder Starter\""
+ " encountered error on catching exceptions and fallback on starting build task: ",
new ConcurrentModificationException("RenderRegion Illegal State"));
}
@@ -168,7 +166,7 @@ public class RenderRegion implements AutoCloseable
}
return CompletableFuture.supplyAsync(() -> {
try {
if (ENABLE_EVENT_STEP_LOGGING) ApiShared.LOGGER.info("RenderRegion start QuadBuild @ {}", regionPos);
EVENT_LOGGER.trace("RenderRegion start QuadBuild @ {}", regionPos);
boolean useSkylightCulling = CONFIG.client().graphics().advancedGraphics().getEnableCaveCulling();
useSkylightCulling &= !lodDim.dimension.hasCeiling();
useSkylightCulling &= lodDim.dimension.hasSkyLight();
@@ -183,17 +181,17 @@ public class RenderRegion implements AutoCloseable
renderBufferBack.build(buildRun);
else
buildRun.run();
if (ENABLE_EVENT_STEP_LOGGING) ApiShared.LOGGER.info("RenderRegion end QuadBuild @ {}", regionPos);
EVENT_LOGGER.trace("RenderRegion end QuadBuild @ {}", regionPos);
return builder;
} catch (Throwable e3) {
ApiShared.LOGGER.error("\"LodNodeBufferBuilder\" was unable to build quads: ", e3);
EVENT_LOGGER.error("\"LodNodeBufferBuilder\" was unable to build quads: ", e3);
throw e3;
}
}, bufferBuilder)
.thenAcceptAsync((builder) -> {
try {
if (ENABLE_EVENT_STEP_LOGGING) ApiShared.LOGGER.info("RenderRegion start Upload @ {}", regionPos);
EVENT_LOGGER.trace("RenderRegion start Upload @ {}", regionPos);
GLProxy glProxy = GLProxy.getInstance();
GpuUploadMethod method = GLProxy.getInstance().getGpuUploadMethod();
GLProxyContext oldContext = glProxy.getGlContext();
@@ -211,22 +209,22 @@ public class RenderRegion implements AutoCloseable
} finally {
glProxy.setGlContext(oldContext);
}
if (ENABLE_EVENT_STEP_LOGGING) ApiShared.LOGGER.info("RenderRegion end Upload @ {}", regionPos);
EVENT_LOGGER.trace("RenderRegion end Upload @ {}", regionPos);
} catch (Throwable e3) {
ApiShared.LOGGER.error("\"LodNodeBufferBuilder\" was unable to upload buffer: ", e3);
EVENT_LOGGER.error("\"LodNodeBufferBuilder\" was unable to upload buffer: ", e3);
throw e3;
}
}, bufferUploader).handle((v, e) -> {
if (e != null) {
setNeedRegen();
if (!backState.compareAndSet(BackState.Building, BackState.Unused)) {
ApiShared.LOGGER.error("\"LodNodeBufferBuilder\""
EVENT_LOGGER.error("\"LodNodeBufferBuilder\""
+ " encountered error on exit: ",
new ConcurrentModificationException("RenderRegion Illegal State"));
}
} else {
if (!backState.compareAndSet(BackState.Building, BackState.Complete)) {
ApiShared.LOGGER.error("\"LodNodeBufferBuilder\""
EVENT_LOGGER.error("\"LodNodeBufferBuilder\""
+ " encountered error on exit: ",
new ConcurrentModificationException("RenderRegion Illegal State"));
}
@@ -358,8 +356,8 @@ public class RenderRegion implements AutoCloseable
childZAdj + (lodDirection.getAxis()==LodDirection.Axis.Z ? 0 : 1));
}
} catch (RuntimeException e) {
ApiShared.LOGGER.warn("Failed to get adj data for [{}:{},{}] at [{}]", detailLevel, posX, posZ, lodDirection);
ApiShared.LOGGER.warn("Detail exception: ", e);
EVENT_LOGGER.warn("Failed to get adj data for [{}:{},{}] at [{}]", detailLevel, posX, posZ, lodDirection);
EVENT_LOGGER.warn("Detail exception: ", e);
}
}
@@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit;
import org.lwjgl.opengl.GL32;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.objects.opengl.builders.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.opengl.LodQuadBuilder.BufferFiller;
@@ -17,6 +17,8 @@ import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.StatsMap;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import static com.seibel.lod.core.render.GLProxy.GL_LOGGER;
public class SimpleRenderBuffer extends RenderBuffer
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
@@ -75,6 +77,7 @@ public class SimpleRenderBuffer extends RenderBuffer
if (b.size == FULL_SIZED_BUFFERS) {
statsMap.incStat("FullsizedVBOs");
}
if (b.size == 0) GL_LOGGER.warn("VBO with size 0");
statsMap.incBytesStat("TotalUsage", b.size);
}
}
@@ -25,7 +25,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
@@ -65,11 +65,13 @@ public class GLProxy
public static final boolean OVERWIDE_VANILLA_GL_LOGGER = true;
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
private ExecutorService workerThread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(GLProxy.class.getSimpleName() + "-Worker-Thread").build());
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final ConfigBasedLogger GL_LOGGER = new ConfigBasedLogger(() -> CONFIG.client().advanced().debugging().debugSwitch().getLogRendererGLEvent());
private static GLProxy instance = null;
/** Minecraft's GLFW window */
@@ -157,22 +159,22 @@ public class GLProxy
GLMessage.Severity s = msg.severity;
if (msg.type == GLMessage.Type.ERROR ||
msg.type == GLMessage.Type.UNDEFINED_BEHAVIOR) {
ApiShared.LOGGER.error("GL ERROR {} from {}: {}", msg.id, msg.source, msg.message);
GL_LOGGER.error("GL ERROR {} from {}: {}", msg.id, msg.source, msg.message);
throw new RuntimeException("GL ERROR: "+msg.toString());
}
RuntimeException e = new RuntimeException("GL MESSAGE: "+msg.toString());
switch (s) {
case HIGH:
ApiShared.LOGGER.error(e);
GL_LOGGER.error("{}", e);
break;
case MEDIUM:
ApiShared.LOGGER.warn(e);
GL_LOGGER.warn("{}", e);
break;
case LOW:
ApiShared.LOGGER.info(e);
GL_LOGGER.info("{}", e);
break;
case NOTIFICATION:
ApiShared.LOGGER.debug(e);
GL_LOGGER.debug("{}", e);
break;
}
@@ -228,10 +230,10 @@ public class GLProxy
// this must be created on minecraft's render context to work correctly
ApiShared.LOGGER.info("Creating " + GLProxy.class.getSimpleName() + "... If this is the last message you see in the log there must have been a OpenGL error.");
ApiShared.LOGGER.info("Lod Render OpenGL version [" + GL11.glGetString(GL11.GL_VERSION) + "].");
GL_LOGGER.info("Creating " + GLProxy.class.getSimpleName() + "... If this is the last message you see in the log there must have been a OpenGL error.");
GL_LOGGER.info("Lod Render OpenGL version [" + GL11.glGetString(GL11.GL_VERSION) + "].");
// getting Minecraft's context has to be done on the render thread,
// where the GL context is
@@ -258,12 +260,10 @@ public class GLProxy
"Additional info:\n"+supportedVersionInfo;
MC.crashMinecraft(errorMessage, new UnsupportedOperationException("This GPU doesn't support OpenGL 3.2."));
}
ApiShared.LOGGER.info("minecraftGlCapabilities:\n"+getVersionInfo(minecraftGlCapabilities));
GL_LOGGER.info("minecraftGlCapabilities:\n"+getVersionInfo(minecraftGlCapabilities));
if (OVERWIDE_VANILLA_GL_LOGGER)
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream((msg) -> {
logMessage(msg);
}, vanillaDebugMessageBuilder), true));
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, vanillaDebugMessageBuilder), true));
GLFW.glfwMakeContextCurrent(0L);
@@ -285,25 +285,25 @@ public class GLProxy
// create the LodBuilder context
lodBuilderGlContext = GLFW.glfwCreateWindow(64, 48, "LOD Builder Window", 0L, minecraftGlContext);
if (lodBuilderGlContext == 0) {
ApiShared.LOGGER.error("ERROR: Failed to create GLFW context for OpenGL 3.2 with"
GL_LOGGER.error("ERROR: Failed to create GLFW context for OpenGL 3.2 with"
+ " Forward Compat Core Profile! Your OS may have not been able to support it!");
throw new UnsupportedOperationException("Forward Compat Core Profile 3.2 creation failure");
}
GLFW.glfwMakeContextCurrent(lodBuilderGlContext);
lodBuilderGlCapabilities = GL.createCapabilities();
ApiShared.LOGGER.info("lodBuilderGlCapabilities:\n"+getVersionInfo(lodBuilderGlCapabilities));
GL_LOGGER.info("lodBuilderGlCapabilities:\n"+getVersionInfo(lodBuilderGlCapabilities));
GLFW.glfwMakeContextCurrent(0L);
// create the proxyWorker's context
proxyWorkerGlContext = GLFW.glfwCreateWindow(64, 48, "LOD proxy worker Window", 0L, minecraftGlContext);
if (proxyWorkerGlContext == 0) {
ApiShared.LOGGER.error("ERROR: Failed to create GLFW context for OpenGL 3.2 with"
GL_LOGGER.error("ERROR: Failed to create GLFW context for OpenGL 3.2 with"
+ " Forward Compat Core Profile! Your OS may have not been able to support it!");
throw new UnsupportedOperationException("Forward Compat Core Profile 3.2 creation failure");
}
GLFW.glfwMakeContextCurrent(proxyWorkerGlContext);
proxyWorkerGlCapabilities = GL.createCapabilities();
ApiShared.LOGGER.info("proxyWorkerGlCapabilities:\n"+getVersionInfo(lodBuilderGlCapabilities));
GL_LOGGER.info("proxyWorkerGlCapabilities:\n"+getVersionInfo(lodBuilderGlCapabilities));
GLFW.glfwMakeContextCurrent(0L);
// Check if we can use the make-over version of Vertex Attribute, which is available in GL4.3 or after
@@ -320,9 +320,7 @@ public class GLProxy
setGlContext(GLProxyContext.LOD_BUILDER);
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream((msg) -> {
logMessage(msg);
}, lodBuilderDebugMessageBuilder), true));
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, lodBuilderDebugMessageBuilder), true));
// get specific capabilities
// Check if we can use the Buffer Storage, which is available in GL4.4 or after
@@ -331,7 +329,7 @@ public class GLProxy
// display the capabilities
if (!bufferStorageSupported)
{
ApiShared.LOGGER.warn("This GPU doesn't support Buffer Storage (OpenGL 4.4), falling back to using other methods.");
GL_LOGGER.warn("This GPU doesn't support Buffer Storage (OpenGL 4.4), falling back to using other methods.");
}
String vendor = GL32.glGetString(GL32.GL_VENDOR).toUpperCase(); // example return: "NVIDIA CORPORATION"
@@ -345,14 +343,12 @@ public class GLProxy
// AMD or Intel card
preferredUploadMethod = GpuUploadMethod.BUFFER_MAPPING;
}
ApiShared.LOGGER.info("GPU Vendor [" + vendor + "], Preferred upload method is [" + preferredUploadMethod + "].");
GL_LOGGER.info("GPU Vendor [" + vendor + "], Preferred upload method is [" + preferredUploadMethod + "].");
setGlContext(GLProxyContext.PROXY_WORKER);
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream((msg) -> {
logMessage(msg);
}, proxyWorkerDebugMessageBuilder), true));
GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, proxyWorkerDebugMessageBuilder), true));
//==========//
// clean up //
@@ -362,7 +358,7 @@ public class GLProxy
setGlContext(GLProxyContext.MINECRAFT);
// GLProxy creation success
ApiShared.LOGGER.info(GLProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day.");
GL_LOGGER.info(GLProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day.");
}
/**
@@ -478,7 +474,7 @@ public class GLProxy
}
catch (Exception e)
{
ApiShared.LOGGER.error(Thread.currentThread().getName() + " ran into a issue: " + e.getMessage());
GL_LOGGER.error(Thread.currentThread().getName() + " ran into a issue: " + e.getMessage());
e.printStackTrace();
}
finally
@@ -490,14 +486,14 @@ public class GLProxy
public static void ensureAllGLJobCompleted() {
if (!hasInstance()) return;
ApiShared.LOGGER.info("Blocking until GL jobs finished!");
GL_LOGGER.info("Blocking until GL jobs finished!");
try {
instance.workerThread.shutdown();
boolean worked = instance.workerThread.awaitTermination(30, TimeUnit.SECONDS);
if (!worked)
ApiShared.LOGGER.error("GLWorkerThread shutdown timed out! Game may crash on exit due to cleanup failure!");
GL_LOGGER.error("GLWorkerThread shutdown timed out! Game may crash on exit due to cleanup failure!");
} catch (InterruptedException e) {
ApiShared.LOGGER.error("GLWorkerThread shutdown is interrupted! Game may crash on exit due to cleanup failure!");
GL_LOGGER.error("GLWorkerThread shutdown is interrupted! Game may crash on exit due to cleanup failure!");
e.printStackTrace();
} finally {
instance.workerThread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(GLProxy.class.getSimpleName() + "-Worker-Thread").build());
@@ -19,7 +19,6 @@
package com.seibel.lod.core.render;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.enums.rendering.*;
import com.seibel.lod.core.handlers.IReflectionHandler;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
@@ -31,6 +30,8 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import static com.seibel.lod.core.render.GLProxy.GL_LOGGER;
/**
* This object is just a replacement for an array
* to make things easier to understand in the LodRenderer.
@@ -104,9 +105,9 @@ public class LodFogConfig
if (DEBUG_DUMP_GENERATED_CODE) {
try (FileOutputStream file = new FileOutputStream("debugGenerated.frag", false)) {
file.write(str.toString().getBytes(StandardCharsets.UTF_8));
ApiShared.LOGGER.info("Debug dumped generated code to debugGenerated.frag for {}", path);
GL_LOGGER.info("Debug dumped generated code to debugGenerated.frag for {}", path);
} catch (IOException e) {
ApiShared.LOGGER.warn("Failed to debug dump generated code to file for {}", path);
GL_LOGGER.warn("Failed to debug dump generated code to file for {}", path);
}
}
return str;
@@ -21,15 +21,12 @@ package com.seibel.lod.core.render;
import java.awt.Color;
import com.seibel.lod.core.enums.rendering.FogDistance;
import com.seibel.lod.core.enums.rendering.FogDrawMode;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.objects.math.Vec3f;
import com.seibel.lod.core.render.objects.*;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.IVersionConstants;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
public class LodRenderProgram extends ShaderProgram {
public static final String VERTEX_SHADER_PATH = "shaders/standard.vert";
@@ -23,14 +23,16 @@ import java.awt.Color;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.logging.SpamReducedLogger;
import com.seibel.lod.core.objects.BoolType;
import com.seibel.lod.core.objects.Pos2D;
import com.seibel.lod.core.util.*;
import com.seibel.lod.core.util.gridList.*;
import org.lwjgl.opengl.GL32;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.objects.opengl.builders.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodBufferBuilderFactory;
import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.enums.rendering.FogColorMode;
import com.seibel.lod.core.enums.rendering.FogDistance;
@@ -57,6 +59,9 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
*/
public class LodRenderer
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final ConfigBasedLogger EVENT_LOGGER = new ConfigBasedLogger(() -> CONFIG.client().advanced().debugging().debugSwitch().getLogRendererBufferEvent());
public static final boolean ENABLE_DRAW_LAG_SPIKE_LOGGING = false;
public static final boolean ENABLE_DUMP_GL_STATE = false;
public static final long DRAW_LAG_SPIKE_THRESOLD_NS = TimeUnit.NANOSECONDS.convert(20, TimeUnit.MILLISECONDS);
@@ -69,7 +74,7 @@ public class LodRenderer
if (!ENABLE_DRAW_LAG_SPIKE_LOGGING) return;
timer = System.nanoTime() - timer;
if (timer> DRAW_LAG_SPIKE_THRESOLD_NS) { //4 ms
ApiShared.LOGGER.info("NOTE: "+source+" took "+Duration.ofNanos(timer)+"!");
EVENT_LOGGER.debug("NOTE: "+source+" took "+Duration.ofNanos(timer)+"!");
}
}
@@ -77,7 +82,6 @@ public class LodRenderer
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/**
* If true the LODs colors will be replaced with
@@ -422,16 +426,18 @@ public class LodRenderer
/** Setup all render objects - REQUIRES to be in render thread */
private void setup() {
if (isSetupComplete) {
ApiShared.LOGGER.warn("Renderer setup called but it has already completed setup!");
EVENT_LOGGER.warn("Renderer setup called but it has already completed setup!");
return;
}
if (!GLProxy.hasInstance()) {
ApiShared.LOGGER.warn("Renderer setup called but GLProxy has not yet been setup!");
EVENT_LOGGER.warn("Renderer setup called but GLProxy has not yet been setup!");
return;
}
EVENT_LOGGER.info("Setting up renderer");
isSetupComplete = true;
shaderProgram = new LodRenderProgram(LodFogConfig.generateFogConfig());
EVENT_LOGGER.info("Renderer setup complete");
}
/** Create all buffers that will be used. */
@@ -503,17 +509,17 @@ public class LodRenderer
* (Many objects are Native, outside of JVM, and need manual cleanup) */
private void cleanup() {
if (!isSetupComplete) {
ApiShared.LOGGER.warn("Renderer cleanup called but Renderer has not completed setup!");
EVENT_LOGGER.warn("Renderer cleanup called but Renderer has not completed setup!");
return;
}
if (!GLProxy.hasInstance()) {
ApiShared.LOGGER.warn("Renderer Cleanup called but the GLProxy has never been inited!");
EVENT_LOGGER.warn("Renderer Cleanup called but the GLProxy has never been inited!");
return;
}
isSetupComplete = false;
ApiShared.LOGGER.info("Renderer Cleanup Started");
EVENT_LOGGER.info("Renderer Cleanup Started");
shaderProgram.free();
ApiShared.LOGGER.info("Renderer Cleanup Complete");
EVENT_LOGGER.info("Renderer Cleanup Complete");
}
/** Calls the BufferBuilder's destroyBuffers method. */
@@ -26,11 +26,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.seibel.lod.core.api.ApiShared;
import org.lwjgl.opengl.GL32;
import com.seibel.lod.core.api.ClientApi;
import static com.seibel.lod.core.render.GLProxy.GL_LOGGER;
/**
* This object holds a OpenGL reference to a shader
* and allows for reading in and compiling a shader file.
@@ -51,7 +52,7 @@ public class Shader
*/
public Shader(int type, String path, boolean absoluteFilePath)
{
ApiShared.LOGGER.info("Loading shader at "+path);
GL_LOGGER.info("Loading shader at "+path);
// Create an empty shader object
id = GL32.glCreateShader(type);
StringBuilder source = loadFile(path, absoluteFilePath, new StringBuilder());
@@ -65,12 +66,13 @@ public class Shader
free(); // important!
throw new RuntimeException(message);
}
ApiShared.LOGGER.info("Shader at "+path+" loaded sucessfully.");
GL_LOGGER.info("Shader at "+path+" loaded sucessfully.");
}
public Shader(int type, String sourceString)
{
ApiShared.LOGGER.info("Loading shader with soruceString:\n{}", sourceString);
GL_LOGGER.info("Loading shader with type: {}", type);
GL_LOGGER.debug("Source:\n{}", sourceString);
// Create an empty shader object
id = GL32.glCreateShader(type);
GL32.glShaderSource(id, sourceString);
@@ -83,7 +85,7 @@ public class Shader
free(); // important!
throw new RuntimeException(message);
}
ApiShared.LOGGER.info("Shader loaded sucessfully.");
GL_LOGGER.info("Shader loaded sucessfully.");
}
// REMEMBER to always free the resource!
@@ -1,9 +1,8 @@
package com.seibel.lod.core.render.objects;
import com.seibel.lod.core.api.ApiShared;
import org.lwjgl.opengl.GL43;
import com.seibel.lod.core.api.ClientApi;
import static com.seibel.lod.core.render.GLProxy.GL_LOGGER;
// In OpenGL 4.3 and later, Vertex Attribute got a make-over.
// Now it provides support for buffer binding points natively.
@@ -64,11 +63,11 @@ public final class VertexAttributePostGL43 extends VertexAttribute {
// Requires VertexAttribute binded
public void completeAndCheck(int expectedStrideSize) {
if (strideSize != expectedStrideSize) {
ApiShared.LOGGER.error("Vertex Attribute calculated stride size " + strideSize +
GL_LOGGER.error("Vertex Attribute calculated stride size " + strideSize +
" does not match the provided expected stride size " + expectedStrideSize + "!");
throw new IllegalArgumentException("Vertex Attribute Incorrect Format");
}
ApiShared.LOGGER.info("Vertex Attribute (GL43+) completed. It contains "+numberOfBindingPoints
GL_LOGGER.info("Vertex Attribute (GL43+) completed. It contains "+numberOfBindingPoints
+" binding points and a stride size of "+strideSize);
}
@@ -5,11 +5,12 @@ import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet;
import com.seibel.lod.core.api.ApiShared;
import org.lwjgl.opengl.GL32;
import com.seibel.lod.core.api.ClientApi;
import static com.seibel.lod.core.render.GLProxy.GL_LOGGER;
public final class VertexAttributePreGL43 extends VertexAttribute {
@@ -120,31 +121,30 @@ public final class VertexAttributePreGL43 extends VertexAttribute {
for (int i = 0; i < pointers.length; i++) {
VertexPointer pointer = pointers[i];
if (pointer == null) {
ApiShared.LOGGER.warn("Vertex Attribute index "+i+" is not set! No index should be skipped normally!");
GL_LOGGER.warn("Vertex Attribute index "+i+" is not set! No index should be skipped normally!");
continue;
}
pointersOffset[i] = currentOffset;
currentOffset += pointer.byteSize;
}
if (currentOffset != expectedStrideSize) {
ApiShared.LOGGER.error("Vertex Attribute calculated stride size " + currentOffset +
GL_LOGGER.error("Vertex Attribute calculated stride size " + currentOffset +
" does not match the provided expected stride size " + expectedStrideSize + "!");
throw new IllegalArgumentException("Vertex Attribute Incorrect Format");
}
strideSize = currentOffset;
ApiShared.LOGGER.info("Vertex Attribute (pre GL43) completed.");
GL_LOGGER.info("Vertex Attribute (pre GL43) completed.");
// Debug logging
ApiShared.LOGGER.info("Vertex Attribute Debug Data:");
ApiShared.LOGGER.info("AttributeIndex: ElementCount, glType, normalized, strideSize, offset");
GL_LOGGER.debug("AttributeIndex: ElementCount, glType, normalized, strideSize, offset");
for (int i=0; i< pointers.length; i++) {
VertexPointer pointer = pointers[i];
if (pointer==null) {
ApiShared.LOGGER.warn(i + ": Null!!!!");
GL_LOGGER.debug(i + ": Null!!!!");
continue;
}
ApiShared.LOGGER.info(i + ": "+pointer.elementCount+", "+
GL_LOGGER.debug(i + ": "+pointer.elementCount+", "+
pointer.glType+", "+pointer.normalized+", "+strideSize+", "+pointersOffset[i]);
}
@@ -19,6 +19,8 @@
package com.seibel.lod.core.util;
import com.seibel.lod.core.logging.SpamReducedLogger;
import java.util.Arrays;
@@ -193,7 +195,7 @@ public class DataPointUtil
}
private static SpamReducedLogger warnLogger = new SpamReducedLogger(1);
private static final SpamReducedLogger warnLogger = new SpamReducedLogger(1);
public static byte getGenerationMode(long dataPoint)
{
@@ -1,60 +0,0 @@
package com.seibel.lod.core.util;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
public class SpamReducedLogger {
private final int maxLogCount;
private final AtomicInteger logTries = new AtomicInteger(0);
private int sectionLogCount = -1;
public SpamReducedLogger(int maxLogPerSec) {
maxLogCount = maxLogPerSec;
ClientApi.spamReducedLoggers.add(new WeakReference<SpamReducedLogger>(this));
}
public void reset() {logTries.set(0);}
public boolean canMaybeLog() {return logTries.get() < maxLogCount;}
public void info(String str, Object... param) {
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
if (sectionLogCount >= maxLogCount) return;
ApiShared.LOGGER.info(str, param);
}
public void debug(String str, Object... param) {
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
if (sectionLogCount >= maxLogCount) return;
ApiShared.LOGGER.debug(str, param);
}
public void warn(String str, Object... param) {
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
if (sectionLogCount >= maxLogCount) return;
ApiShared.LOGGER.warn(str, param);
}
public void error(String str, Object... param) {
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
if (sectionLogCount >= maxLogCount) return;
ApiShared.LOGGER.error(str, param);
}
public void incLogTries() {
sectionLogCount = -1;
}
public void infoInc(String str, Object... param) {
if (logTries.getAndIncrement() >= maxLogCount) return;
ApiShared.LOGGER.info(str, param);
}
public void debugInc(String str, Object... param) {
if (logTries.getAndIncrement() >= maxLogCount) return;
ApiShared.LOGGER.debug(str, param);
}
public void warnInc(String str, Object... param) {
if (logTries.getAndIncrement() >= maxLogCount) return;
ApiShared.LOGGER.warn(str, param);
}
public void errorInc(String str, Object... param) {
if (logTries.getAndIncrement() >= maxLogCount) return;
ApiShared.LOGGER.error(str, param);
}
}
@@ -22,7 +22,8 @@ public class StatsMap
longMap.put(key, longMap.getOrDefault(key, 0L)+value);
}
public void incBytesStat(String key, long bytes) {
bytesMap.put(key, new UnitBytes(bytesMap.getOrDefault(key, new UnitBytes(0)).value()+bytes));
long b = bytesMap.getOrDefault(key, new UnitBytes(0)).value;
bytesMap.put(key, new UnitBytes(b+bytes));
}
@Override
@@ -1,5 +1,7 @@
package com.seibel.lod.core.util;
import java.util.Objects;
public class UnitBytes
{
public final long value;
@@ -43,4 +45,17 @@ public class UnitBytes
str.append(v).append("B");
return str.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UnitBytes unitBytes = (UnitBytes) o;
return value == unitBytes.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}
@@ -19,7 +19,7 @@
package com.seibel.lod.core.wrapperInterfaces;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
@@ -19,18 +19,7 @@
package com.seibel.lod.core.wrapperInterfaces.config;
import com.seibel.lod.core.enums.config.BlocksToAvoid;
import com.seibel.lod.core.enums.config.BufferRebuildTimes;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.DropoffQuality;
import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.enums.config.HorizontalQuality;
import com.seibel.lod.core.enums.config.HorizontalResolution;
import com.seibel.lod.core.enums.config.LightGenerationMode;
import com.seibel.lod.core.enums.config.ServerFolderNameMode;
import com.seibel.lod.core.enums.config.VanillaOverdraw;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.enums.config.*;
import com.seibel.lod.core.enums.rendering.*;
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
@@ -831,6 +820,88 @@ public interface ILodConfigWrapperSingleton extends IBindable
+ " and the F6 key can be used to enable and disable LOD rendering.";
boolean getDebugKeybindingsEnabled();
void setDebugKeybindingsEnabled(boolean newEnableDebugKeybindings);
IDebugSwitch debugSwitch();
interface IDebugSwitch
{
String DESC = "These settings can be used to look for bugs by enabling and disabling logging.";
/* The logging switches available:
* WorldGenEvent
* WorldGenPerformance
* WorldGenLoadEvent
* LodBuilderEvent
* RendererBufferEvent
* RendererGLEvent
* FileReadWriteEvent
* FileSubDimEvent
* NetworkEvent //NOT IMPL YET
*/
LoggerMode LOG_WORLDGEN_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_WORLDGEN_EVENT_DESC = ""
+ " If enabled, the mod will log information about the world generation process. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogWorldGenEvent();
void setLogWorldGenEvent(LoggerMode newLogWorldGenEvent);
LoggerMode LOG_WORLDGEN_PERFORMANCE_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_WORLDGEN_PERFORMANCE_DESC = ""
+ " If enabled, the mod will log performance about the world generation process. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogWorldGenPerformance();
void setLogWorldGenPerformance(LoggerMode newLogWorldGenPerformance);
LoggerMode LOG_WORLDGEN_LOAD_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_FILE;
String LOG_WORLDGEN_LOAD_EVENT_DESC = ""
+ " If enabled, the mod will log information about the world generation process. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogWorldGenLoadEvent();
void setLogWorldGenLoadEvent(LoggerMode newLogWorldGenLoadEvent);
LoggerMode LOG_LODBUILDER_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_LODBUILDER_EVENT_DESC = ""
+ " If enabled, the mod will log information about the LOD generation process. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogLodBuilderEvent();
void setLogLodBuilderEvent(LoggerMode newLogLodBuilderEvent);
LoggerMode LOG_RENDERER_BUFFER_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_RENDERER_BUFFER_EVENT_DESC = ""
+ " If enabled, the mod will log information about the renderer buffer process. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogRendererBufferEvent();
void setLogRendererBufferEvent(LoggerMode newLogRendererBufferEvent);
LoggerMode LOG_RENDERER_GL_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_RENDERER_GL_EVENT_DESC = ""
+ " If enabled, the mod will log information about the renderer OpenGL process. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogRendererGLEvent();
void setLogRendererGLEvent(LoggerMode newLogRendererGLEvent);
LoggerMode LOG_FILE_READWRITE_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_FILE_READWRITE_EVENT_DESC = ""
+ " If enabled, the mod will log information about file read/write operations. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogFileReadWriteEvent();
void setLogFileReadWriteEvent(LoggerMode newLogFileReadWriteEvent);
LoggerMode LOG_FILE_SUB_DIM_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_FILE_SUB_DIM_EVENT_DESC = ""
+ " If enabled, the mod will log information about file sub-dimension operations. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogFileSubDimEvent();
void setLogFileSubDimEvent(LoggerMode newLogFileSubDimEvent);
LoggerMode LOG_NETWORK_EVENT_DEFAULT = LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE;
String LOG_NETWORK_EVENT_DESC = ""
+ " If enabled, the mod will log information about network operations. \n"
+ " This can be useful for debugging. \n";
LoggerMode getLogNetworkEvent();
void setLogNetworkEvent(LoggerMode newLogNetworkEvent);
}
}
interface IBuffers
@@ -1,6 +1,6 @@
package com.seibel.lod.core.wrapperInterfaces.worldGeneration;
import com.seibel.lod.core.objects.opengl.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
@@ -248,6 +248,28 @@
"Enable debug keybindings",
"DistantHorizons.config.client.advanced.debugging.enableDebugKeybindings.@tooltip":
"§6True:§r debug keybindings can be used to change the Debug mode in game.",
"DistantHorizons.config.client.advanced.debugging.debugSwitch":
"Debug switch",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.@tooltip":
"The debug switch to use when logging.",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logWorldGenEvent":
"World Gen Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logWorldGenPerformance":
"World Gen Performance Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logWorldGenLoadEvent":
"World Gen Load Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logLodBuilderEvent":
"Lod Builder Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logRendererBufferEvent":
"Renderer Buffer Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logRendererGLEvent":
"Renderer GL Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logFileReadWriteEvent":
"File Read Write Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logFileSubDimEvent":
"File Sub Dim Event Logging",
"DistantHorizons.config.client.advanced.debugging.debugSwitch.logNetworkEvent":
"Network Event Logging",
"DistantHorizons.config.client.advanced.lodOnlyMode":
"Lod Only Mode §6(ONLY FOR FUN)§r",
"DistantHorizons.config.client.advanced.lodOnlyMode.@tooltip":
@@ -392,6 +414,48 @@
"Show generation mode",
"DistantHorizons.config.enum.DebugMode.SHOW_GENMODE_WIREFRAME":
"Show generation mode with wireframe",
/*
DISABLED(Level.OFF, Level.OFF),
LOG_ALL_TO_FILE(Level.ALL, Level.OFF),
LOG_ERROR_TO_CHAT(Level.ALL, Level.ERROR),
LOG_WARNING_TO_CHAT(Level.ALL, Level.WARN),
LOG_INFO_TO_CHAT(Level.ALL, Level.INFO),
LOG_DEBUG_TO_CHAT(Level.ALL, Level.DEBUG),
LOG_ALL_TO_CHAT(Level.ALL, Level.ALL),
LOG_ERROR_TO_CHAT_AND_FILE(Level.ERROR, Level.ERROR),
LOG_WARNING_TO_CHAT_AND_FILE(Level.WARN, Level.WARN),
LOG_INFO_TO_CHAT_AND_FILE(Level.INFO, Level.INFO),
LOG_DEBUG_TO_CHAT_AND_FILE(Level.DEBUG, Level.DEBUG),
LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE(Level.INFO, Level.WARN),
LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE(Level.INFO, Level.ERROR),
*/
"DistantHorizons.config.enum.LoggerMode.DISABLED":
"Disabled",
"DistantHorizons.config.enum.LoggerMode.LOG_ALL_TO_FILE":
"File: All, Chat: Off",
"DistantHorizons.config.enum.LoggerMode.LOG_ERROR_TO_CHAT":
"File: All, Chat: Error",
"DistantHorizons.config.enum.LoggerMode.LOG_WARNING_TO_CHAT":
"File: All, Chat: Warning",
"DistantHorizons.config.enum.LoggerMode.LOG_INFO_TO_CHAT":
"File: All, Chat: Info",
"DistantHorizons.config.enum.LoggerMode.LOG_DEBUG_TO_CHAT":
"File: All, Chat: Debug",
"DistantHorizons.config.enum.LoggerMode.LOG_ALL_TO_CHAT":
"File: All, Chat: All",
"DistantHorizons.config.enum.LoggerMode.LOG_ERROR_TO_CHAT_AND_FILE":
"File: Error, Chat: Error",
"DistantHorizons.config.enum.LoggerMode.LOG_WARNING_TO_CHAT_AND_FILE":
"File: Warning, Chat: Warning",
"DistantHorizons.config.enum.LoggerMode.LOG_INFO_TO_CHAT_AND_FILE":
"File: Info, Chat: Info",
"DistantHorizons.config.enum.LoggerMode.LOG_DEBUG_TO_CHAT_AND_FILE":
"File: Debug, Chat: Debug",
"DistantHorizons.config.enum.LoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE":
"File: Info, Chat: Warning",
"DistantHorizons.config.enum.LoggerMode.LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE":
"File: Info, Chat: Error",
"DistantHorizons.config.enum.GpuUploadMethod.AUTO":
"Auto",
"DistantHorizons.config.enum.GpuUploadMethod.BUFFER_STORAGE":