update debug wireframe renderer

This commit is contained in:
James Seibel
2026-03-09 17:35:24 -05:00
parent 17cdb0f745
commit 49e34d78a5
20 changed files with 455 additions and 126 deletions
@@ -3,6 +3,7 @@ package com.seibel.distanthorizons.api.interfaces.render;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
import java.util.List; import java.util.List;
@@ -18,7 +19,7 @@ import java.util.List;
* @version 2024-7-3 * @version 2024-7-3
* @since API 3.0.0 * @since API 3.0.0
*/ */
public interface IDhApiCustomRenderObjectFactory public interface IDhApiCustomRenderObjectFactory extends IBindable
{ {
/** /**
* Creates a {@link IDhApiRenderableBoxGroup} from for the given {@link DhApiRenderableBox} * Creates a {@link IDhApiRenderableBoxGroup} from for the given {@link DhApiRenderableBox}
@@ -60,6 +60,8 @@ public class DhApiRenderParam implements IDhApiEventParam
public final DhApiMat4f dhProjectionMatrix; public final DhApiMat4f dhProjectionMatrix;
/** The model view matrix Distant Horizons is using to render this frame. */ /** The model view matrix Distant Horizons is using to render this frame. */
public final DhApiMat4f dhModelViewMatrix; public final DhApiMat4f dhModelViewMatrix;
/** combination of the MVM and projection matrices */
public final DhApiMat4f dhMvmProjMatrix;
public final int worldYOffset; public final int worldYOffset;
@@ -111,6 +113,10 @@ public class DhApiRenderParam implements IDhApiEventParam
this.dhProjectionMatrix = newDhProjectionMatrix; this.dhProjectionMatrix = newDhProjectionMatrix;
this.dhModelViewMatrix = newDhModelViewMatrix; this.dhModelViewMatrix = newDhModelViewMatrix;
DhApiMat4f combinedMatrix = new DhApiMat4f(this.dhProjectionMatrix);
combinedMatrix.multiply(this.dhModelViewMatrix);
this.dhMvmProjMatrix = combinedMatrix;
this.worldYOffset = worldYOffset; this.worldYOffset = worldYOffset;
this.clientLevelWrapper = clientLevelWrapper; this.clientLevelWrapper = clientLevelWrapper;
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.core; package com.seibel.distanthorizons.core;
import com.github.luben.zstd.ZstdOutputStream; import com.github.luben.zstd.ZstdOutputStream;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderEvent;
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;
@@ -160,13 +161,17 @@ public class Initializer
DhApi.Delayed.terrainRepo = DhApiTerrainDataRepo.INSTANCE; DhApi.Delayed.terrainRepo = DhApiTerrainDataRepo.INSTANCE;
DhApi.Delayed.worldProxy = DhApiWorldProxy.INSTANCE; DhApi.Delayed.worldProxy = DhApiWorldProxy.INSTANCE;
DhApi.Delayed.renderProxy = DhApiRenderProxy.INSTANCE; DhApi.Delayed.renderProxy = DhApiRenderProxy.INSTANCE;
DhApi.Delayed.customRenderObjectFactory = GenericRenderObjectFactory.INSTANCE;
DhApi.Delayed.wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class); DhApi.Delayed.wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
if (DhApi.Delayed.wrapperFactory == null) if (DhApi.Delayed.wrapperFactory == null)
{ {
LOGGER.error("Programmer Error: No ["+IWrapperFactory.class.getSimpleName()+"] assigned to the DhApi."); MC_CLIENT.crashMinecraft("Programmer Error: No ["+IWrapperFactory.class.getSimpleName()+"] assigned to the DhApi.", new Exception());
} }
DhApi.Delayed.customRenderObjectFactory = SingletonInjector.INSTANCE.get(IDhApiCustomRenderObjectFactory.class);
if (DhApi.Delayed.customRenderObjectFactory == null)
{
MC_CLIENT.crashMinecraft("Programmer Error: No ["+IDhApiCustomRenderObjectFactory.class.getSimpleName()+"] assigned to the DhApi.", new Exception());
}
DhApi.events.bind(DhApiBeforeRenderEvent.class, IgnoredDimensionCsvHandler.INSTANCE); DhApi.events.bind(DhApiBeforeRenderEvent.class, IgnoredDimensionCsvHandler.INSTANCE);
@@ -34,7 +34,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.DhApiTerrainDataPointUtil; import com.seibel.distanthorizons.core.util.DhApiTerrainDataPointUtil;
import com.seibel.distanthorizons.core.util.FullDataPointUtil; import com.seibel.distanthorizons.core.util.FullDataPointUtil;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
@@ -66,6 +66,8 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
// debugging values // debugging values
private static volatile boolean debugThreadRunning = false; private static volatile boolean debugThreadRunning = false;
private static DhApiTerrainDataCache debugDataCache = new DhApiTerrainDataCache(); private static DhApiTerrainDataCache debugDataCache = new DhApiTerrainDataCache();
@@ -588,9 +590,9 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
if (rayCast.success if (rayCast.success
&& rayCast.payload != null) && rayCast.payload != null)
{ {
DebugRenderer.makeParticle( DEBUG_RENDERER.makeParticle(
new DebugRenderer.BoxParticle( new AbstractDebugWireframeRenderer.BoxParticle(
new DebugRenderer.Box( new AbstractDebugWireframeRenderer.Box(
DhSectionPos.encode((byte) 0, rayCast.payload.pos.x, rayCast.payload.pos.z), DhSectionPos.encode((byte) 0, rayCast.payload.pos.x, rayCast.payload.pos.z),
rayCast.payload.dataPoint.bottomYBlockPos, rayCast.payload.dataPoint.bottomYBlockPos,
rayCast.payload.dataPoint.topYBlockPos, rayCast.payload.dataPoint.topYBlockPos,
@@ -32,7 +32,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo; import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
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.util.threading.ThreadPoolUtil;
@@ -57,6 +57,7 @@ public class SharedApi
/** will be null on the server-side */ /** will be null on the server-side */
@Nullable @Nullable
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final AbstractDebugWireframeRenderer DEBUG_WIREFRAME_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
public static final WorldChunkUpdateManager WORLD_CHUNK_UPDATE_MANAGER = WorldChunkUpdateManager.INSTANCE; // local fariable for quick access public static final WorldChunkUpdateManager WORLD_CHUNK_UPDATE_MANAGER = WorldChunkUpdateManager.INSTANCE; // local fariable for quick access
@@ -105,7 +106,8 @@ public class SharedApi
else else
{ {
ThreadPoolUtil.shutdownThreadPools(); ThreadPoolUtil.shutdownThreadPools();
DebugRenderer.clearRenderables();
DEBUG_WIREFRAME_RENDERER.clearRenderables();
if (MC_RENDER != null) if (MC_RENDER != null)
{ {
@@ -24,9 +24,8 @@ 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.pos.DhSectionPos; 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.render.glObject.GLProxy; import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer;
@@ -49,13 +48,6 @@ public class LodBufferContainer implements AutoCloseable
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
/** number of bytes a single quad takes */
public static final int QUADS_BYTE_SIZE = LodUtil.DH_VERTEX_FORMAT.getByteSize() * 4;
/** how big a single VBO can be in bytes */
public static final int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB
public static final int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE;
public static final int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE;
/** the position closest to minimum X/Z infinity and the level's lowest Y */ /** the position closest to minimum X/Z infinity and the level's lowest Y */
public final DhBlockPos minCornerBlockPos; public final DhBlockPos minCornerBlockPos;
@@ -75,6 +67,7 @@ public class LodBufferContainer implements AutoCloseable
//==============// //==============//
// constructors // // constructors //
//==============// //==============//
//region
public LodBufferContainer(long pos, DhBlockPos minCornerBlockPos) public LodBufferContainer(long pos, DhBlockPos minCornerBlockPos)
{ {
@@ -86,11 +79,14 @@ public class LodBufferContainer implements AutoCloseable
this.uniformContainer.createUniformData(this); this.uniformContainer.createUniformData(this);
} }
//endregion
//==================// //==================//
// buffer uploading // // buffer uploading //
//==================// //==================//
//region
/** Should be run on a DH thread. */ /** Should be run on a DH thread. */
public synchronized CompletableFuture<LodBufferContainer> makeAndUploadBuffersAsync(LodQuadBuilder builder) public synchronized CompletableFuture<LodBufferContainer> makeAndUploadBuffersAsync(LodQuadBuilder builder)
@@ -128,12 +124,12 @@ public class LodBufferContainer implements AutoCloseable
ArrayList<ByteBuffer> opaqueBuffers = builder.makeOpaqueVertexBuffers(); ArrayList<ByteBuffer> opaqueBuffers = builder.makeOpaqueVertexBuffers();
ArrayList<ByteBuffer> transparentBuffers = builder.makeTransparentVertexBuffers(); ArrayList<ByteBuffer> transparentBuffers = builder.makeTransparentVertexBuffers();
this.vbos = resizeBuffer(this.vbos, opaqueBuffers.size()); this.vbos = resizeBufferArray(this.vbos, opaqueBuffers.size());
this.vbosTransparent = resizeBuffer(this.vbosTransparent, transparentBuffers.size()); this.vbosTransparent = resizeBufferArray(this.vbosTransparent, transparentBuffers.size());
// upload on MC's render thread // upload on MC's render thread
GLProxy.queueRunningOnRenderThread(() -> RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() ->
{ {
try try
{ {
@@ -144,11 +140,9 @@ public class LodBufferContainer implements AutoCloseable
throw new InterruptedException(); throw new InterruptedException();
} }
EDhApiGpuUploadMethod gpuUploadMethod = GLProxy.getInstance().getGpuUploadMethod();
// upload on the render thread // upload on the render thread
uploadBuffersDirect(this.vbos, opaqueBuffers, gpuUploadMethod); uploadBuffers(this.vbos, opaqueBuffers);
uploadBuffersDirect(this.vbosTransparent, transparentBuffers, gpuUploadMethod); uploadBuffers(this.vbosTransparent, transparentBuffers);
this.buffersUploaded = true; this.buffersUploaded = true;
// success // success
@@ -182,7 +176,7 @@ public class LodBufferContainer implements AutoCloseable
return future; return future;
} }
private static IVertexBufferWrapper[] resizeBuffer(IVertexBufferWrapper[] vbos, int newSize) private static IVertexBufferWrapper[] resizeBufferArray(IVertexBufferWrapper[] vbos, int newSize)
{ {
if (vbos.length == newSize) if (vbos.length == newSize)
{ {
@@ -203,9 +197,7 @@ public class LodBufferContainer implements AutoCloseable
} }
return newVbos; return newVbos;
} }
private static void uploadBuffersDirect( private static void uploadBuffers(IVertexBufferWrapper[] vbos, ArrayList<ByteBuffer> byteBuffers) throws InterruptedException
IVertexBufferWrapper[] vbos, ArrayList<ByteBuffer> byteBuffers,
EDhApiGpuUploadMethod uploadMethod) throws InterruptedException
{ {
int vboIndex = 0; int vboIndex = 0;
for (int i = 0; i < byteBuffers.size(); i++) for (int i = 0; i < byteBuffers.size(); i++)
@@ -227,7 +219,7 @@ public class LodBufferContainer implements AutoCloseable
ByteBuffer buffer = byteBuffers.get(i); ByteBuffer buffer = byteBuffers.get(i);
int size = buffer.limit() - buffer.position(); int size = buffer.limit() - buffer.position();
int vertexCount = size / lodRenderer.getVertexSize(); int vertexCount = size / lodRenderer.getVertexByteSize();
try try
{ {
@@ -249,11 +241,14 @@ public class LodBufferContainer implements AutoCloseable
} }
} }
//endregion
//================// //================//
// helper methods // // helper methods //
//================// //================//
//region
/** can be used when debugging */ /** can be used when debugging */
public boolean hasNonNullVbos() { return this.vbos != null || this.vbosTransparent != null; } public boolean hasNonNullVbos() { return this.vbos != null || this.vbosTransparent != null; }
@@ -278,11 +273,14 @@ public class LodBufferContainer implements AutoCloseable
public boolean uploadInProgress() { return this.uploadFutureRef.get() != null; } public boolean uploadInProgress() { return this.uploadFutureRef.get() != null; }
//endregion
//================// //================//
// base overrides // // base overrides //
//================// //================//
//region
/** /**
* This method is called when object is no longer in use. * This method is called when object is no longer in use.
@@ -295,7 +293,7 @@ public class LodBufferContainer implements AutoCloseable
{ {
this.buffersUploaded = false; this.buffersUploaded = false;
GLProxy.queueRunningOnRenderThread(() -> RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() ->
{ {
for (IVertexBufferWrapper buffer : this.vbos) for (IVertexBufferWrapper buffer : this.vbos)
{ {
@@ -317,4 +315,8 @@ public class LodBufferContainer implements AutoCloseable
}); });
} }
//endregion
} }
@@ -32,6 +32,7 @@ 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.util.ColorUtil; import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.coreapi.util.MathUtil; import com.seibel.distanthorizons.coreapi.util.MathUtil;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
@@ -306,7 +307,7 @@ public class LodQuadBuilder
// create a new buffer // create a new buffer
if (buffer == null || !buffer.hasRemaining()) if (buffer == null || !buffer.hasRemaining())
{ {
buffer = MemoryUtil.memAlloc(LodBufferContainer.FULL_SIZED_BUFFER); buffer = MemoryUtil.memAlloc(getMaxBufferByteSize());
byteBufferList.add(buffer); byteBufferList.add(buffer);
} }
@@ -481,17 +482,26 @@ public class LodQuadBuilder
return i; return i;
} }
/** Returns how many GpuBuffers will be needed to render opaque quads in this builder. */ private static int maxBufferByteSize = -1;
public int getCurrentNeededOpaqueVertexBufferCount() { return MathUtil.ceilDiv(this.getCurrentOpaqueQuadsCount(), LodBufferContainer.MAX_QUADS_PER_BUFFER); } public static int getMaxBufferByteSize()
/** Returns how many GpuBuffers will be needed to render transparent quads in this builder. */
public int getCurrentNeededTransparentVertexBufferCount()
{ {
if (!this.doTransparency) if (maxBufferByteSize != -1)
{ {
return 0; return maxBufferByteSize;
} }
return MathUtil.ceilDiv(this.getCurrentTransparentQuadsCount(), LodBufferContainer.MAX_QUADS_PER_BUFFER); IMcLodRenderer LOD_RENDERER = SingletonInjector.INSTANCE.get(IMcLodRenderer.class);
/** number of bytes a single quad takes */
int QUADS_BYTE_SIZE = LOD_RENDERER.getVertexByteSize() * 4;
/** how big a single VBO can be in bytes */
int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB
int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE;
int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE;
maxBufferByteSize = FULL_SIZED_BUFFER;
return FULL_SIZED_BUFFER;
} }
///endregion ///endregion
@@ -9,9 +9,7 @@ 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;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel;
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.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; 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.sql.repo.AbstractDhRepo; import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
@@ -38,7 +39,6 @@ import com.seibel.distanthorizons.core.sql.repo.FullDataSourceV2Repo;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.objects.DataCorruptedException; import com.seibel.distanthorizons.core.util.objects.DataCorruptedException;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer;
import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongArrayList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -57,7 +57,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final AbstractDebugWireframeRenderer DEBUG_WIREFRAME_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
private static final Set<String> CORRUPT_DATA_ERRORS_LOGGED = Collections.newSetFromMap(new ConcurrentHashMap<>()); private static final Set<String> CORRUPT_DATA_ERRORS_LOGGED = Collections.newSetFromMap(new ConcurrentHashMap<>());
/** /**
@@ -109,8 +111,7 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
this.updatePropagator = new FullDataUpdatePropagatorV2(this, this.dataUpdater, this.levelId); this.updatePropagator = new FullDataUpdatePropagatorV2(this, this.dataUpdater, this.levelId);
this.dataMigratorV1 = new DataMigratorV1(this.dataUpdater, this.level, this.levelId, this.saveDir); this.dataMigratorV1 = new DataMigratorV1(this.dataUpdater, this.level, this.levelId, this.saveDir);
IMcDebugRenderer debugRenderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); DEBUG_WIREFRAME_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus);
debugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus);
} }
@@ -449,7 +450,7 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
//===========// //===========//
@Override @Override
public void debugRender(IMcDebugRenderer renderer) public void debugRender(AbstractDebugWireframeRenderer renderer)
{ {
this.dataUpdater.debugRender(renderer); this.dataUpdater.debugRender(renderer);
this.updatePropagator.debugRender(renderer); this.updatePropagator.debugRender(renderer);
@@ -466,6 +467,8 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable
this.updatePropagator.close(); this.updatePropagator.close();
this.dataMigratorV1.close(); this.dataMigratorV1.close();
DEBUG_WIREFRAME_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus);
this.repo.close(); this.repo.close();
} }
@@ -7,12 +7,12 @@ 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.pos.DhSectionPos; 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.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.ThreadUtil;
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; 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 com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer;
import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongArrayList;
import java.awt.*; import java.awt.*;
@@ -388,10 +388,10 @@ public class FullDataUpdatePropagatorV2 implements IDebugRenderable, AutoCloseab
//region //region
@Override @Override
public void debugRender(IMcDebugRenderer renderer) public void debugRender(AbstractDebugWireframeRenderer renderer)
{ {
this.updatingPosSet this.updatingPosSet
.forEach((pos) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); .forEach((pos) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); });
} }
@Override @Override
@@ -7,11 +7,11 @@ import com.seibel.distanthorizons.core.file.fullDatafile.IDataSourceUpdateListen
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.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; 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.threading.PositionalLockProvider; import com.seibel.distanthorizons.core.util.threading.PositionalLockProvider;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.awt.*; import java.awt.*;
@@ -225,13 +225,13 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable
//===========// //===========//
@Override @Override
public void debugRender(IMcDebugRenderer renderer) public void debugRender(AbstractDebugWireframeRenderer renderer)
{ {
this.lockedPosSet this.lockedPosSet
.forEach((pos) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); .forEach((pos) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); });
this.queuedUpdateCountsByPos this.queuedUpdateCountsByPos
.forEach((pos, updateCountRef) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); .forEach((pos, updateCountRef) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); });
} }
@Override @Override
@@ -20,13 +20,14 @@
package com.seibel.distanthorizons.core.generation; package com.seibel.distanthorizons.core.generation;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.FullDataPointUtil; import com.seibel.distanthorizons.core.util.FullDataPointUtil;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
@@ -52,6 +53,8 @@ public class DhLightingEngine
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
public static final DhLightingEngine INSTANCE = new DhLightingEngine(); public static final DhLightingEngine INSTANCE = new DhLightingEngine();
private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
/** /**
* Minor garbage collection optimization. <br> * Minor garbage collection optimization. <br>
* Since these objects are always mutated anyway, using a {@link ThreadLocal} will allow us to * Since these objects are always mutated anyway, using a {@link ThreadLocal} will allow us to
@@ -725,9 +728,9 @@ public class DhLightingEngine
// a color can be set to null if you only want to troubleshoot up to a certain light level // a color can be set to null if you only want to troubleshoot up to a certain light level
if (color != null) if (color != null)
{ {
DebugRenderer.makeParticle( DEBUG_RENDERER.makeParticle(
new DebugRenderer.BoxParticle( new AbstractDebugWireframeRenderer.BoxParticle(
new DebugRenderer.Box(DhSectionPos.encode((byte) 0, chunkMinX + x, chunkMinZ + z), y, y + 1, 0.2f, color), new AbstractDebugWireframeRenderer.Box(DhSectionPos.encode((byte) 0, chunkMinX + x, chunkMinZ + z), y, y + 1, 0.2f, color),
10.0, 0f 10.0, 0f
) )
); );
@@ -36,7 +36,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.transformers.LodDataBuilder; import com.seibel.distanthorizons.core.dataObjects.transformers.LodDataBuilder;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.util.ExceptionUtil; import com.seibel.distanthorizons.core.util.ExceptionUtil;
import com.seibel.distanthorizons.core.util.LodUtil.AssertFailureException; import com.seibel.distanthorizons.core.util.LodUtil.AssertFailureException;
@@ -61,6 +61,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
private final IDhApiWorldGenerator generator; private final IDhApiWorldGenerator generator;
@@ -110,7 +111,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
this.lowestDataDetail = generator.getLargestDataDetailLevel(); this.lowestDataDetail = generator.getLargestDataDetailLevel();
this.highestDataDetail = generator.getSmallestDataDetailLevel(); this.highestDataDetail = generator.getSmallestDataDetailLevel();
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue); DEBUG_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue);
LOGGER.info("Created world gen queue"); LOGGER.info("Created world gen queue");
} }
@@ -623,7 +624,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
///region debug ///region debug
@Override @Override
public void debugRender(DebugRenderer renderer) public void debugRender(AbstractDebugWireframeRenderer renderer)
{ {
int levelMinY = this.level.getLevelWrapper().getMinHeight(); int levelMinY = this.level.getLevelWrapper().getMinHeight();
int levelMaxY = this.level.getLevelWrapper().getMaxHeight(); int levelMaxY = this.level.getLevelWrapper().getMaxHeight();
@@ -637,16 +638,16 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
// blue - queued // blue - queued
this.waitingTasks.keySet().forEach((Long pos) -> this.waitingTasks.keySet().forEach((Long pos) ->
{ {
renderer.renderBox( renderer.render(
new DebugRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.blue) new AbstractDebugWireframeRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.blue)
); );
}); });
// red - in progress // red - in progress
this.inProgressGenTasksByLodPos.forEach((Long pos, DataSourceRetrievalTask task) -> this.inProgressGenTasksByLodPos.forEach((Long pos, DataSourceRetrievalTask task) ->
{ {
renderer.renderBox( renderer.render(
new DebugRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.red) new AbstractDebugWireframeRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.red)
); );
}); });
} }
@@ -732,7 +733,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
this.generator.close(); this.generator.close();
DebugRenderer.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue); DEBUG_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue);
try try
@@ -18,6 +18,7 @@ import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceR
import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceResponseMessage; import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceResponseMessage;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; 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;
@@ -42,6 +43,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
.build(); .build();
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
private static final int MAX_RETRY_ATTEMPTS = 3; private static final int MAX_RETRY_ATTEMPTS = 3;
@@ -85,7 +87,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
this.level = level; this.level = level;
this.changedOnly = changedOnly; this.changedOnly = changedOnly;
this.showDebugWireframeConfig = showDebugWireframeConfig; this.showDebugWireframeConfig = showDebugWireframeConfig;
DebugRenderer.register(this, this.showDebugWireframeConfig); DEBUG_RENDERER.register(this, this.showDebugWireframeConfig);
} }
@@ -384,10 +386,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
} }
@Override @Override
public void close() public void close() { DEBUG_RENDERER.unregister(this, this.showDebugWireframeConfig); }
{
DebugRenderer.unregister(this, this.showDebugWireframeConfig);
}
@@ -396,7 +395,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
//===========// //===========//
@Override @Override
public void debugRender(DebugRenderer renderer) public void debugRender(AbstractDebugWireframeRenderer renderer)
{ {
if (MC_CLIENT.getWrappedClientLevel() != this.level.getClientLevelWrapper()) if (MC_CLIENT.getWrappedClientLevel() != this.level.getClientLevelWrapper())
{ {
@@ -427,7 +426,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
} }
} }
renderer.renderBox(new DebugRenderer.Box(pos, -32f, 64f, 0.05f, color)); renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 64f, 0.05f, color));
} }
} }
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.core.render.QuadTree;
import com.seibel.distanthorizons.core.config.Config; 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.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataSourceProviderV2; import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataSourceProviderV2;
import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataUpdatePropagatorV2; import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataUpdatePropagatorV2;
@@ -33,9 +34,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.BeaconRenderHandler;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.ThreadUtil;
import com.seibel.distanthorizons.core.util.WorldGenUtil; import com.seibel.distanthorizons.core.util.WorldGenUtil;
@@ -67,6 +68,9 @@ import java.util.concurrent.locks.ReentrantLock;
public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRenderable, IConfigListener, AutoCloseable public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRenderable, IConfigListener, AutoCloseable
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
/** there should only ever be one {@link LodQuadTree} so having the thread static should be fine */ /** there should only ever be one {@link LodQuadTree} so having the thread static should be fine */
private static final ThreadPoolExecutor FULL_DATA_RETRIEVAL_QUEUE_THREAD = ThreadUtil.makeSingleThreadPool("LodQuadTree Data Retrieval Queue"); private static final ThreadPoolExecutor FULL_DATA_RETRIEVAL_QUEUE_THREAD = ThreadUtil.makeSingleThreadPool("LodQuadTree Data Retrieval Queue");
@@ -135,7 +139,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
{ {
super(viewDiameterInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL); super(viewDiameterInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus); DEBUG_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus);
this.level = level; this.level = level;
this.fullDataSourceProvider = fullDataSourceProvider; this.fullDataSourceProvider = fullDataSourceProvider;
@@ -973,7 +977,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
//region debugging //region debugging
@Override @Override
public void debugRender(DebugRenderer debugRenderer) public void debugRender(AbstractDebugWireframeRenderer debugRenderer)
{ {
this.populateListWithEnabledRenderSections(this.debugNodeList); this.populateListWithEnabledRenderSections(this.debugNodeList);
@@ -1012,7 +1016,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
int levelHeightRange = (levelMaxY - levelMinY); int levelHeightRange = (levelMaxY - levelMinY);
int maxY = levelMaxY - (levelHeightRange / 2); int maxY = levelMaxY - (levelHeightRange / 2);
debugRenderer.renderBox(new DebugRenderer.Box(renderSection.pos, levelMinY, maxY, 0.05f, color)); debugRenderer.render(new AbstractDebugWireframeRenderer.Box(renderSection.pos, levelMinY, maxY, 0.05f, color));
} }
} }
@@ -1030,7 +1034,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
{ {
LOGGER.info("Shutting down LodQuadTree..."); LOGGER.info("Shutting down LodQuadTree...");
DebugRenderer.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus); DEBUG_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus);
Config.Common.WorldGenerator.enableDistantGeneration.removeListener(this); Config.Common.WorldGenerator.enableDistantGeneration.removeListener(this);
Config.Server.enableServerGeneration.removeListener(this); Config.Server.enableServerGeneration.removeListener(this);
@@ -33,6 +33,7 @@ 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.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.BeaconRenderHandler; import com.seibel.distanthorizons.core.render.renderer.BeaconRenderHandler;
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
@@ -60,6 +61,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
@@ -135,7 +137,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
this.beaconRenderHandler = this.quadTree.beaconRenderHandler; this.beaconRenderHandler = this.quadTree.beaconRenderHandler;
this.beaconBeamRepo = this.level.getBeaconBeamRepo(); this.beaconBeamRepo = this.level.getBeaconBeamRepo();
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus); DEBUG_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus);
} }
//endregion constructor //endregion constructor
@@ -443,9 +445,9 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get()) if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get())
{ {
// show that this position has just been disabled // show that this position has just been disabled
DebugRenderer.makeParticle( DEBUG_RENDERER.makeParticle(
new DebugRenderer.BoxParticle( new AbstractDebugWireframeRenderer.BoxParticle(
new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()), new AbstractDebugWireframeRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()),
0.2, 32f 0.2, 32f
) )
); );
@@ -504,7 +506,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
//region base methods //region base methods
@Override @Override
public void debugRender(DebugRenderer debugRenderer) public void debugRender(AbstractDebugWireframeRenderer debugRenderer)
{ {
Color color = Color.red; Color color = Color.red;
if (this.renderingEnabled) if (this.renderingEnabled)
@@ -530,7 +532,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
int levelHeightRange = (levelMaxY - levelMinY); int levelHeightRange = (levelMaxY - levelMinY);
int maxY = levelMaxY - (levelHeightRange / 2); int maxY = levelMaxY - (levelHeightRange / 2);
debugRenderer.renderBox(new DebugRenderer.Box(this.pos, levelMinY, maxY, 0.01f, color)); debugRenderer.render(new AbstractDebugWireframeRenderer.Box(this.pos, levelMinY, maxY, 0.01f, color));
} }
@Override @Override
@@ -546,14 +548,14 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
@Override @Override
public void close() public void close()
{ {
DebugRenderer.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus); DEBUG_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus);
if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get()) if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get())
{ {
// show a particle for the closed section // show a particle for the closed section
DebugRenderer.makeParticle( DEBUG_RENDERER.makeParticle(
new DebugRenderer.BoxParticle( new AbstractDebugWireframeRenderer.BoxParticle(
new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.RED.darker()), new AbstractDebugWireframeRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.RED.darker()),
0.5, 32f 0.5, 32f
) )
); );
@@ -0,0 +1,323 @@
package com.seibel.distanthorizons.core.render.renderer;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
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.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.PriorityBlockingQueue;
public abstract class AbstractDebugWireframeRenderer implements IBindable
{
protected static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder()
.maxCountPerSecond(1)
.build();
protected static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
protected final RendererLists rendererLists = new RendererLists();
protected final PriorityBlockingQueue<BoxParticle> particles = new PriorityBlockingQueue<>();
// used when rendering
@Deprecated // all rendering should be done in a single pass
protected Mat4f dhMvmProjMatrixThisFrame;
@Deprecated // all rendering should be done in a single pass
protected Vec3f camPosFloatThisFrame;
//===========//
// rendering //
//===========//
//region
public void renderPass(RenderParams renderParams)
{
this.dhMvmProjMatrixThisFrame = new Mat4f(renderParams.dhMvmProjMatrix);
Vec3d camPos = MC_RENDER.getCameraExactPosition();
this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
this.rendererLists.render(this);
// particle rendering
BoxParticle head = null;
while ((head = this.particles.poll()) != null && head.isDead())
{ /* remove dead particles */ }
if (head != null)
{
// re-add the popped off head
this.particles.add(head);
}
}
public abstract void render(Box box);
//endregion
//==============//
// registration //
//==============//
//region
public void makeParticle(BoxParticle particle)
{
if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get())
{
this.particles.add(particle);
}
}
public void register(IDebugRenderable renderable, ConfigEntry<Boolean> config) { this.addRenderer(renderable, config); }
public void addRenderer(IDebugRenderable renderable, ConfigEntry<Boolean> config) { this.rendererLists.addRenderable(renderable, config); }
public void unregister(IDebugRenderable renderable, ConfigEntry<Boolean> config) { this.removeRenderer(renderable, config); }
public void removeRenderer(IDebugRenderable renderable, ConfigEntry<Boolean> config) { this.rendererLists.removeRenderable(renderable, config); }
public void clearRenderables() { this.rendererLists.clearRenderables(); }
//endregion
//================//
// helper classes //
//================//
//region
public static final class Box
{
public Vec3f minPos;
public Vec3f maxPos;
public Color color;
public Box(long pos, float minY, float maxY, float marginPercent, Color color)
{
float edgeOffset = DhSectionPos.getBlockWidth(pos) * marginPercent;
int minBlockPosX = DhSectionPos.getMinCornerBlockX(pos);
int minBlockPosZ = DhSectionPos.getMinCornerBlockZ(pos);
int maxBlockPosX = minBlockPosX + DhSectionPos.getBlockWidth(pos);
int maxBlockPosZ = minBlockPosZ + DhSectionPos.getBlockWidth(pos);
this.minPos = new Vec3f(minBlockPosX + edgeOffset, minY, minBlockPosZ + edgeOffset);
this.maxPos = new Vec3f(maxBlockPosX - edgeOffset, maxY, maxBlockPosZ - edgeOffset);
this.color = color;
}
/** only used for */
public Box(Vec3f minPos, Vec3f maxPos, Color color)
{
this.minPos = minPos;
this.maxPos = maxPos;
this.color = color;
}
}
public static final class BoxParticle implements Comparable<BoxParticle>
{
public Box box;
public long startMsTime;
public long durationInMs;
public float yChange;
private BoxParticle(Box box, long startMsTime, long durationInMs, float yChange)
{
this.box = box;
this.startMsTime = startMsTime;
this.durationInMs = durationInMs;
this.yChange = yChange;
}
public BoxParticle(Box box, double secondDuration, float yChange)
{ this(box, System.currentTimeMillis(), (long) (secondDuration * 1_000), yChange); }
@Override
public int compareTo(@NotNull BoxParticle particle)
{ return Long.compare(this.startMsTime + this.durationInMs, particle.startMsTime + particle.durationInMs); }
/** will change each time it's called based on the yChange value and time */
public Box createNewRenderBox()
{
long nowMs = System.currentTimeMillis();
float percent = (nowMs - this.startMsTime) / (float) this.durationInMs;
percent = (float) Math.pow(percent, 4);
float yDiff = this.yChange * percent;
return new Box(
new Vec3f(this.box.minPos.x, this.box.minPos.y + yDiff, this.box.minPos.z),
new Vec3f(this.box.maxPos.x, this.box.maxPos.y + yDiff, this.box.maxPos.z),
this.box.color);
}
public boolean isDead() { return (System.currentTimeMillis() - this.startMsTime) > this.durationInMs; }
}
protected static class RendererLists
{
public final LinkedList<WeakReference<IDebugRenderable>> generalRenderableList = new LinkedList<>();
private final HashMap<ConfigEntry<Boolean>, LinkedList<WeakReference<IDebugRenderable>>> renderableListByConfig = new HashMap<>();
//==============//
// registration //
//==============//
//region
public void addRenderable(IDebugRenderable renderable, @Nullable ConfigEntry<Boolean> config)
{
synchronized (this)
{
if (config != null)
{
if (!this.renderableListByConfig.containsKey(config))
{
this.renderableListByConfig.put(config, new LinkedList<>());
}
LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
renderableList.add(new WeakReference<>(renderable));
}
else
{
this.generalRenderableList.add(new WeakReference<>(renderable));
}
}
}
public void removeRenderable(IDebugRenderable renderable, @Nullable ConfigEntry<Boolean> config)
{
synchronized (this)
{
if (config != null)
{
if (this.renderableListByConfig.containsKey(config))
{
LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
this.removeRenderableFromInternalList(renderableList, renderable);
}
}
else
{
this.removeRenderableFromInternalList(this.generalRenderableList, renderable);
}
}
}
private void removeRenderableFromInternalList(LinkedList<WeakReference<IDebugRenderable>> rendererList, IDebugRenderable renderable)
{
Iterator<WeakReference<IDebugRenderable>> iterator = rendererList.iterator();
while (iterator.hasNext())
{
WeakReference<IDebugRenderable> renderableRef = iterator.next();
if (renderableRef.get() == null)
{
iterator.remove();
continue;
}
if (renderableRef.get() == renderable)
{
iterator.remove();
return;
}
}
}
public void clearRenderables()
{
for (ConfigEntry<Boolean> config : this.renderableListByConfig.keySet())
{
LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
if (config.get() && renderableList != null)
{
renderableList.clear();
}
}
}
//endregion
//===========//
// rendering //
//===========//
//region
public void render(AbstractDebugWireframeRenderer debugRenderer)
{
this.renderList(debugRenderer, this.generalRenderableList);
for (ConfigEntry<Boolean> config : this.renderableListByConfig.keySet())
{
LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
if (config.get() && renderableList != null && renderableList.size() != 0)
{
this.renderList(debugRenderer, renderableList);
}
}
}
private void renderList(AbstractDebugWireframeRenderer debugRenderer, LinkedList<WeakReference<IDebugRenderable>> rendererList)
{
synchronized (this)
{
try
{
Iterator<WeakReference<IDebugRenderable>> iterator = rendererList.iterator();
while (iterator.hasNext())
{
WeakReference<IDebugRenderable> ref = iterator.next();
IDebugRenderable renderable = ref.get();
if (renderable == null)
{
iterator.remove();
continue;
}
renderable.debugRender(debugRenderer);
}
}
catch (Exception e)
{
RATE_LIMITED_LOGGER.error("Unexpected Debug renderer error, Error: "+e.getMessage(), e);
}
}
}
//endregion
}
//endregion
}
@@ -19,7 +19,6 @@
package com.seibel.distanthorizons.core.render.renderer; package com.seibel.distanthorizons.core.render.renderer;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
@@ -28,6 +27,7 @@ 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.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
@@ -148,6 +148,7 @@ public class BlazeLodRenderer
IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class); IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class);
IMcFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IMcFogRenderer.class); IMcFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IMcFogRenderer.class);
IMcFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IMcFarFadeRenderer.class); IMcFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IMcFarFadeRenderer.class);
AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
@@ -231,7 +232,7 @@ public class BlazeLodRenderer
profiler.popPush("Debug wireframes"); profiler.popPush("Debug wireframes");
// Note: this can be very slow if a lot of boxes are being rendered // Note: this can be very slow if a lot of boxes are being rendered
DebugRenderer.INSTANCE.render(renderParams); debugWireframeRenderer.renderPass(renderParams);
} }
profiler.popPush("Apply to MC"); profiler.popPush("Apply to MC");
@@ -258,8 +259,8 @@ public class BlazeLodRenderer
Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix);
combinedMatrix.multiply(renderParams.dhModelViewMatrix); combinedMatrix.multiply(renderParams.dhModelViewMatrix);
FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); fogRenderer.render(combinedMatrix, renderParams.partialTicks);
} }
} }
} }
@@ -21,6 +21,6 @@ package com.seibel.distanthorizons.core.render.renderer;
public interface IDebugRenderable public interface IDebugRenderable
{ {
void debugRender(DebugRenderer r); void debugRender(AbstractDebugWireframeRenderer r);
} }
@@ -1,33 +0,0 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.core.wrapperInterfaces.render;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.render.renderer.RenderParams;
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
import java.util.Collection;
public interface IMcDebugRenderer extends IBindable
{
void render(RenderParams renderEventParam, Collection<DebugRenderer.BoxParticle> boxCollection);
void render(DebugRenderer.Box box);
}