Merge branch 'distant-horizons-core-main'
This commit is contained in:
@@ -32,7 +32,6 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDebugRendering;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.ERendererMode;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
|
||||
import com.seibel.distanthorizons.core.logging.SpamReducedLogger;
|
||||
@@ -51,8 +50,6 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -92,6 +89,9 @@ public class ClientApi
|
||||
/** Holds any chunks that were loaded before the {@link ClientApi#clientLevelLoadEvent(IClientLevelWrapper)} was fired. */
|
||||
public final HashMap<Pair<IClientLevelWrapper, DhChunkPos>, IChunkWrapper> waitingChunkByClientLevelAndPos = new HashMap<>();
|
||||
|
||||
/** re-set every frame during the opaque rendering stage */
|
||||
private boolean renderingCancelledForThisFrame;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
@@ -450,21 +450,37 @@ public class ClientApi
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
/** Should be called before {@link ClientApi#renderDeferredLods} */
|
||||
public void renderLods(IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
|
||||
{ this.renderLodLayer(levelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, true); }
|
||||
|
||||
/**
|
||||
* Only necessary when Shaders are in use.
|
||||
* Should be called after {@link ClientApi#renderLods}
|
||||
*/
|
||||
public void renderDeferredLods(IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
|
||||
{ this.renderLodLayer(levelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, false); }
|
||||
|
||||
private void renderLodLayer(
|
||||
IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks,
|
||||
boolean renderingDeferredLayer)
|
||||
{
|
||||
if (ModInfo.IS_DEV_BUILD && !this.configOverrideReminderPrinted && MC.playerExists())
|
||||
{
|
||||
this.configOverrideReminderPrinted = true;
|
||||
|
||||
// remind the user that this is a development build
|
||||
MC.sendChatMessage(ModInfo.READABLE_NAME + " experimental build " + ModInfo.VERSION);
|
||||
MC.sendChatMessage("You are running an unsupported version of Distant Horizons!");
|
||||
MC.sendChatMessage("Here be dragons!");
|
||||
this.configOverrideReminderPrinted = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
IProfilerWrapper profiler = MC.getProfiler();
|
||||
profiler.pop(); // get out of "terrain"
|
||||
profiler.push("DH-RenderLevel");
|
||||
|
||||
try
|
||||
{
|
||||
if (!RenderUtil.shouldLodsRender(levelWrapper))
|
||||
@@ -472,29 +488,28 @@ public class ClientApi
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting
|
||||
// (also in RenderUtil)
|
||||
IDhClientWorld dhClientWorld = SharedApi.getIDhClientWorld();
|
||||
if (dhClientWorld == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
IDhClientLevel level = dhClientWorld.getOrLoadClientLevel(levelWrapper);
|
||||
|
||||
|
||||
|
||||
DhApiRenderParam renderEventParam =
|
||||
new DhApiRenderParam(mcProjectionMatrix, mcModelViewMatrix,
|
||||
RenderUtil.createLodProjectionMatrix(mcProjectionMatrix, partialTicks),
|
||||
RenderUtil.createLodModelViewMatrix(mcModelViewMatrix), partialTicks);
|
||||
|
||||
try
|
||||
if (renderingDeferredLayer)
|
||||
{
|
||||
if (Config.Client.Advanced.Debugging.rendererMode.get() == ERendererMode.DEFAULT)
|
||||
{
|
||||
DhApiRenderParam renderEventParam =
|
||||
new DhApiRenderParam(mcProjectionMatrix, mcModelViewMatrix,
|
||||
RenderUtil.createLodProjectionMatrix(mcProjectionMatrix, partialTicks),
|
||||
RenderUtil.createLodModelViewMatrix(mcModelViewMatrix), partialTicks);
|
||||
|
||||
boolean renderingCanceled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, new DhApiBeforeRenderEvent.EventParam(renderEventParam));
|
||||
if (!this.rendererDisabledBecauseOfExceptions && !renderingCanceled)
|
||||
this.renderingCancelledForThisFrame = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, new DhApiBeforeRenderEvent.EventParam(renderEventParam));
|
||||
if (!this.rendererDisabledBecauseOfExceptions && !this.renderingCancelledForThisFrame)
|
||||
{
|
||||
level.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, new DhApiAfterRenderEvent.EventParam(renderEventParam));
|
||||
}
|
||||
}
|
||||
else if (Config.Client.Advanced.Debugging.rendererMode.get() == ERendererMode.DEBUG)
|
||||
@@ -503,22 +518,25 @@ public class ClientApi
|
||||
ClientApi.testRenderer.render();
|
||||
profiler.pop();
|
||||
}
|
||||
// the other rendererMode is DISABLED
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
else
|
||||
{
|
||||
this.rendererDisabledBecauseOfExceptions = true;
|
||||
LOGGER.error("Renderer thrown an uncaught exception: ", e);
|
||||
|
||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons"
|
||||
+ " renderer has encountered an exception!");
|
||||
MC.sendChatMessage("\u00A74Renderer is now disabled to prevent further issues.");
|
||||
MC.sendChatMessage("\u00A74Exception detail: " + e);
|
||||
if (!this.rendererDisabledBecauseOfExceptions && !this.renderingCancelledForThisFrame)
|
||||
{
|
||||
level.renderDeferred(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, new DhApiAfterRenderEvent.EventParam(renderEventParam));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("client level rendering uncaught exception: ", e);
|
||||
this.rendererDisabledBecauseOfExceptions = true;
|
||||
LOGGER.error("Unexpected Renderer error in " + (renderingDeferredLayer ? "Opaque" : "Transparent") + " stage. Error: " + e.getMessage(), e);
|
||||
|
||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons renderer has encountered an exception!");
|
||||
MC.sendChatMessage("\u00A74Renderer is now disabled to prevent further issues.");
|
||||
MC.sendChatMessage("\u00A74Exception detail: " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -529,6 +547,7 @@ public class ClientApi
|
||||
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// DEBUG USE //
|
||||
//=================//
|
||||
|
||||
@@ -573,6 +573,7 @@ public class Config
|
||||
.setPerformance(EConfigEntryPerformance.NONE)
|
||||
.build();
|
||||
|
||||
@Deprecated // TODO remove failed experiment
|
||||
public static ConfigEntry<Boolean> seamlessOverdraw = new ConfigEntry.Builder<Boolean>()
|
||||
.set(false)
|
||||
.comment(""
|
||||
|
||||
+3
-24
@@ -274,27 +274,6 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
// the source isn't empty, this object won't be empty after the method finishes
|
||||
this.isEmpty = false;
|
||||
|
||||
for (int i = 0; i < this.renderDataContainer.length; i += this.verticalDataCount)
|
||||
{
|
||||
int thisGenMode = RenderDataPointUtil.getGenerationMode(this.renderDataContainer[i]);
|
||||
int srcGenMode = RenderDataPointUtil.getGenerationMode(renderSource.renderDataContainer[i]);
|
||||
|
||||
if (srcGenMode == 0)
|
||||
{
|
||||
// the source hasn't been generated, don't write it
|
||||
continue;
|
||||
}
|
||||
|
||||
// this object's column is older than the source's column, update it
|
||||
if (thisGenMode <= srcGenMode)
|
||||
{
|
||||
ColumnArrayView thisColumnArrayView = new ColumnArrayView(this.renderDataContainer, this.verticalDataCount, i, this.verticalDataCount);
|
||||
ColumnArrayView srcColumnArrayView = new ColumnArrayView(renderSource.renderDataContainer, renderSource.verticalDataCount, i, renderSource.verticalDataCount);
|
||||
thisColumnArrayView.copyFrom(srcColumnArrayView);
|
||||
|
||||
this.debugSourceFlags[i / this.verticalDataCount] = renderSource.debugSourceFlags[i / this.verticalDataCount];
|
||||
}
|
||||
}
|
||||
localVersion.incrementAndGet();
|
||||
}
|
||||
/**
|
||||
@@ -361,7 +340,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
FullDataToRenderDataTransformer.convertColumnData(level,
|
||||
sourceBlockX + sourceDataPointBlockWidth * (blockOffsetX + x),
|
||||
sourceBlockZ + sourceDataPointBlockWidth * (blockOffsetZ + z),
|
||||
columnArrayView, fullArrayView, 2);
|
||||
columnArrayView, fullArrayView);
|
||||
dataChanged |= hash != columnArrayView.getDataHash();
|
||||
}
|
||||
}
|
||||
@@ -391,7 +370,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
FullDataToRenderDataTransformer.convertColumnData(level,
|
||||
sourceBlockX + sourceDataPointBlockWidth * relSourceX,
|
||||
sourceBlockZ + sourceDataPointBlockWidth * relSourceZ,
|
||||
columnArrayView, fullArrayView, 2);
|
||||
columnArrayView, fullArrayView);
|
||||
dataChanged |= hash != columnArrayView.getDataHash();
|
||||
}
|
||||
}
|
||||
@@ -415,7 +394,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
SingleColumnFullDataAccessor fullArrayView = chunkDataView.get(0, 0);
|
||||
FullDataToRenderDataTransformer.convertColumnData(level, dataCornerPos.x * sourceDataPointBlockWidth,
|
||||
dataCornerPos.z * sourceDataPointBlockWidth,
|
||||
columnArrayView, fullArrayView, 2);
|
||||
columnArrayView, fullArrayView);
|
||||
dataChanged = hash != columnArrayView.getDataHash();
|
||||
this.fillDebugFlag(relStartX, relStartZ, 1, 1, ColumnRenderSource.DebugSourceFlag.DIRECT);
|
||||
}
|
||||
|
||||
+6
-7
@@ -49,12 +49,9 @@ public final class BufferQuad
|
||||
/** This is both North/South and Up/Down since the merging logic is the same either way */
|
||||
public short widthNorthSouthOrUpDown;
|
||||
|
||||
/**
|
||||
* not final since it may need to be modified to be opaque
|
||||
*
|
||||
* @see LodQuadBuilder#fixTransparencyOverVoid
|
||||
*/
|
||||
public int color;
|
||||
public final int color;
|
||||
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||
public final byte irisBlockMaterialId;
|
||||
|
||||
public final byte skyLight;
|
||||
public final byte blockLight;
|
||||
@@ -66,7 +63,7 @@ public final class BufferQuad
|
||||
|
||||
BufferQuad(
|
||||
short x, short y, short z, short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skylight, byte blockLight,
|
||||
int color, byte irisBlockMaterialId, byte skylight, byte blockLight,
|
||||
EDhDirection direction)
|
||||
{
|
||||
if (widthEastWest == 0 || widthNorthSouthOrUpDown == 0)
|
||||
@@ -80,6 +77,7 @@ public final class BufferQuad
|
||||
this.widthEastWest = widthEastWest;
|
||||
this.widthNorthSouthOrUpDown = widthNorthSouthOrUpDown;
|
||||
this.color = color;
|
||||
this.irisBlockMaterialId = irisBlockMaterialId;
|
||||
this.skyLight = skylight;
|
||||
this.blockLight = blockLight;
|
||||
this.direction = direction;
|
||||
@@ -301,6 +299,7 @@ public final class BufferQuad
|
||||
|
||||
// do the quads' color, light, etc. match?
|
||||
if (this.color != quad.color ||
|
||||
this.irisBlockMaterialId != quad.irisBlockMaterialId ||
|
||||
this.skyLight != quad.skyLight ||
|
||||
this.blockLight != quad.blockLight)
|
||||
{
|
||||
|
||||
+33
-33
@@ -36,7 +36,7 @@ public class ColumnBox
|
||||
LodQuadBuilder builder,
|
||||
short xSize, short ySize, short zSize,
|
||||
short x, short minY, short z,
|
||||
int color, byte skyLight, byte blockLight,
|
||||
int color, byte irisBlockMaterialId, byte skyLight, byte blockLight,
|
||||
long topData, long bottomData, ColumnArrayView[][] adjData)
|
||||
{
|
||||
short maxX = (short) (x + xSize);
|
||||
@@ -102,13 +102,13 @@ public class ColumnBox
|
||||
boolean skipTop = RenderDataPointUtil.doesDataPointExist(topData) && (RenderDataPointUtil.getYMin(topData) == maxY) && !isTopTransparent;
|
||||
if (!skipTop)
|
||||
{
|
||||
builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.UP)), skyLightTop, blockLight);
|
||||
builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.UP)), irisBlockMaterialId, skyLightTop, blockLight);
|
||||
}
|
||||
|
||||
boolean skipBottom = RenderDataPointUtil.doesDataPointExist(bottomData) && (RenderDataPointUtil.getYMax(bottomData) == minY) && !isBottomTransparent;
|
||||
if (!skipBottom)
|
||||
{
|
||||
builder.addQuadDown(x, minY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.DOWN)), skyLightBot, blockLight);
|
||||
builder.addQuadDown(x, minY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.DOWN)), irisBlockMaterialId, skyLightBot, blockLight);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,22 +124,22 @@ public class ColumnBox
|
||||
// add an adjacent face if this is opaque face or transparent over the void
|
||||
if (!isTransparent || overVoid)
|
||||
{
|
||||
builder.addQuadAdj(EDhDirection.NORTH, x, minY, z, xSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.NORTH, x, minY, z, xSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
}
|
||||
else if (adjDataNorth.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], EDhDirection.NORTH, x, minY, z, xSize, ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
color, adjOverlapNorth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], EDhDirection.NORTH, x, minY, z, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
color, adjOverlapNorth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[1], EDhDirection.NORTH, (short) (x + xSize / 2), minY, z, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
color, adjOverlapNorth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -151,22 +151,22 @@ public class ColumnBox
|
||||
if (adjDataSouth == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataSouth.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
color, adjOverlapSouth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], EDhDirection.SOUTH, x, minY, maxZ, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
color, adjOverlapSouth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[1], EDhDirection.SOUTH, (short) (x + xSize / 2), minY, maxZ, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
color, adjOverlapSouth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -178,21 +178,21 @@ public class ColumnBox
|
||||
if (adjDataWest == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(EDhDirection.WEST, x, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.WEST, x, minY, z, zSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataWest.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], EDhDirection.WEST, x, minY, z, zSize, ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
color, adjOverlapWest, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], EDhDirection.WEST, x, minY, z, (short) (zSize / 2), ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
color, adjOverlapWest, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataWest[1], EDhDirection.WEST, x, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
color, adjOverlapWest, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -204,21 +204,21 @@ public class ColumnBox
|
||||
if (adjData[EDhDirection.EAST.ordinal() - 2] == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(EDhDirection.EAST, maxX, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.EAST, maxX, minY, z, zSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataEast.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], EDhDirection.EAST, maxX, minY, z, zSize, ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
color, adjOverlapEast, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], EDhDirection.EAST, maxX, minY, z, (short) (zSize / 2), ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
color, adjOverlapEast, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataEast[1], EDhDirection.EAST, maxX, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
color, adjOverlapEast, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public class ColumnBox
|
||||
private static void makeAdjVerticalQuad(
|
||||
LodQuadBuilder builder, ColumnArrayView adjColumnView, EDhDirection direction,
|
||||
short x, short yMin, short z, short horizontalWidth, short ySize,
|
||||
int color, int debugOverlapColor, byte skyLightTop, byte blockLight,
|
||||
int color, int debugOverlapColor, byte irisBlockMaterialId, byte skyLightTop, byte blockLight,
|
||||
long topData, long bottomData)
|
||||
{
|
||||
color = ColorUtil.applyShade(color, MC.getShade(direction));
|
||||
@@ -236,7 +236,7 @@ public class ColumnBox
|
||||
if (adjColumnView == null || adjColumnView.size == 0 || RenderDataPointUtil.isVoid(adjColumnView.get(0)))
|
||||
{
|
||||
// there isn't any data adjacent to this LOD, add the vertical quad
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ public class ColumnBox
|
||||
|
||||
if (firstFace)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, skyLight, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, irisBlockMaterialId, skyLight, blockLight);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -373,7 +373,7 @@ public class ColumnBox
|
||||
throw new RuntimeException("Loop error");
|
||||
}
|
||||
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, skyLight, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, irisBlockMaterialId, skyLight, blockLight);
|
||||
|
||||
previousAdjDepth = -1;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ public class ColumnBox
|
||||
// The input face is completely inside the adj's face, don't render it
|
||||
if (debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -402,14 +402,14 @@ public class ColumnBox
|
||||
|
||||
if (adjYMax > yMin && debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (adjYMax - yMin), debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (adjYMax - yMin), debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
|
||||
// if this is the only face, use the yMax and break,
|
||||
// if there was another face finish the last one and then break
|
||||
if (firstFace)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
else
|
||||
@@ -423,7 +423,7 @@ public class ColumnBox
|
||||
|
||||
if (previousAdjDepth > adjYMax)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
previousAdjDepth = -1;
|
||||
@@ -448,7 +448,7 @@ public class ColumnBox
|
||||
// the adj data intersects the higher part of the current data
|
||||
if (debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (yMax - adjYMin), debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (yMax - adjYMin), debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
|
||||
// we start the creation of a new face
|
||||
@@ -459,12 +459,12 @@ public class ColumnBox
|
||||
// _______&&: y < depth ______ < yMax
|
||||
if (debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (adjYMax - adjYMin), debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (adjYMax - adjYMin), debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
|
||||
if (firstFace)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
else
|
||||
@@ -474,7 +474,7 @@ public class ColumnBox
|
||||
throw new RuntimeException("Loop error");
|
||||
if (previousAdjDepth > adjYMax)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
previousAdjDepth = -1;
|
||||
@@ -502,12 +502,12 @@ public class ColumnBox
|
||||
{
|
||||
// the input LOD is above all adjacent LODs and won't be affected
|
||||
// by them, add the vertical quad using the input's lighting and height
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, skyLightTop, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, irisBlockMaterialId, skyLightTop, blockLight);
|
||||
}
|
||||
else if (previousAdjDepth != -1)
|
||||
{
|
||||
// We need to finish the last quad.
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, nextTopSkyLight, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, irisBlockMaterialId, nextTopSkyLight, blockLight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -85,17 +85,12 @@ public class CubicLodTemplate
|
||||
break;
|
||||
}
|
||||
case SHOW_DETAIL:
|
||||
case SHOW_GENMODE:
|
||||
{
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[detailLevel];
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
case SHOW_GENMODE:
|
||||
{
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[RenderDataPointUtil.getGenerationMode(data)];
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
case SHOW_OVERLAPPING_QUADS:
|
||||
{
|
||||
color = ColorUtil.WHITE;
|
||||
@@ -112,11 +107,14 @@ public class CubicLodTemplate
|
||||
throw new IllegalArgumentException("Unknown debug mode: " + debugging);
|
||||
}
|
||||
|
||||
byte blockMaterialId = RenderDataPointUtil.getBlockMaterialId(data);
|
||||
|
||||
ColumnBox.addBoxQuadsToBuilder(
|
||||
quadBuilder, // buffer
|
||||
width, ySize, width, // setWidth
|
||||
x, yMin, z, // setOffset
|
||||
color, // setColor
|
||||
blockMaterialId, // irisBlockMaterialId
|
||||
RenderDataPointUtil.getLightSky(data), // setSkyLights
|
||||
fullBright ? 15 : RenderDataPointUtil.getLightBlock(data), // setBlockLights
|
||||
topData, bottomData, adjColumnViews); // setAdjData
|
||||
|
||||
+15
-7
@@ -135,7 +135,7 @@ public class LodQuadBuilder
|
||||
public void addQuadAdj(
|
||||
EDhDirection dir, short x, short y, short z,
|
||||
short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skyLight, byte blockLight)
|
||||
int color, byte irisBlockMaterialId, byte skyLight, byte blockLight)
|
||||
{
|
||||
if (dir == EDhDirection.DOWN)
|
||||
{
|
||||
@@ -147,7 +147,7 @@ public class LodQuadBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skyLight, blockLight, dir);
|
||||
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, irisBlockMaterialId, skyLight, blockLight, dir);
|
||||
ArrayList<BufferQuad> quadList = (this.doTransparency && ColorUtil.getAlpha(color) < 255) ? this.transparentQuads[dir.ordinal()] : this.opaqueQuads[dir.ordinal()];
|
||||
if (!quadList.isEmpty() &&
|
||||
(
|
||||
@@ -163,7 +163,7 @@ public class LodQuadBuilder
|
||||
}
|
||||
|
||||
// XZ
|
||||
public void addQuadUp(short x, short maxY, short z, short widthEastWest, short widthNorthSouthOrUpDown, int color, byte skylight, byte blocklight) // TODO argument names are wrong
|
||||
public void addQuadUp(short x, short maxY, short z, short widthEastWest, short widthNorthSouthOrUpDown, int color, byte irisBlockMaterialId, byte skylight, byte blocklight) // TODO argument names are wrong
|
||||
{
|
||||
// cave culling
|
||||
if (this.skipQuadsWithZeroSkylight && skylight == 0 && maxY < this.skyLightCullingBelow)
|
||||
@@ -171,7 +171,7 @@ public class LodQuadBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
BufferQuad quad = new BufferQuad(x, maxY, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, EDhDirection.UP);
|
||||
BufferQuad quad = new BufferQuad(x, maxY, z, widthEastWest, widthNorthSouthOrUpDown, color, irisBlockMaterialId, skylight, blocklight, EDhDirection.UP);
|
||||
boolean isTransparent = (this.doTransparency && ColorUtil.getAlpha(color) < 255);
|
||||
ArrayList<BufferQuad> quadList = isTransparent ? this.transparentQuads[EDhDirection.UP.ordinal()] : this.opaqueQuads[EDhDirection.UP.ordinal()];
|
||||
|
||||
@@ -190,11 +190,11 @@ public class LodQuadBuilder
|
||||
quadList.add(quad);
|
||||
}
|
||||
|
||||
public void addQuadDown(short x, short y, short z, short width, short wz, int color, byte skylight, byte blocklight)
|
||||
public void addQuadDown(short x, short y, short z, short width, short wz, int color, byte irisBlockMaterialId, byte skylight, byte blocklight)
|
||||
{
|
||||
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
|
||||
return;
|
||||
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, EDhDirection.DOWN);
|
||||
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, irisBlockMaterialId, skylight, blocklight, EDhDirection.DOWN);
|
||||
ArrayList<BufferQuad> qs = (doTransparency && ColorUtil.getAlpha(color) < 255)
|
||||
? transparentQuads[EDhDirection.DOWN.ordinal()] : opaqueQuads[EDhDirection.DOWN.ordinal()];
|
||||
if (!qs.isEmpty() &&
|
||||
@@ -219,6 +219,7 @@ public class LodQuadBuilder
|
||||
int[][] quadBase = DIRECTION_VERTEX_IBO_QUAD[quad.direction.ordinal()];
|
||||
short widthEastWest = quad.widthEastWest;
|
||||
short widthNorthSouth = quad.widthNorthSouthOrUpDown;
|
||||
byte normalIndex = (byte) quad.direction.ordinal();
|
||||
EDhDirection.Axis axis = quad.direction.getAxis();
|
||||
for (int i = 0; i < quadBase.length; i++)
|
||||
{
|
||||
@@ -255,13 +256,15 @@ public class LodQuadBuilder
|
||||
}
|
||||
putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz),
|
||||
quad.hasError ? ColorUtil.RED : quad.color, // TODO add debug config that allows toggling this
|
||||
quad.hasError ? 0 : normalIndex,
|
||||
quad.hasError ? 0 : quad.irisBlockMaterialId,
|
||||
quad.hasError ? 15 : quad.skyLight,
|
||||
quad.hasError ? 15 : quad.blockLight,
|
||||
mx, my, mz);
|
||||
}
|
||||
}
|
||||
|
||||
private void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight, int mx, int my, int mz)
|
||||
private void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte normalIndex, byte irisBlockMaterialId, byte skylight, byte blocklight, int mx, int my, int mz)
|
||||
{
|
||||
skylight %= 16;
|
||||
blocklight %= 16;
|
||||
@@ -292,6 +295,11 @@ public class LodQuadBuilder
|
||||
bb.put(g);
|
||||
bb.put(b);
|
||||
bb.put(a);
|
||||
|
||||
// Block ID and normal index are used by the Iris format
|
||||
bb.put(irisBlockMaterialId);
|
||||
bb.put(normalIndex);
|
||||
bb.putShort((short) 0); // padding to make sure the vertex format as a whole is a multiple of 4
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-8
@@ -134,7 +134,7 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
SingleColumnFullDataAccessor fullArrayView = fullDataSource.get(x, z);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView, 1);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView);
|
||||
|
||||
if (fullArrayView.doesColumnExist())
|
||||
{
|
||||
@@ -190,7 +190,7 @@ public class FullDataToRenderDataTransformer
|
||||
}
|
||||
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView, 1);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView);
|
||||
|
||||
columnSource.fillDebugFlag(x, z, 1, 1, ColumnRenderSource.DebugSourceFlag.SPARSE);
|
||||
if (fullArrayView.doesColumnExist())
|
||||
@@ -229,7 +229,7 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
|
||||
// TODO what does this mean?
|
||||
private static void iterateAndConvert(IDhClientLevel level, int blockX, int blockZ, int genMode, ColumnArrayView column, SingleColumnFullDataAccessor data)
|
||||
private static void iterateAndConvert(IDhClientLevel level, int blockX, int blockZ, ColumnArrayView column, SingleColumnFullDataAccessor data)
|
||||
{
|
||||
boolean avoidSolidBlocks = (Config.Client.Advanced.Graphics.Quality.blocksToIgnore.get() == EBlocksToAvoid.NON_COLLIDING);
|
||||
boolean colorBelowWithAvoidedBlocks = Config.Client.Advanced.Graphics.Quality.tintWithAvoidedBlocks.get();
|
||||
@@ -308,7 +308,7 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
// add the block
|
||||
isVoid = false;
|
||||
long columnData = RenderDataPointUtil.createDataPoint(bottomY + blockHeight, bottomY, color, light, genMode);
|
||||
long columnData = RenderDataPointUtil.createDataPoint(bottomY + blockHeight, bottomY, color, light, block.getIrisBlockMaterialId());
|
||||
column.set(columnOffset, columnData);
|
||||
columnOffset++;
|
||||
}
|
||||
@@ -316,12 +316,12 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
if (isVoid)
|
||||
{
|
||||
column.set(0, RenderDataPointUtil.createVoidDataPoint((byte) genMode));
|
||||
column.set(0, RenderDataPointUtil.createVoidDataPoint());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO what does this mean?
|
||||
public static void convertColumnData(IDhClientLevel level, int blockX, int blockZ, ColumnArrayView columnArrayView, SingleColumnFullDataAccessor fullArrayView, int genMode)
|
||||
public static void convertColumnData(IDhClientLevel level, int blockX, int blockZ, ColumnArrayView columnArrayView, SingleColumnFullDataAccessor fullArrayView)
|
||||
{
|
||||
if (!fullArrayView.doesColumnExist())
|
||||
{
|
||||
@@ -337,12 +337,12 @@ public class FullDataToRenderDataTransformer
|
||||
if (dataTotalLength > columnArrayView.verticalSize())
|
||||
{
|
||||
ColumnArrayView totalColumnData = new ColumnArrayView(new long[dataTotalLength], dataTotalLength, 0, dataTotalLength);
|
||||
iterateAndConvert(level, blockX, blockZ, genMode, totalColumnData, fullArrayView);
|
||||
iterateAndConvert(level, blockX, blockZ, totalColumnData, fullArrayView);
|
||||
columnArrayView.changeVerticalSizeFrom(totalColumnData);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterateAndConvert(level, blockX, blockZ, genMode, columnArrayView, fullArrayView); //Directly use the arrayView since it fits.
|
||||
iterateAndConvert(level, blockX, blockZ, columnArrayView, fullArrayView); //Directly use the arrayView since it fits.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ClientLevelModule implements Closeable
|
||||
@@ -150,7 +149,18 @@ public class ClientLevelModule implements Closeable
|
||||
// either the renderer hasn't been started yet, or is being reloaded
|
||||
return;
|
||||
}
|
||||
ClientRenderState.renderer.drawLODs(ClientRenderState.clientLevelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
ClientRenderState.renderer.drawLods(ClientRenderState.clientLevelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
}
|
||||
|
||||
public void renderDeferred(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
ClientRenderState ClientRenderState = this.ClientRenderStateRef.get();
|
||||
if (ClientRenderState == null)
|
||||
{
|
||||
// either the renderer hasn't been started yet, or is being reloaded
|
||||
return;
|
||||
}
|
||||
ClientRenderState.renderer.drawDeferredLods(ClientRenderState.clientLevelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
}
|
||||
|
||||
public void stopRenderer()
|
||||
|
||||
@@ -89,9 +89,11 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
|
||||
|
||||
@Override
|
||||
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
clientside.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
}
|
||||
{ this.clientside.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); }
|
||||
|
||||
@Override
|
||||
public void renderDeferred(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{ this.clientside.renderDeferred(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -82,9 +82,11 @@ public class DhClientServerLevel extends DhLevel implements IDhClientLevel, IDhS
|
||||
|
||||
@Override
|
||||
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
clientside.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
}
|
||||
{ this.clientside.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); }
|
||||
|
||||
@Override
|
||||
public void renderDeferred(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{ this.clientside.renderDeferred(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); }
|
||||
|
||||
@Override
|
||||
public void serverTick() { this.chunkToLodBuilder.tick(); }
|
||||
|
||||
@@ -31,6 +31,7 @@ public interface IDhClientLevel extends IDhLevel
|
||||
void clientTick();
|
||||
|
||||
void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler);
|
||||
void renderDeferred(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler);
|
||||
|
||||
int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block);
|
||||
|
||||
|
||||
@@ -52,9 +52,8 @@ public abstract class AbstractRenderBuffer implements AutoCloseable
|
||||
|
||||
|
||||
|
||||
public static final int DEFAULT_MEMORY_ALLOCATION = (LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 3) * 8;
|
||||
public static final int QUADS_BYTE_SIZE = LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 4;
|
||||
public static final int MAX_QUADS_PER_BUFFER = (1024 * 1024 * 1) / QUADS_BYTE_SIZE;
|
||||
public static final int QUADS_BYTE_SIZE = LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 4; // TODO what does the 4 represent
|
||||
public static final int MAX_QUADS_PER_BUFFER = (1024 * 1024 * 1) / QUADS_BYTE_SIZE; // TODO what do these multiples represent?
|
||||
public static final int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE;
|
||||
|
||||
|
||||
|
||||
@@ -297,6 +297,9 @@ public class LodRenderSection implements IDebugRenderable
|
||||
}
|
||||
}
|
||||
|
||||
// probably used by Iris
|
||||
public void disposeBufferForRecreate() { this.disposeActiveBuffer = true; }
|
||||
|
||||
|
||||
/**
|
||||
* Try and swap in new render buffer for this section. Note that before this call, there should be no other
|
||||
|
||||
@@ -65,7 +65,12 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
{
|
||||
this.lodQuadTree = lodQuadTree;
|
||||
|
||||
this.f3Message = new F3Screen.DynamicMessage(() -> LodUtil.formatLog("Rendered Buffer Count: " + this.loadedNearToFarBuffers.size()));
|
||||
this.f3Message = new F3Screen.DynamicMessage(() ->
|
||||
{
|
||||
// should never be null, but just in case something goes wrong, then the F3 menu won't break
|
||||
String countText = (this.loadedNearToFarBuffers != null) ? this.loadedNearToFarBuffers.size()+"" : "NULL";
|
||||
return LodUtil.formatLog("Rendered Buffer Count: " + countText);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-3
@@ -106,9 +106,12 @@ public class LodRenderProgram extends ShaderProgram
|
||||
else
|
||||
vao = new VertexAttributePreGL43(); // also binds AbstractVertexAttribute
|
||||
vao.bind();
|
||||
// Now a pos+light.
|
||||
vao.setVertexAttribute(0, 0, VertexPointer.addUnsignedShortsPointer(4, false, true)); // 2+2+2+2
|
||||
vao.setVertexAttribute(0, 1, VertexPointer.addUnsignedBytesPointer(4, true, false)); // +4
|
||||
|
||||
// TODO comment what each attribute represents
|
||||
vao.setVertexAttribute(0, 0, VertexPointer.addUnsignedShortsPointer(4, false, true)); // 2+2+2+2 // TODO probably color, blockpos
|
||||
vao.setVertexAttribute(0, 1, VertexPointer.addUnsignedBytesPointer(4, true, false)); // +4 // TODO ?
|
||||
vao.setVertexAttribute(0, 2, VertexPointer.addUnsignedBytesPointer(4, true, true)); // +4 // TODO probably normal index and Iris block ID
|
||||
|
||||
try
|
||||
{
|
||||
vao.completeAndCheck(vertexByteCount);
|
||||
|
||||
+294
-205
@@ -47,7 +47,6 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -88,6 +87,10 @@ public class LodRenderer
|
||||
private int cachedWidth;
|
||||
private int cachedHeight;
|
||||
|
||||
// Iris sets this to enable a deferred rendering mode.
|
||||
// DO NOT SET THIS TO FINAL!!!
|
||||
private boolean deferTransparentRendering = false;
|
||||
|
||||
|
||||
|
||||
public void setupOffset(DhBlockPos pos) throws IllegalStateException
|
||||
@@ -214,15 +217,64 @@ public class LodRenderer
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// main renderer //
|
||||
//===============//
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
public void drawLODs(IClientLevelWrapper clientLevelWrapper, Mat4f baseModelViewMatrix, Mat4f baseProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
/**
|
||||
* This will draw both opaque and transparent LODs if
|
||||
* {@link LodRenderer#deferTransparentRendering} is disabled,
|
||||
* otherwise it will only render opaque LODs.
|
||||
*/
|
||||
public void drawLods(
|
||||
IClientLevelWrapper clientLevelWrapper,
|
||||
Mat4f baseModelViewMatrix, Mat4f baseProjectionMatrix,
|
||||
float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
this.renderLodPass(
|
||||
clientLevelWrapper,
|
||||
baseModelViewMatrix, baseProjectionMatrix,
|
||||
partialTicks, profiler,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is designed for Iris to be able
|
||||
* to draw water in a deferred rendering context.
|
||||
* It needs to be updated with any major changes,
|
||||
* but shouldn't be activated as per deferWaterRendering.
|
||||
*/
|
||||
public void drawDeferredLods(
|
||||
IClientLevelWrapper clientLevelWrapper,
|
||||
Mat4f baseModelViewMatrix, Mat4f baseProjectionMatrix,
|
||||
float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
this.renderLodPass(
|
||||
clientLevelWrapper,
|
||||
baseModelViewMatrix, baseProjectionMatrix,
|
||||
partialTicks, profiler,
|
||||
true);
|
||||
}
|
||||
|
||||
private void renderLodPass(
|
||||
IClientLevelWrapper clientLevelWrapper,
|
||||
Mat4f baseModelViewMatrix, Mat4f baseProjectionMatrix,
|
||||
float partialTicks, IProfilerWrapper profiler,
|
||||
boolean runningDeferredPass)
|
||||
{
|
||||
//====================//
|
||||
// validate rendering //
|
||||
//====================//
|
||||
|
||||
if (runningDeferredPass && !this.deferTransparentRendering)
|
||||
{
|
||||
return;
|
||||
}
|
||||
boolean renderingFirstPass = !runningDeferredPass;
|
||||
|
||||
if (this.rendererClosed)
|
||||
{
|
||||
EVENT_LOGGER.error("drawLODs() called after close()!");
|
||||
EVENT_LOGGER.error("LOD rendering attempted after the renderer has been shut down!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,19 +290,14 @@ public class LodRenderer
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// rendering setup //
|
||||
//=================//
|
||||
|
||||
try
|
||||
{
|
||||
if (IRIS_ACCESSOR != null && IRIS_ACCESSOR.isRenderingShadowPass())
|
||||
{
|
||||
// Do not do this while Iris compat is being worked on.
|
||||
|
||||
// We do not have a wy to properly render shader shadow pass, since they can
|
||||
// and often do change the projection entirely, as well as the output usage.
|
||||
|
||||
//EVENT_LOGGER.debug("Skipping shadow pass render.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: Since lightmapTexture is changing every frame, it's faster to recreate it than to reuse the old one.
|
||||
ILightMapWrapper lightmap = MC_RENDER.getLightmapWrapper(clientLevelWrapper);
|
||||
if (lightmap == null)
|
||||
@@ -268,133 +315,12 @@ public class LodRenderer
|
||||
}
|
||||
drawSaveGLState.end("drawSaveGLState");
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// draw params setup //
|
||||
//===================//
|
||||
|
||||
profiler.push("LOD draw setup");
|
||||
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setup();
|
||||
|
||||
// shouldn't normally happen, but just in case
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MC_RENDER.getTargetFrameBufferViewportWidth() != this.cachedWidth || MC_RENDER.getTargetFrameBufferViewportHeight() != this.cachedHeight)
|
||||
{
|
||||
this.cachedWidth = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
this.cachedHeight = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
// just resizing the textures doesn't work when Optifine is present,
|
||||
// so recreate the textures with the new size instead
|
||||
this.createColorAndDepthTextures(this.cachedWidth, this.cachedHeight);
|
||||
}
|
||||
|
||||
this.setActiveFramebufferId(this.framebuffer.getId());
|
||||
this.setActiveDepthTextureId(this.depthTexture.getTextureId());
|
||||
if (this.nullableColorTexture != null)
|
||||
{
|
||||
this.setActiveColorTextureId(this.nullableColorTexture.getTextureId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// get MC's color texture
|
||||
int mcColorTextureId = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||
this.setActiveColorTextureId(mcColorTextureId);
|
||||
}
|
||||
// Bind LOD frame buffer
|
||||
this.framebuffer.bind();
|
||||
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// recreating the GL State at this point is necessary in order to get the correct depth texture
|
||||
minecraftGlState = new GLState();
|
||||
if (ENABLE_DUMP_GL_STATE)
|
||||
{
|
||||
tickLogger.debug("Re-saving GL state due to Optifine presence: " + minecraftGlState); //
|
||||
}
|
||||
|
||||
|
||||
// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
|
||||
// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
|
||||
this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F);
|
||||
|
||||
|
||||
// don't clear the color texture, that removes the sky
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
|
||||
// Set OpenGL polygon mode
|
||||
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
||||
if (renderWireframe)
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
//GL32.glDisable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GL32.glEnable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
|
||||
// Enable depth test and depth mask
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
GL32.glDepthMask(true);
|
||||
|
||||
// Disable blending
|
||||
// We render opaque first, then transparent
|
||||
GL32.glDisable(GL32.GL_BLEND);
|
||||
|
||||
/*---------Bind required objects--------*/
|
||||
// Setup LodRenderProgram and the LightmapTexture if it has not yet been done
|
||||
// also binds LightmapTexture, VAO, and ShaderProgram
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setup();
|
||||
}
|
||||
else
|
||||
{
|
||||
LodFogConfig newFogConfig = this.shaderProgram.isShaderUsable();
|
||||
if (newFogConfig != null)
|
||||
{
|
||||
this.shaderProgram.free();
|
||||
this.shaderProgram = new LodRenderProgram(newFogConfig);
|
||||
|
||||
FogShader.INSTANCE.free();
|
||||
FogShader.INSTANCE = new FogShader(newFogConfig);
|
||||
}
|
||||
this.shaderProgram.bind();
|
||||
}
|
||||
|
||||
/*---------Get required data--------*/
|
||||
//int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
//Mat4f modelViewProjectionMatrix = RenderUtil.createCombinedModelViewProjectionMatrix(baseProjectionMatrix, baseModelViewMatrix, partialTicks);
|
||||
|
||||
Mat4f projectionMatrix = RenderUtil.createLodProjectionMatrix(baseProjectionMatrix, partialTicks);
|
||||
|
||||
Mat4f modelViewProjectionMatrix = new Mat4f(projectionMatrix);
|
||||
modelViewProjectionMatrix.multiply(RenderUtil.createLodModelViewMatrix(baseModelViewMatrix));
|
||||
|
||||
/*---------Fill uniform data--------*/
|
||||
this.shaderProgram.fillUniformData(modelViewProjectionMatrix, /*Light map = GL_TEXTURE0*/ 0,
|
||||
MC.getWrappedClientLevel().getMinHeight(), partialTicks);
|
||||
this.setupGLStateAndRenderObjects(minecraftGlState, profiler, modelViewProjectionMatrix, partialTicks, renderingFirstPass);
|
||||
|
||||
lightmap.bind();
|
||||
if (ENABLE_IBO)
|
||||
@@ -402,7 +328,14 @@ public class LodRenderer
|
||||
this.quadIBO.bind();
|
||||
}
|
||||
|
||||
this.bufferHandler.buildRenderListAndUpdateSections(this.getLookVector());
|
||||
if (renderingFirstPass)
|
||||
{
|
||||
this.bufferHandler.buildRenderListAndUpdateSections(this.getLookVector());
|
||||
|
||||
transparencyEnabled = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled;
|
||||
fakeOceanFloor = Config.Client.Advanced.Graphics.Quality.transparency.get().fakeTransparencyEnabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -412,72 +345,74 @@ public class LodRenderer
|
||||
|
||||
LagSpikeCatcher drawLagSpikeCatcher = new LagSpikeCatcher();
|
||||
|
||||
profiler.popPush("LOD Opaque");
|
||||
// TODO: Directional culling
|
||||
this.bufferHandler.renderOpaque(this);
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Ssao.enabled.get())
|
||||
if (!runningDeferredPass)
|
||||
{
|
||||
profiler.popPush("LOD SSAO");
|
||||
SSAORenderer.INSTANCE.render(minecraftGlState, projectionMatrix, partialTicks);
|
||||
}
|
||||
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.setModelViewProjectionMatrix(modelViewProjectionMatrix);
|
||||
FogShader.INSTANCE.render(partialTicks);
|
||||
|
||||
//DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker
|
||||
|
||||
// Render transparent LOD sections (such as water)
|
||||
transparencyEnabled = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled;
|
||||
fakeOceanFloor = Config.Client.Advanced.Graphics.Quality.transparency.get().fakeTransparencyEnabled;
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
|
||||
{
|
||||
profiler.popPush("LOD Transparent");
|
||||
//===================================//
|
||||
// standard (non-deferred) rendering //
|
||||
//===================================//
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
this.bufferHandler.renderTransparent(this);
|
||||
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
|
||||
|
||||
// Disable blending for opaque rendering
|
||||
GL32.glDisable(GL32.GL_BLEND);
|
||||
|
||||
profiler.popPush("LOD Opaque");
|
||||
// TODO: Directional culling
|
||||
this.bufferHandler.renderOpaque(this);
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Ssao.enabled.get())
|
||||
{
|
||||
profiler.popPush("LOD SSAO");
|
||||
SSAORenderer.INSTANCE.render(minecraftGlState, projectionMatrix, partialTicks);
|
||||
}
|
||||
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.setModelViewProjectionMatrix(modelViewProjectionMatrix);
|
||||
FogShader.INSTANCE.render(partialTicks);
|
||||
|
||||
//DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker
|
||||
|
||||
if (!this.deferTransparentRendering)
|
||||
{
|
||||
this.renderTransparentBuffers(profiler, partialTicks);
|
||||
}
|
||||
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// If MC's framebuffer is being used the depth needs to be cleared to prevent rendering on top of MC.
|
||||
// This should only happen when Optifine shaders are being used.
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
drawLagSpikeCatcher.end("LodDraw");
|
||||
|
||||
|
||||
|
||||
//=============================//
|
||||
// Apply to the MC FrameBuffer //
|
||||
//=============================//
|
||||
|
||||
profiler.popPush("LOD Apply");
|
||||
|
||||
GLState dhApplyGlState = new GLState();
|
||||
|
||||
// Copy the LOD framebuffer to Minecraft's framebuffer
|
||||
DhApplyShader.INSTANCE.render(partialTicks);
|
||||
|
||||
dhApplyGlState.restore();
|
||||
|
||||
}
|
||||
|
||||
if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get())
|
||||
else
|
||||
{
|
||||
profiler.popPush("Debug wireframes");
|
||||
// Note: this can be very slow if a lot of boxes are being rendered
|
||||
DebugRenderer.INSTANCE.render(modelViewProjectionMatrix);
|
||||
//====================//
|
||||
// deferred rendering //
|
||||
//====================//
|
||||
|
||||
this.renderTransparentBuffers(profiler, partialTicks);
|
||||
|
||||
drawLagSpikeCatcher.end("LodTranslucentDraw");
|
||||
}
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// If MC's framebuffer is being used the depth needs to be cleared to prevent rendering on top of MC.
|
||||
// This should only happen when Optifine shaders are being used.
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
drawLagSpikeCatcher.end("LodDraw");
|
||||
|
||||
|
||||
|
||||
//=============================//
|
||||
// Apply to the MC FrameBuffer //
|
||||
//=============================//
|
||||
|
||||
profiler.popPush("LOD Apply");
|
||||
|
||||
GLState dhApplyGlState = new GLState();
|
||||
|
||||
// Copy the LOD framebuffer to Minecraft's framebuffer
|
||||
DhApplyShader.INSTANCE.render(partialTicks);
|
||||
|
||||
dhApplyGlState.restore();
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
@@ -487,7 +422,13 @@ public class LodRenderer
|
||||
profiler.popPush("LOD cleanup");
|
||||
LagSpikeCatcher drawCleanup = new LagSpikeCatcher();
|
||||
|
||||
GLProxy.getInstance().runRenderThreadTasks();
|
||||
// GLProxy tasks should be run after all rendering has been done
|
||||
boolean afterEnabledDeferredPass = this.deferTransparentRendering && !renderingFirstPass;
|
||||
boolean afterOnlyRenderingPass = !this.deferTransparentRendering && renderingFirstPass;
|
||||
if (afterEnabledDeferredPass || afterOnlyRenderingPass)
|
||||
{
|
||||
GLProxy.getInstance().runRenderThreadTasks();
|
||||
}
|
||||
|
||||
lightmap.unbind();
|
||||
if (ENABLE_IBO)
|
||||
@@ -497,6 +438,13 @@ public class LodRenderer
|
||||
|
||||
this.shaderProgram.unbind();
|
||||
|
||||
if (renderingFirstPass && Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get())
|
||||
{
|
||||
profiler.popPush("Debug wireframes");
|
||||
// Note: this can be very slow if a lot of boxes are being rendered
|
||||
DebugRenderer.INSTANCE.render(modelViewProjectionMatrix);
|
||||
profiler.popPush("LOD cleanup");
|
||||
}
|
||||
|
||||
minecraftGlState.restore();
|
||||
drawCleanup.end("LodDrawCleanup");
|
||||
@@ -512,15 +460,156 @@ public class LodRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private void renderTransparentBuffers(IProfilerWrapper profiler, float partialTicks)
|
||||
{
|
||||
if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
|
||||
{
|
||||
profiler.popPush("LOD Transparent");
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
this.bufferHandler.renderTransparent(this);
|
||||
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
|
||||
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.render(partialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// Setup Functions //
|
||||
//=================//
|
||||
|
||||
/** Setup all render objects - REQUIRES to be in render thread */
|
||||
private void setup()
|
||||
private void setupGLStateAndRenderObjects(
|
||||
GLState minecraftGlState, IProfilerWrapper profiler,
|
||||
Mat4f modelViewProjectionMatrix,
|
||||
float partialTicks,
|
||||
boolean firstPass)
|
||||
{
|
||||
//===================//
|
||||
// draw params setup //
|
||||
//===================//
|
||||
|
||||
profiler.push("LOD draw setup");
|
||||
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setupRenderObjects();
|
||||
|
||||
// shouldn't normally happen, but just in case
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MC_RENDER.getTargetFrameBufferViewportWidth() != this.cachedWidth || MC_RENDER.getTargetFrameBufferViewportHeight() != this.cachedHeight)
|
||||
{
|
||||
this.cachedWidth = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
this.cachedHeight = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
// just resizing the textures doesn't work when Optifine is present,
|
||||
// so recreate the textures with the new size instead
|
||||
this.createColorAndDepthTextures(this.cachedWidth, this.cachedHeight);
|
||||
}
|
||||
|
||||
this.setActiveFramebufferId(this.framebuffer.getId());
|
||||
this.setActiveDepthTextureId(this.depthTexture.getTextureId());
|
||||
if (this.nullableColorTexture != null)
|
||||
{
|
||||
this.setActiveColorTextureId(this.nullableColorTexture.getTextureId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// get MC's color texture
|
||||
int mcColorTextureId = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||
this.setActiveColorTextureId(mcColorTextureId);
|
||||
}
|
||||
// Bind LOD frame buffer
|
||||
this.framebuffer.bind();
|
||||
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// recreating the GL State at this point is necessary in order to get the correct depth texture
|
||||
minecraftGlState.saveState();
|
||||
if (ENABLE_DUMP_GL_STATE)
|
||||
{
|
||||
tickLogger.debug("Re-saving GL state due to Optifine presence: " + minecraftGlState);
|
||||
}
|
||||
|
||||
|
||||
// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
|
||||
// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
|
||||
this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F);
|
||||
|
||||
|
||||
// don't clear the color texture, that removes the sky
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else if (firstPass)
|
||||
{
|
||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
|
||||
// Set OpenGL polygon mode
|
||||
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
||||
if (renderWireframe)
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
//GL32.glDisable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GL32.glEnable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
|
||||
// Enable depth test and depth mask
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
GL32.glDepthMask(true);
|
||||
|
||||
/*---------Bind required objects--------*/
|
||||
// Setup LodRenderProgram and the LightmapTexture if it has not yet been done
|
||||
// also binds LightmapTexture, VAO, and ShaderProgram
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setupRenderObjects();
|
||||
}
|
||||
else
|
||||
{
|
||||
LodFogConfig newFogConfig = this.shaderProgram.isShaderUsable();
|
||||
if (newFogConfig != null)
|
||||
{
|
||||
this.shaderProgram.free();
|
||||
this.shaderProgram = new LodRenderProgram(newFogConfig);
|
||||
|
||||
FogShader.INSTANCE.free();
|
||||
FogShader.INSTANCE = new FogShader(newFogConfig);
|
||||
}
|
||||
this.shaderProgram.bind();
|
||||
}
|
||||
|
||||
/*---------Get required data--------*/
|
||||
//int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
//Mat4f modelViewProjectionMatrix = RenderUtil.createCombinedModelViewProjectionMatrix(baseProjectionMatrix, baseModelViewMatrix, partialTicks);
|
||||
|
||||
|
||||
/*---------Fill uniform data--------*/
|
||||
this.shaderProgram.fillUniformData(modelViewProjectionMatrix, /*Light map = GL_TEXTURE0*/ 0,
|
||||
MC.getWrappedClientLevel().getMinHeight(), partialTicks);
|
||||
}
|
||||
|
||||
/** Setup all render objects - MUST be called on the render thread */
|
||||
private void setupRenderObjects()
|
||||
{
|
||||
if (this.isSetupComplete)
|
||||
{
|
||||
@@ -647,12 +736,12 @@ public class LodRenderer
|
||||
|
||||
|
||||
|
||||
//======================//
|
||||
// Cleanup Functions //
|
||||
//======================//
|
||||
//===================//
|
||||
// Cleanup Functions //
|
||||
//===================//
|
||||
|
||||
/**
|
||||
* cleanup and free all render objects. MUST be on the render thread
|
||||
* cleanup and free all render objects.
|
||||
* (Many objects are Native, outside of JVM, and need manual cleanup)
|
||||
*/
|
||||
private void cleanup()
|
||||
|
||||
+19
-3
@@ -35,9 +35,11 @@ public class DefaultLodVertexFormats
|
||||
public static final LodVertexFormatElement ELEMENT_UV = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.FLOAT, 2, false);
|
||||
public static final LodVertexFormatElement ELEMENT_LIGHT_MAP_UV = new LodVertexFormatElement(1, LodVertexFormatElement.DataType.SHORT, 2, false);
|
||||
public static final LodVertexFormatElement ELEMENT_NORMAL = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 3, false);
|
||||
public static final LodVertexFormatElement ELEMENT_PADDING = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, true);
|
||||
public static final LodVertexFormatElement ELEMENT_BYTE_PADDING = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, true);
|
||||
|
||||
public static final LodVertexFormatElement ELEMENT_LIGHT = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.UBYTE, 1, false);
|
||||
public static final LodVertexFormatElement ELEMENT_IRIS_MATERIAL_INDEX = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, false);
|
||||
public static final LodVertexFormatElement ELEMENT_IRIS_NORMAL_INDEX = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, false);
|
||||
|
||||
|
||||
public static final LodVertexFormat POSITION = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder().add(ELEMENT_POSITION).build());
|
||||
@@ -48,7 +50,21 @@ public class DefaultLodVertexFormats
|
||||
public static final LodVertexFormat POSITION_COLOR_TEX_LIGHTMAP = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder().add(ELEMENT_POSITION).add(ELEMENT_COLOR).add(ELEMENT_UV).add(ELEMENT_LIGHT_MAP_UV).build());
|
||||
|
||||
public static final LodVertexFormat POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder()
|
||||
.add(ELEMENT_POSITION).add(ELEMENT_PADDING).add(ELEMENT_LIGHT)
|
||||
.add(ELEMENT_COLOR).build());
|
||||
.add(ELEMENT_POSITION)
|
||||
.add(ELEMENT_BYTE_PADDING)
|
||||
.add(ELEMENT_LIGHT)
|
||||
.add(ELEMENT_COLOR)
|
||||
.build());
|
||||
|
||||
public static final LodVertexFormat POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder()
|
||||
.add(ELEMENT_POSITION)
|
||||
.add(ELEMENT_BYTE_PADDING)
|
||||
.add(ELEMENT_LIGHT)
|
||||
.add(ELEMENT_COLOR)
|
||||
.add(ELEMENT_IRIS_MATERIAL_INDEX)
|
||||
.add(ELEMENT_IRIS_NORMAL_INDEX)
|
||||
.add(ELEMENT_BYTE_PADDING)
|
||||
.add(ELEMENT_BYTE_PADDING) // padding is to make sure the format is a multiple of 4
|
||||
.build());
|
||||
|
||||
}
|
||||
|
||||
@@ -138,8 +138,7 @@ public class LodUtil
|
||||
public static final int MAX_ALLOCATABLE_DIRECT_MEMORY = 64 * 1024 * 1024;
|
||||
|
||||
/** the format of data stored in the GPU buffers */
|
||||
public static final LodVertexFormat LOD_VERTEX_FORMAT = DefaultLodVertexFormats.POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT;
|
||||
|
||||
public static final LodVertexFormat LOD_VERTEX_FORMAT = DefaultLodVertexFormats.POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX;
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -202,7 +202,7 @@ public class RenderDataPointReducingList
|
||||
lowerMaxY,
|
||||
RenderDataPointUtil.getLightSky(higherData),
|
||||
RenderDataPointUtil.getLightBlock(higherData),
|
||||
RenderDataPointUtil.getGenerationMode(higherData)
|
||||
RenderDataPointUtil.getBlockMaterialId(higherData)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -829,7 +829,7 @@ public class RenderDataPointReducingList
|
||||
int size = view.size();
|
||||
if (size <= 0)
|
||||
{
|
||||
return RenderDataPointUtil.createVoidDataPoint((byte)(1));
|
||||
return RenderDataPointUtil.createVoidDataPoint();
|
||||
}
|
||||
|
||||
long highest;
|
||||
@@ -849,7 +849,7 @@ public class RenderDataPointReducingList
|
||||
}
|
||||
}
|
||||
//no visible segments, return void.
|
||||
return RenderDataPointUtil.createVoidDataPoint((byte) (1));
|
||||
return RenderDataPointUtil.createVoidDataPoint();
|
||||
}
|
||||
|
||||
//second loop: merge the rest of the segments.
|
||||
@@ -887,7 +887,7 @@ public class RenderDataPointReducingList
|
||||
// so, if we didn't set any data points, add a void data point.
|
||||
if (writeIndex == 0)
|
||||
{
|
||||
view.set(writeIndex++, RenderDataPointUtil.createVoidDataPoint((byte) (1)));
|
||||
view.set(writeIndex++, RenderDataPointUtil.createVoidDataPoint());
|
||||
}
|
||||
|
||||
for (int size = view.size(); writeIndex < size; writeIndex++)
|
||||
|
||||
@@ -24,8 +24,6 @@ import com.seibel.distanthorizons.core.logging.SpamReducedLogger;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.IColumnDataView;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* A helper class that is used to access the data from a long
|
||||
@@ -35,7 +33,7 @@ import java.util.Arrays;
|
||||
*
|
||||
* <strong>DataPoint Format: </strong><br>
|
||||
* <code>
|
||||
* GM: generation mode <br>
|
||||
* BM: block material id <br>
|
||||
* A: color alpha <br>
|
||||
* R: color red <br>
|
||||
* G: color green <br>
|
||||
@@ -46,7 +44,7 @@ import java.util.Arrays;
|
||||
* SL: sky light <br>
|
||||
*
|
||||
* =======Bit layout======= <br>
|
||||
* _ GM GM GM A A A A | <br>
|
||||
* BM BM BM BM A A A A | <br>
|
||||
* R R R R R R R R | <br>
|
||||
* G G G G G G G G | <br>
|
||||
* B B B B B B B B | <br><br>
|
||||
@@ -74,7 +72,7 @@ public class RenderDataPointUtil
|
||||
public final static int ALPHA_DOWNSIZE_SHIFT = 4;
|
||||
|
||||
|
||||
public final static int GEN_TYPE_SHIFT = 60;
|
||||
public final static int IRIS_BLOCK_MATERIAL_ID_SHIFT = 60;
|
||||
|
||||
public final static int COLOR_SHIFT = 32;
|
||||
public final static int BLUE_SHIFT = COLOR_SHIFT;
|
||||
@@ -97,12 +95,11 @@ public class RenderDataPointUtil
|
||||
public final static long HEIGHT_DEPTH_MASK = 0xFFFFFF;
|
||||
public final static long BLOCK_LIGHT_MASK = 0xF;
|
||||
public final static long SKY_LIGHT_MASK = 0xF;
|
||||
public final static long GEN_TYPE_MASK = 0b111;
|
||||
public final static long COMPARE_SHIFT = GEN_TYPE_SHIFT;
|
||||
public final static long IRIS_BLOCK_MATERIAL_ID_MASK = 0xF;
|
||||
public final static long COMPARE_SHIFT = 0b111;
|
||||
|
||||
public final static long HEIGHT_SHIFTED_MASK = HEIGHT_MASK << HEIGHT_SHIFT;
|
||||
public final static long DEPTH_SHIFTED_MASK = DEPTH_MASK << DEPTH_SHIFT;
|
||||
public final static long GEN_TYPE_SHIFTED_MASK = GEN_TYPE_MASK << GEN_TYPE_SHIFT;
|
||||
|
||||
public final static long VOID_SETTER = HEIGHT_SHIFTED_MASK | DEPTH_SHIFTED_MASK;
|
||||
|
||||
@@ -112,27 +109,19 @@ public class RenderDataPointUtil
|
||||
// datapoint manipulation //
|
||||
//========================//
|
||||
|
||||
public static long createVoidDataPoint(byte generationMode)
|
||||
{
|
||||
if (generationMode == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Trying to create void datapoint with genMode 0, which is NOT allowed in DataPoint version 10!");
|
||||
}
|
||||
|
||||
return (generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT;
|
||||
}
|
||||
public static long createVoidDataPoint() { return EMPTY_DATA; }
|
||||
|
||||
public static long createDataPoint(int height, int depth, int color, int lightSky, int lightBlock, int generationMode)
|
||||
public static long createDataPoint(int height, int depth, int color, int lightSky, int lightBlock, int irisBlockMaterialId)
|
||||
{
|
||||
return createDataPoint(
|
||||
ColorUtil.getAlpha(color),
|
||||
ColorUtil.getRed(color),
|
||||
ColorUtil.getGreen(color),
|
||||
ColorUtil.getBlue(color),
|
||||
height, depth, lightSky, lightBlock, generationMode);
|
||||
height, depth, lightSky, lightBlock, irisBlockMaterialId);
|
||||
}
|
||||
|
||||
public static long createDataPoint(int height, int depth, int color, int light, int generationMode)
|
||||
public static long createDataPoint(int height, int depth, int color, int light, int irisBlockMaterialId)
|
||||
{
|
||||
LodUtil.assertTrue(light >= 0 && light < 256, "Raw Light value must be between 0 and 255!");
|
||||
|
||||
@@ -141,28 +130,29 @@ public class RenderDataPointUtil
|
||||
ColorUtil.getRed(color),
|
||||
ColorUtil.getGreen(color),
|
||||
ColorUtil.getBlue(color),
|
||||
height, depth, light % 16, light / 16, generationMode);
|
||||
height, depth,
|
||||
light % 16, light / 16,
|
||||
irisBlockMaterialId);
|
||||
}
|
||||
|
||||
public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int generationMode)
|
||||
public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int irisBlockMaterialId)
|
||||
{
|
||||
LodUtil.assertTrue(generationMode != 0, "Trying to create datapoint with genMode 0, which is NOT allowed in DataPoint version 10!");
|
||||
|
||||
LodUtil.assertTrue(height >= 0 && height < MAX_WORLD_Y_SIZE, "Trying to create datapoint with height[" + height + "] out of range!");
|
||||
LodUtil.assertTrue(depth >= 0 && depth < MAX_WORLD_Y_SIZE, "Trying to create datapoint with depth[" + depth + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(lightSky >= 0 && lightSky < 16, "Trying to create datapoint with lightSky[" + lightSky + "] out of range!");
|
||||
LodUtil.assertTrue(lightBlock >= 0 && lightBlock < 16, "Trying to create datapoint with lightBlock[" + lightBlock + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(irisBlockMaterialId >= 0 && irisBlockMaterialId < 256, "Trying to create datapoint with irisBlockMaterialId[" + irisBlockMaterialId + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(alpha >= 0 && alpha < 256, "Trying to create datapoint with alpha[" + alpha + "] out of range!");
|
||||
LodUtil.assertTrue(red >= 0 && red < 256, "Trying to create datapoint with red[" + red + "] out of range!");
|
||||
LodUtil.assertTrue(green >= 0 && green < 256, "Trying to create datapoint with green[" + green + "] out of range!");
|
||||
LodUtil.assertTrue(blue >= 0 && blue < 256, "Trying to create datapoint with blue[" + blue + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(generationMode >= 0 && generationMode < 8, "Trying to create datapoint with genMode[" + generationMode + "] out of range!");
|
||||
LodUtil.assertTrue(depth <= height, "Trying to create datapoint with depth[" + depth + "] greater than height[" + height + "]!");
|
||||
|
||||
return (long) (alpha >>> ALPHA_DOWNSIZE_SHIFT) << ALPHA_SHIFT
|
||||
long out = (long) (alpha >>> ALPHA_DOWNSIZE_SHIFT) << ALPHA_SHIFT
|
||||
| (red & RED_MASK) << RED_SHIFT
|
||||
| (green & GREEN_MASK) << GREEN_SHIFT
|
||||
| (blue & BLUE_MASK) << BLUE_SHIFT
|
||||
@@ -170,8 +160,10 @@ public class RenderDataPointUtil
|
||||
| (depth & DEPTH_MASK) << DEPTH_SHIFT
|
||||
| (lightBlock & BLOCK_LIGHT_MASK) << BLOCK_LIGHT_SHIFT
|
||||
| (lightSky & SKY_LIGHT_MASK) << SKY_LIGHT_SHIFT
|
||||
| (generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT
|
||||
| (irisBlockMaterialId & IRIS_BLOCK_MATERIAL_ID_MASK) << IRIS_BLOCK_MATERIAL_ID_SHIFT
|
||||
;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static long shiftHeightAndDepth(long dataPoint, short offset)
|
||||
@@ -195,19 +187,8 @@ public class RenderDataPointUtil
|
||||
public static byte getLightSky(long dataPoint) { return (byte) ((dataPoint >>> SKY_LIGHT_SHIFT) & SKY_LIGHT_MASK); }
|
||||
public static byte getLightBlock(long dataPoint) { return (byte) ((dataPoint >>> BLOCK_LIGHT_SHIFT) & BLOCK_LIGHT_MASK); }
|
||||
|
||||
public static byte getGenerationMode(long dataPoint)
|
||||
{
|
||||
byte genMode = (byte) ((dataPoint >>> GEN_TYPE_SHIFT) & GEN_TYPE_MASK);
|
||||
if (warnLogger.canMaybeLog() && doesDataPointExist(dataPoint) && genMode == 0)
|
||||
{
|
||||
warnLogger.warnInc("Existing datapoint with genMode 0 detected! This is invalid in DataPoint version 10!"
|
||||
+ " This may be caused by old data that has not been updated correctly.");
|
||||
return 1;
|
||||
}
|
||||
return (genMode == 0) ? 1 : genMode;
|
||||
}
|
||||
public static byte getBlockMaterialId(long dataPoint) { return (byte) ((dataPoint >>> IRIS_BLOCK_MATERIAL_ID_SHIFT) & IRIS_BLOCK_MATERIAL_ID_MASK); }
|
||||
|
||||
public static long overrideGenerationMode(long current, byte b) { return (current & ~GEN_TYPE_SHIFTED_MASK) | ((b & GEN_TYPE_MASK) << GEN_TYPE_SHIFT); }
|
||||
|
||||
public static boolean isVoid(long dataPoint) { return (((dataPoint >>> DEPTH_SHIFT) & HEIGHT_DEPTH_MASK) == 0); }
|
||||
|
||||
@@ -244,7 +225,7 @@ public class RenderDataPointUtil
|
||||
getGreen(dataPoint) +
|
||||
" BL:" + getLightBlock(dataPoint) +
|
||||
" SL:" + getLightSky(dataPoint) +
|
||||
" G:" + getGenerationMode(dataPoint);
|
||||
" BID:" + getBlockMaterialId(dataPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -39,4 +39,6 @@ public interface IBlockStateWrapper extends IDhApiBlockStateWrapper
|
||||
|
||||
int getLightEmission();
|
||||
|
||||
byte getIrisBlockMaterialId();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user