generic object rendering

This commit is contained in:
James Seibel
2026-03-01 19:32:54 -06:00
parent 200e089a33
commit 3d9ae5f088
22 changed files with 269 additions and 69 deletions
@@ -39,6 +39,7 @@ import com.seibel.distanthorizons.core.sql.repo.ChunkHashRepo;
import com.seibel.distanthorizons.core.util.KeyedLockContainer;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.Nullable;
@@ -118,7 +119,7 @@ public abstract class AbstractDhLevel implements IDhLevel
/** handles any setup that needs the repos to be created */
protected void runRepoReliantSetup()
{
GenericObjectRenderer genericRenderer = this.getGenericRenderer();
IMcGenericRenderer genericRenderer = this.getGenericRenderer();
if (genericRenderer != null)
{
// only client levels can render clouds
@@ -30,7 +30,9 @@ import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree;
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -43,6 +45,7 @@ public class ClientLevelModule implements Closeable, IDataSourceUpdateListenerFu
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
private final IDhClientLevel clientLevel;
@@ -56,7 +59,7 @@ public class ClientLevelModule implements Closeable, IDataSourceUpdateListenerFu
* Destroying the {@link GenericObjectRenderer} would cause any existing bindings to be
* erroneously removed.
*/
public final GenericObjectRenderer genericRenderer = new GenericObjectRenderer();
public final IMcGenericRenderer genericRenderer = WRAPPER_FACTORY.createGenericRenderer();
@@ -42,6 +42,7 @@ import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import org.jetbrains.annotations.NotNull;
@@ -298,7 +299,7 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel
public ISaveStructure getSaveStructure() { return this.saveStructure; }
@Override
public GenericObjectRenderer getGenericRenderer() { return this.clientside.genericRenderer; }
public IMcGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; }
@Override
public RenderBufferHandler getRenderBufferHandler()
{
@@ -29,6 +29,7 @@ import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import org.jetbrains.annotations.Nullable;
@@ -138,7 +139,7 @@ public class DhClientServerLevel extends AbstractDhServerLevel implements IDhCli
@Override
public GenericObjectRenderer getGenericRenderer() { return this.clientside.genericRenderer; }
public IMcGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; }
@Override
public RenderBufferHandler getRenderBufferHandler()
{
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManag
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import org.jetbrains.annotations.Nullable;
@@ -69,7 +70,7 @@ public class DhServerLevel extends AbstractDhServerLevel
//=========//
@Override
public GenericObjectRenderer getGenericRenderer()
public IMcGenericRenderer getGenericRenderer()
{
// server-only levels don't support rendering
return null;
@@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRend
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -92,7 +93,7 @@ public interface IDhLevel extends AutoCloseable, GeneratedFullDataSourceProvider
* Not supported on the server-side.
*/
@Nullable
GenericObjectRenderer getGenericRenderer();
IMcGenericRenderer getGenericRenderer();
/**
* Will return null if the renderer isn't set up yet. <br>
* Not supported on the server-side.
@@ -36,6 +36,7 @@ import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.coreapi.util.StringUtil;
import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -203,7 +204,7 @@ public class F3Screen
}
// Generic rendering
GenericObjectRenderer genericRenderer = level.getGenericRenderer();
IMcGenericRenderer genericRenderer = level.getGenericRenderer();
if (genericRenderer != null)
{
messageList.add(genericRenderer.getVboRenderDebugMenuString());
@@ -44,6 +44,7 @@ import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadTree;
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.coreapi.util.MathUtil;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongIterator;
@@ -141,7 +142,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
this.fullDataSourceProvider = fullDataSourceProvider;
this.blockRenderDistanceDiameter = viewDiameterInBlocks;
GenericObjectRenderer genericObjectRenderer = this.level.getGenericRenderer();
IMcGenericRenderer genericObjectRenderer = this.level.getGenericRenderer();
this.beaconRenderHandler = (genericObjectRenderer != null) ? new BeaconRenderHandler(genericObjectRenderer) : null;
Config.Common.WorldGenerator.enableDistantGeneration.addListener(this);
@@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** AKA Index Buffer TODO RENAME */
public class QuadElementBuffer extends GLElementBuffer
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -51,6 +51,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrap
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
@@ -159,7 +160,7 @@ public class LodRenderer
}
RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler;
GenericObjectRenderer genericRenderer = renderParams.genericRenderer;
IMcGenericRenderer genericRenderer = renderParams.genericRenderer;
ILightMapWrapper lightmap = renderParams.lightmap;
@@ -28,10 +28,12 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper;
@@ -114,7 +116,7 @@ public class McLodRenderer
}
RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler;
//GenericObjectRenderer genericRenderer = renderParams.genericRenderer;
IMcGenericRenderer genericRenderer = renderParams.genericRenderer;
@@ -174,8 +176,8 @@ public class McLodRenderer
// custom objects with SSAO
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
{
//profiler.popPush("Custom Objects");
//genericRenderer.render(renderParams, profiler, true);
profiler.popPush("Custom Objects");
genericRenderer.render(renderParams, profiler, true);
}
// SSAO
@@ -188,8 +190,8 @@ public class McLodRenderer
// custom objects without SSAO
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
{
//profiler.popPush("Custom Objects");
//genericRenderer.render(renderParams, profiler, false);
profiler.popPush("Custom Objects");
genericRenderer.render(renderParams, profiler, false);
}
// combined pass transparent rendering
@@ -239,6 +241,8 @@ public class McLodRenderer
//DebugRenderer.INSTANCE.render(combinedMatrix);
}
lodRenderer.applyToMcTexture();
}
else
{
@@ -328,8 +332,6 @@ public class McLodRenderer
lodRenderer.render(renderEventParam, opaquePass, modelPos, vbos, profilerWrapper);
}
}
lodRenderer.applyToMcTexture();
}
else
{
@@ -19,6 +19,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftCli
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
/**
@@ -41,7 +42,7 @@ public class RenderParams extends DhApiRenderParam
public IClientLevelWrapper clientLevelWrapper;
public ILightMapWrapper lightmap;
public RenderBufferHandler renderBufferHandler;
public GenericObjectRenderer genericRenderer;
public IMcGenericRenderer genericRenderer;
public Vec3d exactCameraPosition;
/** @see DhRenderState#vanillaFogEnabled */
public boolean vanillaFogEnabled;
@@ -36,6 +36,7 @@ import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.NotNull;
@@ -77,7 +78,7 @@ public class BeaconRenderHandler
//=============//
//region
public BeaconRenderHandler(@NotNull GenericObjectRenderer renderer)
public BeaconRenderHandler(@NotNull IMcGenericRenderer renderer)
{
this.activeBeaconBoxRenderGroup = GenericRenderObjectFactory.INSTANCE.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0));
this.activeBeaconBoxRenderGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
@@ -33,6 +33,7 @@ import com.seibel.distanthorizons.core.util.LodUtil;
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.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -80,7 +81,7 @@ public class CloudRenderHandler
= new IDhApiRenderableBoxGroup[(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1][(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1];
private final IDhClientLevel level;
private final GenericObjectRenderer renderer;
private final IMcGenericRenderer renderer;
/** cached array so we don't need to re-create it each frame for each cloud group */
private final Vec3d[] cullingCorners = new Vec3d[]
@@ -102,7 +103,7 @@ public class CloudRenderHandler
//=============//
//region
public CloudRenderHandler(IDhClientLevel level, GenericObjectRenderer renderer)
public CloudRenderHandler(IDhClientLevel level, IMcGenericRenderer renderer)
{
this.level = level;
this.renderer = renderer;
@@ -316,16 +317,16 @@ public class CloudRenderHandler
return;
}
if (!this.renderer.getInstancedRenderingAvailable())
{
if (!this.disabledWarningLogged)
{
this.disabledWarningLogged = true;
LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled.");
}
boxGroup.setActive(false);
return;
}
//if (!this.renderer.getInstancedRenderingAvailable())
//{
// if (!this.disabledWarningLogged)
// {
// this.disabledWarningLogged = true;
// LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled.");
// }
// boxGroup.setActive(false);
// return;
//}
IClientLevelWrapper clientLevelWrapper = this.level.getClientLevelWrapper();
if (clientLevelWrapper == null)
@@ -38,12 +38,14 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer;
import com.seibel.distanthorizons.core.render.renderer.RenderParams;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
import com.seibel.distanthorizons.coreapi.ModInfo;
@@ -63,7 +65,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @see IDhApiCustomRenderRegister
* @see DhApiRenderableBox
*/
public class GenericObjectRenderer implements IDhApiCustomRenderRegister
public class GenericObjectRenderer implements IMcGenericRenderer
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -386,7 +388,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
* if true that means this render call is happening before the SSAO pass
* and any objects rendered in this pass will have SSAO applied to them.
*/
public void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
@Override
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
{
// render setup //
profiler.push("setup");
@@ -472,7 +475,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
boxGroup.tryUpdateInstancedDataAsync();
// skip groups that haven't been uploaded yet
if (boxGroup.instancedVbos.state != InstancedVboContainer.EState.RENDER)
if (boxGroup.instancedVbos.getState() != InstancedVboContainer.EState.RENDER)
{
continue;
}
@@ -554,27 +557,29 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// Bind instance data //
profiler.popPush("binding");
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.color);
InstancedVboContainer container = (InstancedVboContainer)(boxGroup.instancedVbos);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color);
GL32.glEnableVertexAttribArray(1);
GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0);
this.vertexAttribDivisor(1, 1);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.scale);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.scale);
GL32.glEnableVertexAttribArray(2);
this.vertexAttribDivisor(2, 1);
GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.chunkPos);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.chunkPos);
GL32.glEnableVertexAttribArray(3);
this.vertexAttribDivisor(3, 1);
GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.subChunkPos);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.subChunkPos);
GL32.glEnableVertexAttribArray(4);
this.vertexAttribDivisor(4, 1);
GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.material);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.material);
GL32.glEnableVertexAttribArray(5);
this.vertexAttribDivisor(5, 1);
GL32.glVertexAttribIPointer(5, 1, GL32.GL_BYTE, Byte.BYTES, 0);
@@ -582,9 +587,9 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// Draw instanced
profiler.popPush("render");
if (boxGroup.instancedVbos.uploadedBoxCount > 0)
if (container.uploadedBoxCount > 0)
{
GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, boxGroup.instancedVbos.uploadedBoxCount);
GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, container.uploadedBoxCount);
}
@@ -0,0 +1,38 @@
package com.seibel.distanthorizons.core.render.renderer.generic;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import java.util.List;
public interface IInstancedVboContainer extends AutoCloseable
{
void uploadDataToGpu();
void updateVertexData(List<DhApiRenderableBox> uploadBoxList);
EState getState();
void setState(EState state);
@Override
void close();
//================//
// helper classes //
//================//
//region
enum EState
{
NEW,
UPDATING_DATA,
READY_TO_UPLOAD,
RENDER,
ERROR,
}
//endregion
}
@@ -17,7 +17,7 @@ import java.util.List;
*
* @see RenderableBoxGroup
*/
public class InstancedVboContainer implements AutoCloseable
public class InstancedVboContainer implements IInstancedVboContainer
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -40,7 +40,11 @@ public class InstancedVboContainer implements AutoCloseable
public int uploadedBoxCount = 0;
public EState state = EState.NEW;
private EState state = EState.NEW;
@Override
public EState getState() { return this.state; }
@Override
public void setState(EState state) { this.state = state; }
@@ -171,23 +175,6 @@ public class InstancedVboContainer implements AutoCloseable
//================//
// helper classes //
//================//
//region
public enum EState
{
NEW,
UPDATING_DATA,
READY_TO_UPLOAD,
RENDER,
ERROR,
}
//endregion
}
@@ -12,6 +12,7 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.jetbrains.annotations.Nullable;
@@ -35,6 +36,7 @@ public class RenderableBoxGroup
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
public static final AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0);
@@ -67,9 +69,9 @@ public class RenderableBoxGroup
public Consumer<DhApiRenderParam> afterRenderFunc;
// instance data
public InstancedVboContainer instancedVbos = new InstancedVboContainer();
public IInstancedVboContainer instancedVbos = WRAPPER_FACTORY.createInstancedVboContainer();
/** double buffering for thread safety and to prevent locking the render thread during update */
private InstancedVboContainer altInstancedVbos = new InstancedVboContainer();
private IInstancedVboContainer altInstancedVbos = WRAPPER_FACTORY.createInstancedVboContainer();
@@ -195,12 +197,12 @@ public class RenderableBoxGroup
public void tryUpdateInstancedDataAsync()
{
// if the alt container is done, swap it in
if (this.altInstancedVbos.state == InstancedVboContainer.EState.READY_TO_UPLOAD)
if (this.altInstancedVbos.getState() == InstancedVboContainer.EState.READY_TO_UPLOAD)
{
this.altInstancedVbos.uploadDataToGpu();
// swap VBO references for rendering
InstancedVboContainer temp = this.instancedVbos;
IInstancedVboContainer temp = this.instancedVbos;
this.instancedVbos = this.altInstancedVbos;
this.altInstancedVbos = temp;
@@ -224,15 +226,15 @@ public class RenderableBoxGroup
}
// if the alternate container is already updating, don't double-queue it
if (this.altInstancedVbos.state == InstancedVboContainer.EState.UPDATING_DATA)
if (this.altInstancedVbos.getState() == InstancedVboContainer.EState.UPDATING_DATA)
{
return;
}
this.altInstancedVbos.state = InstancedVboContainer.EState.UPDATING_DATA;
this.altInstancedVbos.setState(InstancedVboContainer.EState.UPDATING_DATA);
this.altInstancedVbos.tryRunRenderThreadSetup();
//this.altInstancedVbos.tryRunRenderThreadSetup();
// copy over the box list so we can upload without concurrent modification issues
this.uploadBoxList.clear();
@@ -252,14 +254,14 @@ public class RenderableBoxGroup
catch (Exception e)
{
LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e);
this.altInstancedVbos.state = InstancedVboContainer.EState.ERROR;
this.altInstancedVbos.setState(InstancedVboContainer.EState.ERROR);
}
});
}
catch (RejectedExecutionException ignore)
{
// the executor was shut down, it should be back up shortly and able to accept new jobs
this.altInstancedVbos.state = InstancedVboContainer.EState.NEW;
this.altInstancedVbos.setState(InstancedVboContainer.EState.NEW);
}
}
@@ -341,7 +343,7 @@ public class RenderableBoxGroup
//region
@Override
public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:["+this.originBlockPos.x+","+this.originBlockPos.y+","+this.originBlockPos.z+"], size:["+this.size()+"], active:["+this.active+"]"; }
public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:[("+this.originBlockPos.x+", "+this.originBlockPos.y+", "+this.originBlockPos.z+")], size:["+this.size()+"], active:["+this.active+"]"; }
@Override
public void close()
@@ -21,8 +21,10 @@ package com.seibel.distanthorizons.core.wrapperInterfaces;
import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.render.renderer.generic.IInstancedVboContainer;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
@@ -107,4 +109,8 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable
IVertexBufferWrapper createVboWrapper();
IInstancedVboContainer createInstancedVboContainer();
IMcGenericRenderer createGenericRenderer();
}
@@ -0,0 +1,34 @@
/*
* 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.api.interfaces.render.IDhApiCustomRenderRegister;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.core.render.renderer.RenderParams;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
public interface IMcGenericRenderer extends IDhApiCustomRenderRegister, IBindable
{
void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao);
String getVboRenderDebugMenuString();
}
@@ -0,0 +1,10 @@
#version 150 core
in vec4 fColor;
out vec4 fragColor;
void main()
{
fragColor = fColor;
}
@@ -0,0 +1,101 @@
#version 330 core
//layout (location = 1) in vec4 aColor; // RGBA_FLOAT_COLOR
//layout (location = 2) in vec3 aScale; // VEC3_SCALE
//layout (location = 3) in ivec3 aTranslateChunk; // IVEC3_SCALE
//layout (location = 4) in vec3 aTranslateSubChunk; // VEC3_SCALE
//layout (location = 5) in int aMaterial; // IRIS_MATERIAL
//uniform sampler2D /*vec4*/ uColorMap;
//uniform sampler2D /*vec3*/ uScaleMap;
//uniform sampler2D /*int*/ uTranslateChunkXMap;
//uniform sampler2D /*int*/ uTranslateChunkYMap;
//uniform sampler2D /*int*/ uTranslateChunkZMap;
//uniform sampler2D /*vec3*/ uTranslateSubChunkMap;
//uniform sampler2D /*int*/ uMaterialMap;
//
//in vec3 vPosition;
in vec3 vPosition;
in vec4 aColor; // RGBA_FLOAT_COLOR
in int aMaterial; // IRIS_MATERIAL
layout (std140) uniform vertUniformBlock
{
ivec3 uOffsetChunk;
vec3 uOffsetSubChunk;
ivec3 uCameraPosChunk;
vec3 uCameraPosSubChunk;
mat4 uProjectionMvm;
int uSkyLight;
int uBlockLight;
float uNorthShading;
float uSouthShading;
float uEastShading;
float uWestShading;
float uTopShading;
float uBottomShading;
};
uniform sampler2D uLightMap;
out vec4 fColor;
void main()
{
vec3 aScale = vec3(1);
if (aMaterial == 999)
{
aScale = vec3(2);
}
// vec4 aColor = texelFetch(uColorMap, ivec2(gl_InstanceID,0), 0);
// vec3 aScale = texelFetch(uScaleMap, ivec2(gl_InstanceID,0), 0).xyz;
//
// float chunkX = int(texelFetch(uTranslateChunkXMap, ivec2(gl_InstanceID,0), 0).x);
// float chunkY = int(texelFetch(uTranslateChunkYMap, ivec2(gl_InstanceID,0), 0).x);
// float chunkZ = int(texelFetch(uTranslateChunkZMap, ivec2(gl_InstanceID,0), 0).x);
// ivec3 aTranslateChunk = ivec3(chunkX, chunkY, chunkZ);
//
// vec3 aTranslateSubChunk = texelFetch(uTranslateSubChunkMap, ivec2(gl_InstanceID,0), 0).xyz;
// int aMaterial = int(texelFetch(uMaterialMap, ivec2(gl_InstanceID,0), 0).x);
// aTranslate - moves the vertex to the boxGroup's relative position
// uOffset - moves the vertex to the boxGroup's world position
// uCameraPos - moves the vertex into camera space
vec3 trans = (uOffsetChunk - uCameraPosChunk) * 16.0f;
// separate float and int values are to fix percission loss at extreme distances from the origin (IE 10,000,000+)
// luckily large translate values minus large cameraPos generally equal values that cleanly fit in a float
trans += (uOffsetSubChunk - uCameraPosSubChunk);
// combination translation and scaling matrix
mat4 transform = mat4(
aScale.x, 0.0, 0.0, 0.0,
0.0, aScale.y, 0.0, 0.0,
0.0, 0.0, aScale.z, 0.0,
trans.x, trans.y, trans.z, 1.0
);
gl_Position = uProjectionMvm * transform * vec4(vPosition, 1.0);
float blockLight = (float(uBlockLight)+0.5) / 16.0;
float skyLight = (float(uSkyLight)+0.5) / 16.0;
vec4 lightColor = vec4(texture(uLightMap, vec2(blockLight, skyLight)).xyz, 1.0);
fColor = lightColor * aColor;
int vertexIndex = gl_VertexID % 24;
// apply directional shading
if (vertexIndex >= 0 && vertexIndex < 4) { fColor.rgb *= uNorthShading; }
else if (vertexIndex >= 4 && vertexIndex < 8) { fColor.rgb *= uSouthShading; }
else if (vertexIndex >= 8 && vertexIndex < 12) { fColor.rgb *= uWestShading; }
else if (vertexIndex >= 12 && vertexIndex < 16) { fColor.rgb *= uEastShading; }
else if (vertexIndex >= 16 && vertexIndex < 20) { fColor.rgb *= uBottomShading; }
else if (vertexIndex >= 20 && vertexIndex < 24) { fColor.rgb *= uTopShading; }
}