Merge branch 'main' of https://gitlab.com/jeseibel/distant-horizons-core
This commit is contained in:
+1
-1
@@ -52,7 +52,7 @@ public class DhApiWorldGenerationConfig implements IDhApiWorldGenerationConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<ELightGenerationMode> lightingEngine()
|
||||
{ return new DhApiConfigValue<>(WorldGenerator.lightingEngine); }
|
||||
{ return new DhApiConfigValue<>(WorldGenerator.worldGenLightingEngine); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.world.*;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.core.level.IDhClientLevel;
|
||||
@@ -133,29 +134,41 @@ public class ClientApi
|
||||
}
|
||||
}
|
||||
|
||||
public void clientChunkLoadEvent(IChunkWrapper chunk, IClientLevelWrapper level)
|
||||
public void clientChunkLoadEvent(IChunkWrapper chunk, IClientLevelWrapper level) { this.applyChunkUpdate(chunk, level); }
|
||||
public void clientChunkSaveEvent(IChunkWrapper chunk, IClientLevelWrapper level) { this.applyChunkUpdate(chunk, level); }
|
||||
private void applyChunkUpdate(IChunkWrapper chunk, IClientLevelWrapper level)
|
||||
{
|
||||
if (SharedApi.getEnvironment() == EWorldEnvironment.Client_Only)
|
||||
// if the user is in a single player world the chunk updates are handled on the server side
|
||||
if (SharedApi.getEnvironment() != EWorldEnvironment.Client_Only)
|
||||
{
|
||||
IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level);
|
||||
if (dhLevel != null)
|
||||
return;
|
||||
}
|
||||
|
||||
// only continue if the level is still loaded
|
||||
IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level);
|
||||
if (dhLevel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
dhLevel.updateChunkAsync(chunk);
|
||||
|
||||
// also update any existing neighbour chunks so lighting changes are propagated correctly
|
||||
for (int xOffset = -1; xOffset <= 1; xOffset++)
|
||||
{
|
||||
for (int zOffset = -1; zOffset <= 1; zOffset++)
|
||||
{
|
||||
dhLevel.updateChunkAsync(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clientChunkSaveEvent(IChunkWrapper chunk, IClientLevelWrapper level)
|
||||
{
|
||||
if (SharedApi.getEnvironment() == EWorldEnvironment.Client_Only)
|
||||
{
|
||||
IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level);
|
||||
if (dhLevel != null)
|
||||
{
|
||||
dhLevel.updateChunkAsync(chunk);
|
||||
DhChunkPos neighbourPos = new DhChunkPos(chunk.getChunkPos().x+xOffset, chunk.getChunkPos().z+zOffset);
|
||||
IChunkWrapper neighbourChunk = dhLevel.getLevelWrapper().tryGetChunk(neighbourPos);
|
||||
if (neighbourChunk != null)
|
||||
{
|
||||
dhLevel.updateChunkAsync(neighbourChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void clientLevelUnloadEvent(IClientLevelWrapper level)
|
||||
{
|
||||
|
||||
@@ -644,19 +644,28 @@ public class Config
|
||||
*/
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<ELightGenerationMode> lightingEngine = new ConfigEntry.Builder<ELightGenerationMode>()
|
||||
.set(ELightGenerationMode.MINECRAFT)
|
||||
public static ConfigEntry<ELightGenerationMode> worldGenLightingEngine = new ConfigEntry.Builder<ELightGenerationMode>()
|
||||
.set(ELightGenerationMode.DISTANT_HORIZONS)
|
||||
.comment(""
|
||||
+ " How should distant generation chunk lighting be generated? \n"
|
||||
+ " How should Distant Horizons world generation chunk lighting be handled? \n"
|
||||
+ "\n"
|
||||
+ ELightGenerationMode.MINECRAFT + ": Use Minecraft's lighting engine to generate chunk lighting. \n"
|
||||
+ " Generally higher quality; but may crash MC's lighting engine if there is an issue. \n"
|
||||
+ ELightGenerationMode.DISTANT_HORIZONS + ": Uses Distant Horizons' lighting engine to estimate chunk lighting. \n"
|
||||
+ " Generally lower quality; but more stable for large numbers of world generator threads. \n"
|
||||
+ ELightGenerationMode.DISTANT_HORIZONS + ": Uses Distant Horizons' lighting engine to generate chunk lighting. \n"
|
||||
+ " May not exactly match MC's, but is more stable for large numbers of world generator threads. \n"
|
||||
+ "\n"
|
||||
+ "This will effect generation speed, but not rendering performance.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Integer> worldGenerationTimeoutLengthInSeconds = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(5, 60, 60*10/*10 minutes*/)
|
||||
.comment(""
|
||||
+ "How long should a world generator thread run for before timing out? \n"
|
||||
+ "Note: If you are experiencing timeout errors it is better to lower your CPU usage first \n"
|
||||
+ "via the thread config before changing this value. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
// deprecated and not implemented, can be made public if we ever re-implement it
|
||||
@Deprecated
|
||||
private static ConfigEntry<EGenerationPriority> generationPriority = new ConfigEntry.Builder<EGenerationPriority>()
|
||||
|
||||
+5
-2
@@ -25,6 +25,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
*/
|
||||
public class FullDataPointIdMap
|
||||
{
|
||||
public static final String SEPARATOR_STRING = "_DH-BSW_";
|
||||
|
||||
|
||||
// FIXME: Improve performance maybe?
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
@@ -157,11 +160,11 @@ public class FullDataPointIdMap
|
||||
}
|
||||
|
||||
|
||||
public String serialize() { return this.biome.serialize() + " " + this.blockState.serialize(); }
|
||||
public String serialize() { return this.biome.serialize() + SEPARATOR_STRING + this.blockState.serialize(); }
|
||||
|
||||
public static Entry deserialize(String str) throws IOException, InterruptedException
|
||||
{
|
||||
String[] stringArray = str.split(" ");
|
||||
String[] stringArray = str.split(SEPARATOR_STRING);
|
||||
if (stringArray.length != 2)
|
||||
{
|
||||
throw new IOException("Failed to deserialize BiomeBlockStateEntry");
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
|
||||
/** measured in dataPoints */
|
||||
public static final int WIDTH = BitShiftUtil.powerOfTwo(SECTION_SIZE_OFFSET);
|
||||
|
||||
public static final byte DATA_FORMAT_VERSION = 0;
|
||||
public static final byte DATA_FORMAT_VERSION = 1;
|
||||
/** written to the binary file to mark what {@link IFullDataSource} the binary file corresponds to */
|
||||
public static final long TYPE_ID = "CompleteFullDataSource".hashCode();
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo
|
||||
/** aka max detail level */
|
||||
public static final byte MAX_SECTION_DETAIL = SECTION_SIZE_OFFSET + SPARSE_UNIT_DETAIL;
|
||||
|
||||
public static final byte DATA_FORMAT_VERSION = 0;
|
||||
public static final byte DATA_FORMAT_VERSION = 1;
|
||||
/** written to the binary file to mark what {@link IFullDataSource} the binary file corresponds to */
|
||||
public static final long TYPE_ID = "HighDetailIncompleteFullDataSource".hashCode();
|
||||
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp
|
||||
/** measured in dataPoints */
|
||||
public static final int WIDTH = BitShiftUtil.powerOfTwo(SECTION_SIZE_OFFSET);
|
||||
|
||||
public static final byte DATA_FORMAT_VERSION = 0; // TODO rename to data format version
|
||||
public static final byte DATA_FORMAT_VERSION = 1;
|
||||
/** written to the binary file to mark what {@link IFullDataSource} the binary file corresponds to */
|
||||
public static final long TYPE_ID = "LowDetailIncompleteFullDataSource".hashCode();
|
||||
|
||||
|
||||
+3
-3
@@ -20,8 +20,8 @@
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
|
||||
/** Represents a render-able quad. */
|
||||
public final class BufferQuad
|
||||
@@ -56,7 +56,7 @@ public final class BufferQuad
|
||||
|
||||
public final byte skyLight;
|
||||
public final byte blockLight;
|
||||
public final ELodDirection direction;
|
||||
public final EDhDirection direction;
|
||||
|
||||
public boolean hasError = false;
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class BufferQuad
|
||||
|
||||
BufferQuad(short x, short y, short z, short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skylight, byte blockLight,
|
||||
ELodDirection direction)
|
||||
EDhDirection direction)
|
||||
{
|
||||
if (widthEastWest == 0 || widthNorthSouthOrUpDown == 0)
|
||||
throw new IllegalArgumentException("Size 0 quad!");
|
||||
|
||||
+25
-25
@@ -20,12 +20,12 @@
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderDataPointUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
|
||||
public class ColumnBox
|
||||
@@ -100,13 +100,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(ELodDirection.UP)), skyLightTop, blockLight);
|
||||
builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.UP)), 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(ELodDirection.DOWN)), skyLightBot, blockLight);
|
||||
builder.addQuadDown(x, minY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.DOWN)), skyLightBot, blockLight);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,28 +115,28 @@ public class ColumnBox
|
||||
// TODO merge duplicate code
|
||||
//NORTH face vertex creation
|
||||
{
|
||||
ColumnArrayView[] adjDataNorth = adjData[ELodDirection.NORTH.ordinal() - 2]; // TODO can we use something other than ordinal-2?
|
||||
ColumnArrayView[] adjDataNorth = adjData[EDhDirection.NORTH.ordinal() - 2]; // TODO can we use something other than ordinal-2?
|
||||
int adjOverlapNorth = ColorUtil.INVISIBLE;
|
||||
if (adjDataNorth == null)
|
||||
{
|
||||
// add an adjacent face if this is opaque face or transparent over the void
|
||||
if (!isTransparent || overVoid)
|
||||
{
|
||||
builder.addQuadAdj(ELodDirection.NORTH, x, minY, z, xSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.NORTH, x, minY, z, xSize, ySize, color, (byte) 15, blockLight);
|
||||
}
|
||||
}
|
||||
else if (adjDataNorth.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], ELodDirection.NORTH, x, minY, z, xSize, ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], EDhDirection.NORTH, x, minY, z, xSize, ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], ELodDirection.NORTH, x, minY, z, (short) (xSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], EDhDirection.NORTH, x, minY, z, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[1], ELodDirection.NORTH, (short) (x + xSize / 2), minY, z, (short) (xSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[1], EDhDirection.NORTH, (short) (x + xSize / 2), minY, z, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
@@ -144,26 +144,26 @@ public class ColumnBox
|
||||
|
||||
//SOUTH face vertex creation
|
||||
{
|
||||
ColumnArrayView[] adjDataSouth = adjData[ELodDirection.SOUTH.ordinal() - 2];
|
||||
ColumnArrayView[] adjDataSouth = adjData[EDhDirection.SOUTH.ordinal() - 2];
|
||||
int adjOverlapSouth = ColorUtil.INVISIBLE;
|
||||
if (adjDataSouth == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(ELodDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataSouth.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], ELodDirection.SOUTH, x, minY, maxZ, xSize, ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], ELodDirection.SOUTH, x, minY, maxZ, (short) (xSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], EDhDirection.SOUTH, x, minY, maxZ, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[1], ELodDirection.SOUTH, (short) (x + xSize / 2), minY, maxZ, (short) (xSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[1], EDhDirection.SOUTH, (short) (x + xSize / 2), minY, maxZ, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
@@ -171,25 +171,25 @@ public class ColumnBox
|
||||
|
||||
//WEST face vertex creation
|
||||
{
|
||||
ColumnArrayView[] adjDataWest = adjData[ELodDirection.WEST.ordinal() - 2];
|
||||
ColumnArrayView[] adjDataWest = adjData[EDhDirection.WEST.ordinal() - 2];
|
||||
int adjOverlapWest = ColorUtil.INVISIBLE;
|
||||
if (adjDataWest == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(ELodDirection.WEST, x, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.WEST, x, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataWest.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], ELodDirection.WEST, x, minY, z, zSize, ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], EDhDirection.WEST, x, minY, z, zSize, ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], ELodDirection.WEST, x, minY, z, (short) (zSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], EDhDirection.WEST, x, minY, z, (short) (zSize / 2), ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataWest[1], ELodDirection.WEST, x, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataWest[1], EDhDirection.WEST, x, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
@@ -197,25 +197,25 @@ public class ColumnBox
|
||||
|
||||
//EAST face vertex creation
|
||||
{
|
||||
ColumnArrayView[] adjDataEast = adjData[ELodDirection.EAST.ordinal() - 2];
|
||||
ColumnArrayView[] adjDataEast = adjData[EDhDirection.EAST.ordinal() - 2];
|
||||
int adjOverlapEast = ColorUtil.INVISIBLE;
|
||||
if (adjData[ELodDirection.EAST.ordinal() - 2] == null)
|
||||
if (adjData[EDhDirection.EAST.ordinal() - 2] == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(ELodDirection.EAST, maxX, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.EAST, maxX, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataEast.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], ELodDirection.EAST, maxX, minY, z, zSize, ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], EDhDirection.EAST, maxX, minY, z, zSize, ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], ELodDirection.EAST, maxX, minY, z, (short) (zSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], EDhDirection.EAST, maxX, minY, z, (short) (zSize / 2), ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataEast[1], ELodDirection.EAST, maxX, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
makeAdjVerticalQuad(builder, adjDataEast[1], EDhDirection.EAST, maxX, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
@@ -224,7 +224,7 @@ public class ColumnBox
|
||||
|
||||
// the overlap color can be used to see faces that shouldn't be rendered
|
||||
private static void makeAdjVerticalQuad(
|
||||
LodQuadBuilder builder, ColumnArrayView adjColumnView, ELodDirection direction,
|
||||
LodQuadBuilder builder, ColumnArrayView adjColumnView, EDhDirection direction,
|
||||
short x, short yMin, short z, short horizontalWidth, short ySize,
|
||||
int color, int debugOverlapColor, byte skyLightTop, byte blockLight,
|
||||
long topData, long bottomData)
|
||||
|
||||
+4
-4
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDebugRendering;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.enums.EGLProxyContext;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
|
||||
@@ -18,7 +19,6 @@ import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.Reference;
|
||||
import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -215,7 +215,7 @@ public class ColumnRenderBufferBuilder
|
||||
// We avoid cases where the adjPosition is in player chunk while the position is
|
||||
// not
|
||||
// to always have a wall underwater
|
||||
for (ELodDirection lodDirection : ELodDirection.ADJ_DIRECTIONS)
|
||||
for (EDhDirection lodDirection : EDhDirection.ADJ_DIRECTIONS)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -280,8 +280,8 @@ public class ColumnRenderBufferBuilder
|
||||
adjColumnViews[lodDirection.ordinal() - 2] = new ColumnArrayView[2];
|
||||
adjColumnViews[lodDirection.ordinal() - 2][0] = adjRenderSource.getVerticalDataPointView(xAdj, zAdj);
|
||||
adjColumnViews[lodDirection.ordinal() - 2][1] = adjRenderSource.getVerticalDataPointView(
|
||||
xAdj + (lodDirection.getAxis() == ELodDirection.Axis.X ? 0 : 1),
|
||||
zAdj + (lodDirection.getAxis() == ELodDirection.Axis.Z ? 0 : 1));
|
||||
xAdj + (lodDirection.getAxis() == EDhDirection.Axis.X ? 0 : 1),
|
||||
zAdj + (lodDirection.getAxis() == EDhDirection.Axis.Z ? 0 : 1));
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
|
||||
+11
-11
@@ -23,7 +23,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.*;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.Pos2D;
|
||||
import com.seibel.distanthorizons.core.render.AbstractRenderBuffer;
|
||||
@@ -136,11 +136,11 @@ public class LodQuadBuilder
|
||||
// add quads //
|
||||
//===========//
|
||||
|
||||
public void addQuadAdj(ELodDirection dir, short x, short y, short z,
|
||||
public void addQuadAdj(EDhDirection dir, short x, short y, short z,
|
||||
short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skyLight, byte blockLight)
|
||||
{
|
||||
if (dir == ELodDirection.DOWN)
|
||||
if (dir == EDhDirection.DOWN)
|
||||
{
|
||||
throw new IllegalArgumentException("addQuadAdj() is only for adj direction! Not UP or Down!");
|
||||
}
|
||||
@@ -174,9 +174,9 @@ public class LodQuadBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, ELodDirection.UP);
|
||||
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, EDhDirection.UP);
|
||||
boolean isTransparent = (this.doTransparency && ColorUtil.getAlpha(color) < 255);
|
||||
ArrayList<BufferQuad> quadList = isTransparent ? this.transparentQuads[ELodDirection.UP.ordinal()] : this.opaqueQuads[ELodDirection.UP.ordinal()];
|
||||
ArrayList<BufferQuad> quadList = isTransparent ? this.transparentQuads[EDhDirection.UP.ordinal()] : this.opaqueQuads[EDhDirection.UP.ordinal()];
|
||||
|
||||
|
||||
// update the minimum relative height for this quad's positions
|
||||
@@ -214,9 +214,9 @@ public class LodQuadBuilder
|
||||
{
|
||||
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
|
||||
return;
|
||||
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, ELodDirection.DOWN);
|
||||
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, EDhDirection.DOWN);
|
||||
ArrayList<BufferQuad> qs = (doTransparency && ColorUtil.getAlpha(color) < 255)
|
||||
? transparentQuads[ELodDirection.DOWN.ordinal()] : opaqueQuads[ELodDirection.DOWN.ordinal()];
|
||||
? transparentQuads[EDhDirection.DOWN.ordinal()] : opaqueQuads[EDhDirection.DOWN.ordinal()];
|
||||
if (!qs.isEmpty() &&
|
||||
(qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| qs.get(qs.size()-1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
@@ -238,7 +238,7 @@ public class LodQuadBuilder
|
||||
int[][] quadBase = DIRECTION_VERTEX_IBO_QUAD[quad.direction.ordinal()];
|
||||
short widthEastWest = quad.widthEastWest;
|
||||
short widthNorthSouth = quad.widthNorthSouthOrUpDown;
|
||||
ELodDirection.Axis axis = quad.direction.getAxis();
|
||||
EDhDirection.Axis axis = quad.direction.getAxis();
|
||||
for (int i = 0; i < quadBase.length; i++)
|
||||
{
|
||||
short dx, dy, dz;
|
||||
@@ -349,7 +349,7 @@ public class LodQuadBuilder
|
||||
|
||||
|
||||
// only run the second merge if the face is the top or bottom
|
||||
if (directionIndex == ELodDirection.UP.ordinal() || directionIndex == ELodDirection.DOWN.ordinal())
|
||||
if (directionIndex == EDhDirection.UP.ordinal() || directionIndex == EDhDirection.DOWN.ordinal())
|
||||
{
|
||||
mergeCount += mergeQuadsInternal(this.opaqueQuads, directionIndex, BufferMergeDirectionEnum.NorthSouthOrUpDown);
|
||||
if (this.doTransparency)
|
||||
@@ -400,7 +400,7 @@ public class LodQuadBuilder
|
||||
public void fixTransparencyOverVoid()
|
||||
{
|
||||
// make transparent LODs opaque if they are over the void
|
||||
ListIterator<BufferQuad> iter = this.transparentQuads[ELodDirection.UP.ordinal()].listIterator();
|
||||
ListIterator<BufferQuad> iter = this.transparentQuads[EDhDirection.UP.ordinal()].listIterator();
|
||||
if (iter.hasNext())
|
||||
{
|
||||
BufferQuad currentQuad = iter.next();
|
||||
@@ -422,7 +422,7 @@ public class LodQuadBuilder
|
||||
|
||||
// move the now-opaque quad into the opaque list (if not done the quads may render on top of other transparent quads)
|
||||
iter.remove();
|
||||
this.opaqueQuads[ELodDirection.UP.ordinal()].add(currentQuad);
|
||||
this.opaqueQuads[EDhDirection.UP.ordinal()].add(currentQuad);
|
||||
}
|
||||
|
||||
currentQuad = iter.next();
|
||||
|
||||
+9
-9
@@ -397,18 +397,18 @@ public class FullDataToRenderDataTransformer
|
||||
// System.arraycopy(result, 0, data, dataOffset, maxVerticalData);
|
||||
// }
|
||||
//
|
||||
// public static final ELodDirection[] DIRECTIONS = new ELodDirection[] {
|
||||
// ELodDirection.UP,
|
||||
// ELodDirection.DOWN,
|
||||
// ELodDirection.WEST,
|
||||
// ELodDirection.EAST,
|
||||
// ELodDirection.NORTH,
|
||||
// ELodDirection.SOUTH };
|
||||
// public static final EDhDirection[] DIRECTIONS = new EDhDirection[] {
|
||||
// EDhDirection.UP,
|
||||
// EDhDirection.DOWN,
|
||||
// EDhDirection.WEST,
|
||||
// EDhDirection.EAST,
|
||||
// EDhDirection.NORTH,
|
||||
// EDhDirection.SOUTH };
|
||||
//
|
||||
// private boolean hasCliffFace(IChunkWrapper chunk, int x, int y, int z) {
|
||||
// for (ELodDirection dir : DIRECTIONS) {
|
||||
// for (EDhDirection dir : DIRECTIONS) {
|
||||
// IBlockDetailWrapper block = chunk.getBlockDetailAtFace(x, y, z, dir);
|
||||
// if (block == null || !block.hasFaceCullingFor(ELodDirection.OPPOSITE_DIRECTIONS[dir.ordinal()]))
|
||||
// if (block == null || !block.hasFaceCullingFor(EDhDirection.OPPOSITE_DIRECTIONS[dir.ordinal()]))
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
|
||||
+21
-8
@@ -10,15 +10,26 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
|
||||
public class LodDataBuilder {
|
||||
public class LodDataBuilder
|
||||
{
|
||||
|
||||
private static final IBlockStateWrapper AIR = SingletonInjector.INSTANCE.get(IWrapperFactory.class).getAirBlockStateWrapper();
|
||||
public static ChunkSizedFullDataAccessor createChunkData(IChunkWrapper chunkWrapper) {
|
||||
if (!canGenerateLodFromChunk(chunkWrapper)) return null;
|
||||
|
||||
|
||||
|
||||
public static ChunkSizedFullDataAccessor createChunkData(IChunkWrapper chunkWrapper)
|
||||
{
|
||||
if (!canGenerateLodFromChunk(chunkWrapper))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
ChunkSizedFullDataAccessor chunkData = new ChunkSizedFullDataAccessor(chunkWrapper.getChunkPos());
|
||||
|
||||
for (int x=0; x<16; x++) {
|
||||
for (int z=0; z<16; z++) {
|
||||
for (int x=0; x<LodUtil.CHUNK_WIDTH; x++)
|
||||
{
|
||||
for (int z=0; z<LodUtil.CHUNK_WIDTH; z++)
|
||||
{
|
||||
LongArrayList longs = new LongArrayList(chunkWrapper.getHeight()/4);
|
||||
int lastY = chunkWrapper.getMaxBuildHeight();
|
||||
IBiomeWrapper biome = chunkWrapper.getBiome(x, lastY, z);
|
||||
@@ -29,12 +40,14 @@ public class LodDataBuilder {
|
||||
|
||||
int y=chunkWrapper.getLightBlockingHeightMapValue(x, z);
|
||||
|
||||
for (; y>=chunkWrapper.getMinBuildHeight(); y--) {
|
||||
for (; y>=chunkWrapper.getMinBuildHeight(); y--)
|
||||
{
|
||||
IBiomeWrapper newBiome = chunkWrapper.getBiome(x, y, z);
|
||||
IBlockStateWrapper newBlockState = chunkWrapper.getBlockState(x, y, z);
|
||||
byte newLight = (byte) ((chunkWrapper.getBlockLight(x,y+1,z) << 4) + chunkWrapper.getSkyLight(x,y+1,z));
|
||||
|
||||
if (!newBiome.equals(biome) || !newBlockState.equals(blockState)) {
|
||||
if (!newBiome.equals(biome) || !newBlockState.equals(blockState))
|
||||
{
|
||||
longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunkWrapper.getMinBuildHeight(), light));
|
||||
biome = newBiome;
|
||||
blockState = newBlockState;
|
||||
|
||||
+61
-50
@@ -29,7 +29,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Vec3i;
|
||||
|
||||
/**
|
||||
* An (almost) exact copy of Minecraft's
|
||||
* Direction enum.
|
||||
* Direction enum. <Br><Br>
|
||||
*
|
||||
* Up <Br>
|
||||
* Down <Br>
|
||||
@@ -41,46 +41,57 @@ import com.seibel.distanthorizons.coreapi.util.math.Vec3i;
|
||||
* @author James Seibel
|
||||
* @version 2021-11-13
|
||||
*/
|
||||
public enum ELodDirection
|
||||
public enum EDhDirection
|
||||
{
|
||||
DOWN(0, 1, -1, "down", ELodDirection.AxisDirection.NEGATIVE, ELodDirection.Axis.Y, new Vec3i(0, -1, 0)),
|
||||
UP(1, 0, -1, "up", ELodDirection.AxisDirection.POSITIVE, ELodDirection.Axis.Y, new Vec3i(0, 1, 0)),
|
||||
NORTH(2, 3, 2, "north", ELodDirection.AxisDirection.NEGATIVE, ELodDirection.Axis.Z, new Vec3i(0, 0, -1)),
|
||||
SOUTH(3, 2, 0, "south", ELodDirection.AxisDirection.POSITIVE, ELodDirection.Axis.Z, new Vec3i(0, 0, 1)),
|
||||
WEST(4, 5, 1, "west", ELodDirection.AxisDirection.NEGATIVE, ELodDirection.Axis.X, new Vec3i(-1, 0, 0)),
|
||||
EAST(5, 4, 3, "east", ELodDirection.AxisDirection.POSITIVE, ELodDirection.Axis.X, new Vec3i(1, 0, 0));
|
||||
public static final ELodDirection[] DIRECTIONS = new ELodDirection[] {
|
||||
ELodDirection.UP,
|
||||
ELodDirection.DOWN,
|
||||
ELodDirection.WEST,
|
||||
ELodDirection.EAST,
|
||||
ELodDirection.NORTH,
|
||||
ELodDirection.SOUTH };
|
||||
DOWN(0, 1, -1, "down", EDhDirection.AxisDirection.NEGATIVE, EDhDirection.Axis.Y, new Vec3i(0, -1, 0)),
|
||||
UP(1, 0, -1, "up", EDhDirection.AxisDirection.POSITIVE, EDhDirection.Axis.Y, new Vec3i(0, 1, 0)),
|
||||
NORTH(2, 3, 2, "north", EDhDirection.AxisDirection.NEGATIVE, EDhDirection.Axis.Z, new Vec3i(0, 0, -1)),
|
||||
SOUTH(3, 2, 0, "south", EDhDirection.AxisDirection.POSITIVE, EDhDirection.Axis.Z, new Vec3i(0, 0, 1)),
|
||||
WEST(4, 5, 1, "west", EDhDirection.AxisDirection.NEGATIVE, EDhDirection.Axis.X, new Vec3i(-1, 0, 0)),
|
||||
EAST(5, 4, 3, "east", EDhDirection.AxisDirection.POSITIVE, EDhDirection.Axis.X, new Vec3i(1, 0, 0));
|
||||
|
||||
/**
|
||||
* Up, Down, West, East, North, South <br>
|
||||
* Similar to {@link EDhDirection#OPPOSITE_DIRECTIONS}, just with a different order
|
||||
*/
|
||||
public static final EDhDirection[] CARDINAL_DIRECTIONS = new EDhDirection[] {
|
||||
EDhDirection.UP,
|
||||
EDhDirection.DOWN,
|
||||
EDhDirection.WEST,
|
||||
EDhDirection.EAST,
|
||||
EDhDirection.NORTH,
|
||||
EDhDirection.SOUTH };
|
||||
|
||||
/**
|
||||
* Up, Down, South, North, East, West <br>
|
||||
* Similar to {@link EDhDirection#CARDINAL_DIRECTIONS}, just with a different order
|
||||
*/
|
||||
public static final EDhDirection[] OPPOSITE_DIRECTIONS = new EDhDirection[] {
|
||||
EDhDirection.UP,
|
||||
EDhDirection.DOWN,
|
||||
EDhDirection.SOUTH,
|
||||
EDhDirection.NORTH,
|
||||
EDhDirection.EAST,
|
||||
EDhDirection.WEST };
|
||||
|
||||
/** North, South, East, West */ // TODO rename to state this is just X/Z or flat directions
|
||||
public static final EDhDirection[] ADJ_DIRECTIONS = new EDhDirection[] {
|
||||
EDhDirection.EAST,
|
||||
EDhDirection.WEST,
|
||||
EDhDirection.SOUTH,
|
||||
EDhDirection.NORTH };
|
||||
|
||||
public static final ELodDirection[] OPPOSITE_DIRECTIONS = new ELodDirection[] {
|
||||
ELodDirection.UP,
|
||||
ELodDirection.DOWN,
|
||||
ELodDirection.SOUTH,
|
||||
ELodDirection.NORTH,
|
||||
ELodDirection.EAST,
|
||||
ELodDirection.WEST };
|
||||
/** North, South, East, West */
|
||||
public static final ELodDirection[] ADJ_DIRECTIONS = new ELodDirection[] {
|
||||
ELodDirection.EAST,
|
||||
ELodDirection.WEST,
|
||||
ELodDirection.SOUTH,
|
||||
ELodDirection.NORTH };
|
||||
// private final int data3d;
|
||||
// private final int oppositeIndex;
|
||||
// private final int data2d;
|
||||
|
||||
private final String name;
|
||||
private final ELodDirection.Axis axis;
|
||||
private final ELodDirection.AxisDirection axisDirection;
|
||||
private final EDhDirection.Axis axis;
|
||||
private final EDhDirection.AxisDirection axisDirection;
|
||||
private final Vec3i normal;
|
||||
private static final ELodDirection[] VALUES = values();
|
||||
private static final EDhDirection[] VALUES = values();
|
||||
|
||||
private static final Map<String, ELodDirection> BY_NAME = Arrays.stream(VALUES).collect(Collectors.toMap(ELodDirection::getName, (p_199787_0_) ->
|
||||
private static final Map<String, EDhDirection> BY_NAME = Arrays.stream(VALUES).collect(Collectors.toMap(EDhDirection::getName, (p_199787_0_) ->
|
||||
{
|
||||
return p_199787_0_;
|
||||
}));
|
||||
@@ -117,7 +128,7 @@ public enum ELodDirection
|
||||
|
||||
|
||||
|
||||
ELodDirection(int p_i46016_3_, int p_i46016_4_, int p_i46016_5_, String p_i46016_6_, ELodDirection.AxisDirection p_i46016_7_, ELodDirection.Axis p_i46016_8_, Vec3i p_i46016_9_)
|
||||
EDhDirection(int p_i46016_3_, int p_i46016_4_, int p_i46016_5_, String p_i46016_6_, EDhDirection.AxisDirection p_i46016_7_, EDhDirection.Axis p_i46016_8_, Vec3i p_i46016_9_)
|
||||
{
|
||||
// this.data3d = p_i46016_3_;
|
||||
// this.data2d = p_i46016_5_;
|
||||
@@ -218,7 +229,7 @@ public enum ELodDirection
|
||||
// return this.data2d;
|
||||
// }
|
||||
|
||||
public ELodDirection.AxisDirection getAxisDirection()
|
||||
public EDhDirection.AxisDirection getAxisDirection()
|
||||
{
|
||||
return this.axisDirection;
|
||||
}
|
||||
@@ -228,7 +239,7 @@ public enum ELodDirection
|
||||
// return from3DDataValue(this.oppositeIndex);
|
||||
// }
|
||||
|
||||
public ELodDirection getClockWise()
|
||||
public EDhDirection getClockWise()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
@@ -245,7 +256,7 @@ public enum ELodDirection
|
||||
}
|
||||
}
|
||||
|
||||
public ELodDirection getCounterClockWise()
|
||||
public EDhDirection getCounterClockWise()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
@@ -267,12 +278,12 @@ public enum ELodDirection
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public ELodDirection.Axis getAxis()
|
||||
public EDhDirection.Axis getAxis()
|
||||
{
|
||||
return this.axis;
|
||||
}
|
||||
|
||||
public static ELodDirection byName(String name)
|
||||
public static EDhDirection byName(String name)
|
||||
{
|
||||
return name == null ? null : BY_NAME.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
@@ -298,17 +309,17 @@ public enum ELodDirection
|
||||
// return from2DDataValue(MathHelper.floor(p_176733_0_ / 90.0D + 0.5D) & 3);
|
||||
// }
|
||||
|
||||
public static ELodDirection fromAxisAndDirection(ELodDirection.Axis p_211699_0_, ELodDirection.AxisDirection p_211699_1_)
|
||||
public static EDhDirection fromAxisAndDirection(EDhDirection.Axis p_211699_0_, EDhDirection.AxisDirection p_211699_1_)
|
||||
{
|
||||
switch (p_211699_0_)
|
||||
{
|
||||
case X:
|
||||
return p_211699_1_ == ELodDirection.AxisDirection.POSITIVE ? EAST : WEST;
|
||||
return p_211699_1_ == EDhDirection.AxisDirection.POSITIVE ? EAST : WEST;
|
||||
case Y:
|
||||
return p_211699_1_ == ELodDirection.AxisDirection.POSITIVE ? UP : DOWN;
|
||||
return p_211699_1_ == EDhDirection.AxisDirection.POSITIVE ? UP : DOWN;
|
||||
case Z:
|
||||
default:
|
||||
return p_211699_1_ == ELodDirection.AxisDirection.POSITIVE ? SOUTH : NORTH;
|
||||
return p_211699_1_ == EDhDirection.AxisDirection.POSITIVE ? SOUTH : NORTH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,9 +356,9 @@ public enum ELodDirection
|
||||
// return lodDirection;
|
||||
// }
|
||||
|
||||
public static ELodDirection get(ELodDirection.AxisDirection p_181076_0_, ELodDirection.Axis p_181076_1_)
|
||||
public static EDhDirection get(EDhDirection.AxisDirection p_181076_0_, EDhDirection.Axis p_181076_1_)
|
||||
{
|
||||
for (ELodDirection lodDirection : VALUES)
|
||||
for (EDhDirection lodDirection : VALUES)
|
||||
{
|
||||
if (lodDirection.getAxisDirection() == p_181076_0_ && lodDirection.getAxis() == p_181076_1_)
|
||||
{
|
||||
@@ -371,7 +382,7 @@ public enum ELodDirection
|
||||
// return this.normal.getX() * f1 + this.normal.getZ() * f2 > 0.0F;
|
||||
// }
|
||||
|
||||
public enum Axis implements Predicate<ELodDirection>
|
||||
public enum Axis implements Predicate<EDhDirection>
|
||||
{
|
||||
X("x")
|
||||
{
|
||||
@@ -416,9 +427,9 @@ public enum ELodDirection
|
||||
}
|
||||
};
|
||||
|
||||
private static final ELodDirection.Axis[] VALUES = values();
|
||||
private static final EDhDirection.Axis[] VALUES = values();
|
||||
|
||||
private static final Map<String, ELodDirection.Axis> BY_NAME = Arrays.stream(VALUES).collect(Collectors.toMap(ELodDirection.Axis::getName, (p_199785_0_) ->
|
||||
private static final Map<String, EDhDirection.Axis> BY_NAME = Arrays.stream(VALUES).collect(Collectors.toMap(EDhDirection.Axis::getName, (p_199785_0_) ->
|
||||
{
|
||||
return p_199785_0_;
|
||||
}));
|
||||
@@ -429,7 +440,7 @@ public enum ELodDirection
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static ELodDirection.Axis byName(String name)
|
||||
public static EDhDirection.Axis byName(String name)
|
||||
{
|
||||
return BY_NAME.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
@@ -461,7 +472,7 @@ public enum ELodDirection
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean test(ELodDirection p_test_1_)
|
||||
public boolean test(EDhDirection p_test_1_)
|
||||
{
|
||||
return p_test_1_ != null && p_test_1_.getAxis() == this;
|
||||
}
|
||||
@@ -510,7 +521,7 @@ public enum ELodDirection
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public ELodDirection.AxisDirection opposite()
|
||||
public EDhDirection.AxisDirection opposite()
|
||||
{
|
||||
return this == POSITIVE ? NEGATIVE : POSITIVE;
|
||||
}
|
||||
+3
-2
@@ -205,8 +205,9 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
|
||||
})
|
||||
.whenComplete((fullDataSource, ex) ->
|
||||
{
|
||||
if (ex != null && !LodUtil.isInterruptOrReject(ex)) {
|
||||
LOGGER.error("Error updating file "+this.file+": ", ex);
|
||||
if (ex != null && !LodUtil.isInterruptOrReject(ex))
|
||||
{
|
||||
LOGGER.error("Error updating file ["+this.file+"]: ", ex);
|
||||
}
|
||||
|
||||
if (fullDataSource != null) {
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
package com.seibel.distanthorizons.core.generation;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This logic was roughly based on
|
||||
* <a href="https://github.com/PaperMC/Starlight/blob/acc8ed9634bbe27ec68e8842e420948bfa9707e7/TECHNICAL_DETAILS.md">Starlight's technical documentation</a>
|
||||
* although there were some changes due to how our lighting engine works in comparison to Minecraft's.
|
||||
*/
|
||||
public class DhLightingEngine
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final DhLightingEngine INSTANCE = new DhLightingEngine();
|
||||
|
||||
|
||||
private DhLightingEngine() { }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Note: depending on the implementation of {@link IChunkWrapper#setDhBlockLight(int, int, int, int)} and {@link IChunkWrapper#setDhSkyLight(int, int, int, int)}
|
||||
* the light values may be stored in the wrapper itself instead of the wrapped chunk object.
|
||||
* If that is the case unwrapping the chunk will undo any work this method did.
|
||||
*
|
||||
* @param centerChunk the chunk we want to apply lighting to
|
||||
* @param nearbyChunkList should also contain centerChunk
|
||||
* @param maxSkyLight should be a value between 0 and 15
|
||||
*/
|
||||
public void lightChunks(IChunkWrapper centerChunk, List<IChunkWrapper> nearbyChunkList, int maxSkyLight)
|
||||
{
|
||||
DhChunkPos centerChunkPos = centerChunk.getChunkPos();
|
||||
|
||||
HashMap<DhChunkPos, IChunkWrapper> chunksByChunkPos = new HashMap<>(9);
|
||||
LinkedList<LightPos> blockLightPosQueue = new LinkedList<>();
|
||||
LinkedList<LightPos> skyLightPosQueue = new LinkedList<>();
|
||||
|
||||
// generate the list of chunk pos we need,
|
||||
// currently a 3x3 grid
|
||||
HashSet<DhChunkPos> requestedAdjacentPositions = new HashSet<>(9);
|
||||
for (int xOffset = -1; xOffset <= 1; xOffset++)
|
||||
{
|
||||
for (int zOffset = -1; zOffset <= 1; zOffset++)
|
||||
{
|
||||
DhChunkPos adjacentPos = new DhChunkPos(centerChunkPos.x+xOffset, centerChunkPos.z+zOffset);
|
||||
requestedAdjacentPositions.add(adjacentPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// find all adjacent chunks
|
||||
// and get any necessary info from them
|
||||
for (IChunkWrapper chunk : nearbyChunkList)
|
||||
{
|
||||
if (chunk != null && requestedAdjacentPositions.contains(chunk.getChunkPos()))
|
||||
{
|
||||
// remove the newly found position
|
||||
requestedAdjacentPositions.remove(chunk.getChunkPos());
|
||||
|
||||
// add the adjacent chunk
|
||||
chunksByChunkPos.put(chunk.getChunkPos(), chunk);
|
||||
|
||||
|
||||
|
||||
// get and set the adjacent chunk's initial block lights
|
||||
List<DhBlockPos> blockLightPosList = chunk.getBlockLightPosList();
|
||||
for (DhBlockPos blockLightPos : blockLightPosList)
|
||||
{
|
||||
// get the light
|
||||
DhBlockPos relLightBlockPos = blockLightPos.convertToChunkRelativePos();
|
||||
IBlockStateWrapper blockState = chunk.getBlockState(relLightBlockPos);
|
||||
int lightValue = blockState.getLightEmission();
|
||||
blockLightPosQueue.add(new LightPos(blockLightPos, lightValue));
|
||||
|
||||
// set the light
|
||||
DhBlockPos relBlockPos = blockLightPos.convertToChunkRelativePos();
|
||||
chunk.setDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, lightValue);
|
||||
}
|
||||
|
||||
|
||||
// get and set the adjacent chunk's initial skylights,
|
||||
// if the dimension has skylights
|
||||
if (maxSkyLight > 0)
|
||||
{
|
||||
// get the adjacent chunk's sky lights
|
||||
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++) // relative block pos
|
||||
{
|
||||
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||
{
|
||||
// get the light
|
||||
int maxY = chunk.getLightBlockingHeightMapValue(relX, relZ);
|
||||
DhBlockPos skyLightPos = new DhBlockPos(chunk.getMinBlockX() + relX, maxY, chunk.getMinBlockZ() + relZ);
|
||||
skyLightPosQueue.add(new LightPos(skyLightPos, maxSkyLight));
|
||||
|
||||
// set the light
|
||||
DhBlockPos relBlockPos = skyLightPos.convertToChunkRelativePos();
|
||||
chunk.setDhSkyLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, maxSkyLight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (requestedAdjacentPositions.isEmpty())
|
||||
{
|
||||
// we found every chunk we needed, we don't need to keep iterating
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// validate that at least 1 chunk was found
|
||||
if (chunksByChunkPos.size() == 0)
|
||||
{
|
||||
LOGGER.warn("Attempted to generate lighting for position ["+centerChunkPos+"], but neither that chunk nor any adjacent chunks were found. No chunk lighting was performed.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// block light
|
||||
this.propagateLightPosList(blockLightPosQueue, chunksByChunkPos,
|
||||
(neighbourChunk, relBlockPos) -> neighbourChunk.getDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z),
|
||||
(neighbourChunk, relBlockPos, newLightValue) -> neighbourChunk.setDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, newLightValue));
|
||||
|
||||
// sky light
|
||||
this.propagateLightPosList(skyLightPosQueue, chunksByChunkPos,
|
||||
(neighbourChunk, relBlockPos) -> neighbourChunk.getDhSkyLight(relBlockPos.x, relBlockPos.y, relBlockPos.z),
|
||||
(neighbourChunk, relBlockPos, newLightValue) -> neighbourChunk.setDhSkyLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, newLightValue));
|
||||
|
||||
|
||||
LOGGER.trace("Finished generating lighting for chunk: ["+centerChunkPos+"]");
|
||||
}
|
||||
|
||||
/** Applies each {@link LightPos} from the queue to the given set of {@link IChunkWrapper}'s. */
|
||||
private void propagateLightPosList(
|
||||
LinkedList<LightPos> lightPosQueue, HashMap<DhChunkPos, IChunkWrapper> chunksByChunkPos,
|
||||
IGetLightFunc getLightFunc, ISetLightFunc setLightFunc)
|
||||
{
|
||||
// update each light position
|
||||
while (!lightPosQueue.isEmpty())
|
||||
{
|
||||
LightPos lightPos = lightPosQueue.poll();
|
||||
DhBlockPos pos = lightPos.pos;
|
||||
int lightValue = lightPos.lightValue;
|
||||
|
||||
// propagate the lighting in each cardinal direction, IE: -x, +x, -y, +y, -z, +z
|
||||
for (EDhDirection direction : EDhDirection.CARDINAL_DIRECTIONS)
|
||||
{
|
||||
DhBlockPos neighbourBlockPos = pos.offset(direction);
|
||||
DhChunkPos neighbourChunkPos = new DhChunkPos(neighbourBlockPos);
|
||||
// converting the block pos into a relative position is necessary for accessing the light values in the chunk
|
||||
DhBlockPos relNeighbourBlockPos = neighbourBlockPos.convertToChunkRelativePos();
|
||||
|
||||
|
||||
// only continue if the light position is inside one of our chunks
|
||||
IChunkWrapper neighbourChunk = chunksByChunkPos.get(neighbourChunkPos);
|
||||
if (neighbourChunk == null)
|
||||
{
|
||||
// the light pos is outside our generator's range, ignore it
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int currentBlockLight = getLightFunc.getLight(neighbourChunk, relNeighbourBlockPos);
|
||||
if (currentBlockLight >= (lightValue - 1))
|
||||
{
|
||||
// short circuit for when the light value at this position
|
||||
// is already greater-than what we could set it
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
IBlockStateWrapper neighbourBlockState = neighbourChunk.getBlockState(relNeighbourBlockPos);
|
||||
// Math.max(1, ...) is used so that the propagated light level always drops by at least 1, preventing infinite cycles.
|
||||
int targetLevel = lightValue - Math.max(1, neighbourBlockState.getOpacity());
|
||||
if (targetLevel > currentBlockLight)
|
||||
{
|
||||
// this position is darker than the new light value, update/set it
|
||||
setLightFunc.setLight(neighbourChunk, relNeighbourBlockPos, targetLevel);
|
||||
|
||||
// now that light has been propagated to this blockPos
|
||||
// we need to queue it up so its neighbours can be propagated as well
|
||||
lightPosQueue.add(new LightPos(neighbourBlockPos, targetLevel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// propagation complete
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
@FunctionalInterface
|
||||
interface IGetLightFunc { int getLight(IChunkWrapper chunk, DhBlockPos pos); }
|
||||
@FunctionalInterface
|
||||
interface ISetLightFunc { void setLight(IChunkWrapper chunk, DhBlockPos pos, int lightValue); }
|
||||
|
||||
private static class LightPos
|
||||
{
|
||||
public final DhBlockPos pos;
|
||||
public final int lightValue;
|
||||
|
||||
public LightPos(DhBlockPos pos, int lightValue)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.lightValue = lightValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.seibel.distanthorizons.core.file.fullDatafile.GeneratedFullDataFileHa
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
|
||||
public interface IDhServerLevel extends IDhLevel, GeneratedFullDataFileHandler.IOnWorldGenCompleteListener
|
||||
{
|
||||
{
|
||||
void serverTick();
|
||||
void doWorldGen();
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.pos;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DhBlockPos {
|
||||
@@ -110,10 +113,23 @@ public class DhBlockPos {
|
||||
return asLong(x, y, z);
|
||||
}
|
||||
|
||||
public DhBlockPos offset(int x, int y, int z)
|
||||
{
|
||||
return new DhBlockPos(this.x + x, this.y + y, this.z + z);
|
||||
}
|
||||
public DhBlockPos offset(EDhDirection direction) { return this.offset(direction.getNormal().x, direction.getNormal().y, direction.getNormal().z); }
|
||||
public DhBlockPos offset(int x, int y, int z) { return new DhBlockPos(this.x + x, this.y + y, this.z + z); }
|
||||
|
||||
/** Limits the block position to a value between 0 and 15 (inclusive) */
|
||||
public DhBlockPos convertToChunkRelativePos()
|
||||
{
|
||||
// move the position into the range -15 and +15
|
||||
int relX = (this.x % LodUtil.CHUNK_WIDTH);
|
||||
// if the position is negative move it into the range 0 and 15
|
||||
relX = (relX < 0) ? (relX + LodUtil.CHUNK_WIDTH) : relX;
|
||||
|
||||
int relZ = (this.z % LodUtil.CHUNK_WIDTH);
|
||||
relZ = (relZ < 0) ? (relZ + LodUtil.CHUNK_WIDTH) : relZ;
|
||||
|
||||
// the y value shouldn't need to be changed
|
||||
return new DhBlockPos(relX, this.y, relZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to quickly determine the rough distance between two points<Br>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.seibel.distanthorizons.core.pos;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.network.protocol.INetworkObject;
|
||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
@@ -187,7 +187,7 @@ public class DhSectionPos implements Comparable<DhSectionPos>, INetworkObject
|
||||
|
||||
public DhSectionPos getParentPos() { return new DhSectionPos((byte) (this.sectionDetailLevel + 1), BitShiftUtil.half(this.sectionX), BitShiftUtil.half(this.sectionZ)); }
|
||||
|
||||
public DhSectionPos getAdjacentPos(ELodDirection dir)
|
||||
public DhSectionPos getAdjacentPos(EDhDirection dir)
|
||||
{
|
||||
return new DhSectionPos(this.sectionDetailLevel,
|
||||
this.sectionX + dir.getNormal().x,
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.render;
|
||||
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBufferBuilder;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.file.renderfile.ILodRenderSourceProvider;
|
||||
import com.seibel.distanthorizons.core.level.IDhClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
@@ -11,7 +12,6 @@ import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.Reference;
|
||||
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadTree;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Objects;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -224,8 +223,8 @@ public class LodRenderSection implements IDebugRenderable
|
||||
|
||||
private LodRenderSection[] getNeighbors()
|
||||
{
|
||||
LodRenderSection[] adjacents = new LodRenderSection[ELodDirection.ADJ_DIRECTIONS.length];
|
||||
for (ELodDirection direction : ELodDirection.ADJ_DIRECTIONS) {
|
||||
LodRenderSection[] adjacents = new LodRenderSection[EDhDirection.ADJ_DIRECTIONS.length];
|
||||
for (EDhDirection direction : EDhDirection.ADJ_DIRECTIONS) {
|
||||
try {
|
||||
DhSectionPos adjPos = pos.getAdjacentPos(direction);
|
||||
LodRenderSection adjRenderSection = parentQuadTree.getValue(adjPos);
|
||||
@@ -285,8 +284,8 @@ public class LodRenderSection implements IDebugRenderable
|
||||
tellNeighborsUpdated();
|
||||
}
|
||||
LodRenderSection[] adjacents = getNeighbors();
|
||||
ColumnRenderSource[] adjacentSources = new ColumnRenderSource[ELodDirection.ADJ_DIRECTIONS.length];
|
||||
for (int i = 0; i < ELodDirection.ADJ_DIRECTIONS.length; i++) {
|
||||
ColumnRenderSource[] adjacentSources = new ColumnRenderSource[EDhDirection.ADJ_DIRECTIONS.length];
|
||||
for (int i = 0; i < EDhDirection.ADJ_DIRECTIONS.length; i++) {
|
||||
LodRenderSection adj = adjacents[i];
|
||||
if (adj != null) {
|
||||
adjacentSources[i] = adj.getRenderSource();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.seibel.distanthorizons.core.render;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.Pos2D;
|
||||
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
|
||||
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -45,16 +45,16 @@ public class RenderBufferHandler
|
||||
*/
|
||||
public void buildRenderListAndUpdateSections(Vec3f lookForwardVector)
|
||||
{
|
||||
ELodDirection[] axisDirections = new ELodDirection[3];
|
||||
EDhDirection[] axisDirections = new EDhDirection[3];
|
||||
|
||||
// Do the axis that are the longest first (i.e. the largest absolute value of the lookForwardVector),
|
||||
// with the sign being the opposite of the respective lookForwardVector component's sign
|
||||
float absX = Math.abs(lookForwardVector.x);
|
||||
float absY = Math.abs(lookForwardVector.y);
|
||||
float absZ = Math.abs(lookForwardVector.z);
|
||||
ELodDirection xDir = lookForwardVector.x < 0 ? ELodDirection.EAST : ELodDirection.WEST;
|
||||
ELodDirection yDir = lookForwardVector.y < 0 ? ELodDirection.UP : ELodDirection.DOWN;
|
||||
ELodDirection zDir = lookForwardVector.z < 0 ? ELodDirection.SOUTH : ELodDirection.NORTH;
|
||||
EDhDirection xDir = lookForwardVector.x < 0 ? EDhDirection.EAST : EDhDirection.WEST;
|
||||
EDhDirection yDir = lookForwardVector.y < 0 ? EDhDirection.UP : EDhDirection.DOWN;
|
||||
EDhDirection zDir = lookForwardVector.z < 0 ? EDhDirection.SOUTH : EDhDirection.NORTH;
|
||||
|
||||
if (absX >= absY && absX >= absZ)
|
||||
{
|
||||
@@ -112,7 +112,7 @@ public class RenderBufferHandler
|
||||
return bManhattanDistance - aManhattanDistance;
|
||||
}
|
||||
|
||||
for (ELodDirection axisDirection : axisDirections)
|
||||
for (EDhDirection axisDirection : axisDirections)
|
||||
{
|
||||
if (axisDirection.getAxis().isVertical())
|
||||
{
|
||||
@@ -120,7 +120,7 @@ public class RenderBufferHandler
|
||||
}
|
||||
|
||||
int abPosDifference;
|
||||
if (axisDirection.getAxis().equals(ELodDirection.Axis.X))
|
||||
if (axisDirection.getAxis().equals(EDhDirection.Axis.X))
|
||||
{
|
||||
abPosDifference = aPos.x - bPos.x;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class RenderBufferHandler
|
||||
continue;
|
||||
}
|
||||
|
||||
if (axisDirection.getAxisDirection().equals(ELodDirection.AxisDirection.NEGATIVE))
|
||||
if (axisDirection.getAxisDirection().equals(EDhDirection.AxisDirection.NEGATIVE))
|
||||
{
|
||||
abPosDifference = -abPosDifference; // Reverse the sign
|
||||
}
|
||||
|
||||
+16
-2
@@ -30,6 +30,9 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.QuadElementBuffer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.DarkShader;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.FogShader;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.SSAORenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOShader;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
@@ -76,7 +79,10 @@ public class LodRenderer
|
||||
|
||||
public void setupOffset(DhBlockPos pos) {
|
||||
Vec3d cam = MC_RENDER.getCameraExactPosition();
|
||||
shaderProgram.setModelPos(new Vec3f((float) (pos.x - cam.x), (float) (pos.y - cam.y), (float) (pos.z - cam.z)));
|
||||
Vec3f modelPos = new Vec3f((float) (pos.x - cam.x), (float) (pos.y - cam.y), (float) (pos.z - cam.z));
|
||||
|
||||
shaderProgram.setModelPos(modelPos);
|
||||
// FogShader.INSTANCE.setModelPos(modelPos);
|
||||
}
|
||||
|
||||
public void drawVbo(GLVertexBuffer vbo) {
|
||||
@@ -203,6 +209,8 @@ public class LodRenderer
|
||||
if (newConfig != null) {
|
||||
shaderProgram.free();
|
||||
shaderProgram = new LodRenderProgram(newConfig);
|
||||
// FogShader.INSTANCE.free();
|
||||
// FogShader.INSTANCE = new FogShader(newConfig);
|
||||
}
|
||||
shaderProgram.bind();
|
||||
}
|
||||
@@ -244,7 +252,12 @@ public class LodRenderer
|
||||
bufferHandler.renderOpaque(this);
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Quality.ssao.get()) {
|
||||
SSAOShader.INSTANCE.render(partialTicks);
|
||||
// SSAOShader.INSTANCE.render(partialTicks);
|
||||
SSAORenderer.INSTANCE.render(partialTicks);
|
||||
}
|
||||
{
|
||||
// FogShader.INSTANCE.render(partialTicks);
|
||||
// DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker
|
||||
}
|
||||
|
||||
//======================//
|
||||
@@ -348,6 +361,7 @@ public class LodRenderer
|
||||
isSetupComplete = false;
|
||||
EVENT_LOGGER.info("Renderer Cleanup Started");
|
||||
shaderProgram.free();
|
||||
// FogShader.INSTANCE.free();
|
||||
if (quadIBO != null) quadIBO.destroy(false);
|
||||
EVENT_LOGGER.info("Renderer Cleanup Complete");
|
||||
}
|
||||
|
||||
+9
-1
@@ -6,6 +6,7 @@ import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
@@ -14,6 +15,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public abstract class AbstractShaderRenderer {
|
||||
protected static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
protected static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final float[] box_vertices = {
|
||||
@@ -106,7 +108,7 @@ public abstract class AbstractShaderRenderer {
|
||||
this.setApplyShaderUniforms(partialTicks);
|
||||
}
|
||||
GL32.glEnable(GL11.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_ZERO, GL32.GL_SRC_ALPHA);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, shaderTexture);
|
||||
@@ -149,4 +151,10 @@ public abstract class AbstractShaderRenderer {
|
||||
boxBuffer.bind();
|
||||
boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES);
|
||||
}
|
||||
|
||||
public void free() {
|
||||
this.shader.free();
|
||||
if (this.applyShader != null)
|
||||
this.applyShader.free();
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
|
||||
public class DarkShader extends AbstractShaderRenderer {
|
||||
public static DarkShader INSTANCE = new DarkShader();
|
||||
|
||||
protected DarkShader() {
|
||||
super(new ShaderProgram("shaders/normal.vert", "shaders/test/dark.frag", "fragColor", new String[] { "vPosition", "color" }));
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EFogColorMode;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class FogShader extends AbstractShaderRenderer {
|
||||
public static FogShader INSTANCE = new FogShader(LodFogConfig.generateFogConfig());
|
||||
private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
|
||||
|
||||
// public final int modelOffsetUniform;
|
||||
public final int worldYOffsetUniform;
|
||||
|
||||
// Fog Uniforms
|
||||
public final int fogColorUniform;
|
||||
public final int fogScaleUniform;
|
||||
public final int fogVerticalScaleUniform;
|
||||
public final int nearFogStartUniform;
|
||||
public final int nearFogLengthUniform;;
|
||||
public final int fullFogModeUniform;
|
||||
|
||||
public FogShader(LodFogConfig fogConfig) {
|
||||
// TODO & Note: This code is a bit jank, so try to make it better later (preferably not using something to process the shader)
|
||||
// This code is just a temp fix so that it looks fine for the time being
|
||||
// and even with the jank soloution, i cannot get it to work
|
||||
super(new ShaderProgram(
|
||||
() -> Shader.loadFile("shaders/fog/fog.vert", false, new StringBuilder()).toString(),
|
||||
() -> fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(),
|
||||
"fragColor", new String[] { "vPosition", "vPos", "color" }
|
||||
));
|
||||
|
||||
// modelOffsetUniform = this.shader.getUniformLocation("modelOffset");
|
||||
worldYOffsetUniform = this.shader.getUniformLocation("worldYOffset");
|
||||
// Fog uniforms
|
||||
fogColorUniform = this.shader.getUniformLocation("fogColor");
|
||||
fullFogModeUniform = this.shader.getUniformLocation("fullFogMode");
|
||||
fogScaleUniform = this.shader.tryGetUniformLocation("fogScale");
|
||||
fogVerticalScaleUniform = this.shader.tryGetUniformLocation("fogVerticalScale");
|
||||
// near
|
||||
nearFogStartUniform = this.shader.tryGetUniformLocation("nearFogStart");
|
||||
nearFogLengthUniform = this.shader.tryGetUniformLocation("nearFogLength");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
void setShaderUniforms(float partialTicks) {
|
||||
int lodDrawDistance = RenderUtil.getFarClipPlaneDistanceInBlocks();
|
||||
int vanillaDrawDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
// super.bind();
|
||||
vanillaDrawDistance += 32; // Give it a 2 chunk boundary for near fog.
|
||||
|
||||
|
||||
this.shader.setUniform(worldYOffsetUniform, (float) MC.getWrappedClientWorld().getMinHeight());
|
||||
|
||||
// Fog
|
||||
this.shader.setUniform(fullFogModeUniform, MC_RENDER.isFogStateSpecial() ? 1 : 0);
|
||||
this.shader.setUniform(fogColorUniform, MC_RENDER.isFogStateSpecial() ? getSpecialFogColor(partialTicks) : getFogColor(partialTicks));
|
||||
|
||||
float nearFogLen = vanillaDrawDistance * 0.2f / lodDrawDistance;
|
||||
float nearFogStart = vanillaDrawDistance * (VERSION_CONSTANTS.isVanillaRenderedChunkSquare() ? (float)Math.sqrt(2.) : 1.f) / lodDrawDistance;
|
||||
if (nearFogStartUniform != -1) this.shader.setUniform(nearFogStartUniform, nearFogStart);
|
||||
if (nearFogLengthUniform != -1) this.shader.setUniform(nearFogLengthUniform, nearFogLen);
|
||||
if (fogScaleUniform != -1) this.shader.setUniform(fogScaleUniform, 1.f/lodDrawDistance);
|
||||
if (fogVerticalScaleUniform != -1) this.shader.setUniform(fogVerticalScaleUniform, 1.f/MC.getWrappedClientWorld().getHeight());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Color getFogColor(float partialTicks)
|
||||
{
|
||||
Color fogColor;
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.colorMode.get() == EFogColorMode.USE_SKY_COLOR)
|
||||
fogColor = MC_RENDER.getSkyColor();
|
||||
else
|
||||
fogColor = MC_RENDER.getFogColor(partialTicks);
|
||||
|
||||
return fogColor;
|
||||
}
|
||||
private Color getSpecialFogColor(float partialTicks)
|
||||
{
|
||||
return MC_RENDER.getSpecialFogColor(partialTicks);
|
||||
}
|
||||
|
||||
public void setModelPos(Vec3f modelPos) {
|
||||
// this.shader.setUniform(modelOffsetUniform, modelPos);
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
// TODO: Move over to SSAOShader
|
||||
// For some reason this version looks slightly different to that, even tough there isnt much visible change in the code
|
||||
public class SSAORenderer {
|
||||
public static SSAORenderer INSTANCE = new SSAORenderer();
|
||||
|
||||
public SSAORenderer() {
|
||||
}
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final float[] box_vertices = {
|
||||
-1, -1,
|
||||
1, -1,
|
||||
1, 1,
|
||||
-1, -1,
|
||||
1, 1,
|
||||
-1, 1,
|
||||
};
|
||||
|
||||
ShaderProgram ssaoShader;
|
||||
ShaderProgram applyShader;
|
||||
GLVertexBuffer boxBuffer;
|
||||
VertexAttribute va;
|
||||
boolean init = false;
|
||||
|
||||
private static final int MAX_KERNEL_SIZE = 32;
|
||||
private float[] kernel = new float[MAX_KERNEL_SIZE * 3];
|
||||
|
||||
public void init() {
|
||||
if (init) return;
|
||||
|
||||
init = true;
|
||||
va = VertexAttribute.create();
|
||||
va.bind();
|
||||
// Pos
|
||||
va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
va.completeAndCheck(Float.BYTES * 2);
|
||||
ssaoShader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
|
||||
applyShader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/apply-frag.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
|
||||
|
||||
// Generate kernel
|
||||
kernel = genKernel();
|
||||
// Framebuffer
|
||||
createBuffer();
|
||||
}
|
||||
|
||||
private int width = -1;
|
||||
private int height = -1;
|
||||
private int ssaoFramebuffer = -1;
|
||||
|
||||
private int ssaoTexture = -1;
|
||||
|
||||
private void createFramebuffer(int width, int height) {
|
||||
if (ssaoFramebuffer != -1) {
|
||||
GL32.glDeleteFramebuffers(ssaoFramebuffer);
|
||||
ssaoFramebuffer = -1;
|
||||
}
|
||||
|
||||
if (ssaoTexture != -1) {
|
||||
GL32.glDeleteTextures(ssaoTexture);
|
||||
ssaoTexture = -1;
|
||||
}
|
||||
|
||||
ssaoFramebuffer = GL32.glGenFramebuffers();
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, ssaoFramebuffer);
|
||||
|
||||
ssaoTexture = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, ssaoTexture);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RED, width, height, 0, GL32.GL_RED, GL32.GL_FLOAT, (ByteBuffer) null);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST);
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, ssaoTexture, 0);
|
||||
}
|
||||
|
||||
private void createBuffer() {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.asFloatBuffer().put(box_vertices);
|
||||
buffer.rewind();
|
||||
boxBuffer = new GLVertexBuffer(false);
|
||||
boxBuffer.bind();
|
||||
boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES);
|
||||
}
|
||||
|
||||
private static float[] genKernel() {
|
||||
float[] kernel = new float[MAX_KERNEL_SIZE * 3];
|
||||
for (int i = 0; i < MAX_KERNEL_SIZE; i++) {
|
||||
float sampleX = (float) (Math.random() * 2.0 - 1.0);
|
||||
float sampleY = (float) (Math.random() * 2.0 - 1.0);
|
||||
float sampleZ = (float) Math.random();
|
||||
|
||||
|
||||
// Normalize
|
||||
float magnitude = (float) Math.sqrt(Math.pow(sampleX, 2) + Math.pow(sampleY, 2) + Math.pow(sampleZ, 2));
|
||||
sampleX /= magnitude;
|
||||
sampleY /= magnitude;
|
||||
sampleZ /= magnitude;
|
||||
|
||||
float scale = i / (float) MAX_KERNEL_SIZE;
|
||||
float interpolatedScale = (float) (0.1 + (scale * scale) * (0.9));
|
||||
|
||||
sampleX *= interpolatedScale;
|
||||
sampleY *= interpolatedScale;
|
||||
sampleZ *= interpolatedScale;
|
||||
kernel[i * 3] = sampleX;
|
||||
kernel[i * 3 + 1] = sampleY;
|
||||
kernel[i * 3 + 2] = sampleZ;
|
||||
}
|
||||
return kernel;
|
||||
}
|
||||
|
||||
public void render(float partialTicks) {
|
||||
GLState state = new GLState();
|
||||
init();
|
||||
//GL32.glDepthMask(false);
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
if (this.width != width || this.height != height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
createFramebuffer(width, height);
|
||||
}
|
||||
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, ssaoFramebuffer);
|
||||
GL32.glViewport(0, 0, width, height);
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL32.GL_BLEND);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
|
||||
|
||||
Mat4f perspective = Mat4f.perspective(
|
||||
(float) MC_RENDER.getFov(partialTicks),
|
||||
MC_RENDER.getTargetFrameBufferViewportWidth() / (float) MC_RENDER.getTargetFrameBufferViewportHeight(),
|
||||
RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks),
|
||||
(float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2)));
|
||||
|
||||
ssaoShader.bind();
|
||||
ssaoShader.setUniform(ssaoShader.getUniformLocation("gProj"), perspective);
|
||||
ssaoShader.setUniform(ssaoShader.getUniformLocation("gSampleRad"), 3.0f);
|
||||
ssaoShader.setUniform(ssaoShader.getUniformLocation("gFactor"), 0.8f);
|
||||
ssaoShader.setUniform(ssaoShader.getUniformLocation("gPower"), 1.0f);
|
||||
va.bind();
|
||||
va.bindBufferToAllBindingPoint(boxBuffer.getId());
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
|
||||
GL32.glUniform3fv(ssaoShader.getUniformLocation("gKernel"), kernel);
|
||||
GL32.glUniform1i(ssaoShader.getUniformLocation("gDepthMap"), 0);
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
|
||||
applyShader.bind();
|
||||
GL32.glEnable(GL11.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, ssaoTexture);
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
|
||||
//GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, ssaoFramebuffer);
|
||||
//GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, MC_RENDER.getTargetFrameBuffer());
|
||||
//GL32.glBlitFramebuffer(
|
||||
// 0, 0, width, height,
|
||||
// 0, 0, width, height,
|
||||
// GL11.GL_COLOR_BUFFER_BIT,
|
||||
// GL11.GL_NEAREST
|
||||
//);
|
||||
|
||||
state.restore();
|
||||
}
|
||||
|
||||
public void free() {
|
||||
ssaoShader.free();
|
||||
applyShader.free();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -15,9 +15,9 @@ public class SSAOShader extends AbstractShaderRenderer {
|
||||
|
||||
public SSAOShader() {
|
||||
super(
|
||||
new ShaderProgram("shaders/ssao/ao.vert", "shaders/ssao/ao.frag",
|
||||
new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag",
|
||||
"fragColor", new String[]{"vPos"}),
|
||||
new ShaderProgram("shaders/ssao/ao.vert", "shaders/ssao/apply-frag.frag",
|
||||
new ShaderProgram("shaders/normal.vert", "shaders/ssao/apply-frag.frag",
|
||||
"fragColor", new String[]{"vPos"})
|
||||
);
|
||||
|
||||
|
||||
+9
-6
@@ -2,14 +2,17 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.block;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
|
||||
|
||||
/**
|
||||
* A Minecraft version independent way of handling Blocks.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-11-12
|
||||
*/
|
||||
/** A Minecraft version independent way of handling Blocks. */
|
||||
public interface IBlockStateWrapper extends IDhApiBlockStateWrapper
|
||||
{
|
||||
String serialize();
|
||||
|
||||
/**
|
||||
* Returning a value of 0 means the block is completely transparent. <br.
|
||||
* Returning a value of 15 means the block is completely opaque.
|
||||
*/
|
||||
int getOpacity();
|
||||
|
||||
int getLightEmission();
|
||||
|
||||
}
|
||||
|
||||
+38
-14
@@ -19,14 +19,20 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.wrapperInterfaces.chunk;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IChunkWrapper extends IBindable
|
||||
{
|
||||
DhChunkPos getChunkPos();
|
||||
|
||||
default int getHeight() { return this.getMaxBuildHeight() - this.getMinBuildHeight(); }
|
||||
int getMinBuildHeight();
|
||||
int getMaxBuildHeight();
|
||||
@@ -39,27 +45,44 @@ public interface IChunkWrapper extends IBindable
|
||||
*/
|
||||
int getLightBlockingHeightMapValue(int xRel, int zRel);
|
||||
|
||||
int getMaxX();
|
||||
int getMaxZ();
|
||||
int getMinX();
|
||||
int getMinZ();
|
||||
int getMaxBlockX();
|
||||
int getMaxBlockZ();
|
||||
int getMinBlockX();
|
||||
int getMinBlockZ();
|
||||
|
||||
long getLongChunkPos();
|
||||
|
||||
void setIsDhLightCorrect(boolean isDhLightCorrect);
|
||||
boolean isLightCorrect();
|
||||
|
||||
default int getBlockLight(int x, int y, int z) {return -1;}
|
||||
|
||||
default int getSkyLight(int x, int y, int z) {return -1;}
|
||||
int getDhSkyLight(int relX, int relY, int relZ);
|
||||
void setDhSkyLight(int relX, int relY, int relZ, int lightValue);
|
||||
|
||||
int getDhBlockLight(int relX, int relY, int relZ);
|
||||
void setDhBlockLight(int relX, int relY, int relZ, int lightValue);
|
||||
|
||||
int getBlockLight(int relX, int relY, int relZ);
|
||||
int getSkyLight(int relX, int relY, int relZ);
|
||||
|
||||
|
||||
List<DhBlockPos> getBlockLightPosList();
|
||||
|
||||
|
||||
default boolean blockPosInsideChunk(DhBlockPos blockPos) { return this.blockPosInsideChunk(blockPos.x, blockPos.y, blockPos.z); }
|
||||
default boolean blockPosInsideChunk(int x, int y, int z)
|
||||
{
|
||||
return (x >= this.getMinX() && x <= this.getMaxX()
|
||||
return (x >= this.getMinBlockX() && x <= this.getMaxBlockX()
|
||||
&& y >= this.getMinBuildHeight() && y < this.getMaxBuildHeight()
|
||||
&& z >= this.getMinZ() && z <= this.getMaxZ());
|
||||
&& z >= this.getMinBlockZ() && z <= this.getMaxBlockZ());
|
||||
}
|
||||
default boolean blockPosInsideChunk(DhBlockPos2D blockPos)
|
||||
{
|
||||
return (blockPos.x >= this.getMinBlockX() && blockPos.x <= this.getMaxBlockX()
|
||||
&& blockPos.z >= this.getMinBlockZ() && blockPos.z <= this.getMaxBlockZ());
|
||||
}
|
||||
|
||||
boolean doesNearbyChunksExist();
|
||||
boolean doNearbyChunksExist();
|
||||
String toString();
|
||||
|
||||
/** This is a bad hash algorithm, but can be used for rough debugging. */
|
||||
@@ -78,11 +101,12 @@ public interface IChunkWrapper extends IBindable
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
IBlockStateWrapper getBlockState(int x, int y, int z);
|
||||
IBiomeWrapper getBiome(int x, int y, int z);
|
||||
|
||||
DhChunkPos getChunkPos();
|
||||
|
||||
|
||||
default IBlockStateWrapper getBlockState(DhBlockPos pos) { return this.getBlockState(pos.x, pos.y, pos.z); }
|
||||
IBlockStateWrapper getBlockState(int relX, int relY, int relZ);
|
||||
|
||||
IBiomeWrapper getBiome(int relX, int relY, int relZ);
|
||||
|
||||
boolean isStillValid();
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,10 +23,10 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.core.enums.ELodDirection;
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import org.apache.logging.log4j.Level;
|
||||
@@ -57,7 +57,7 @@ public interface IMinecraftClientWrapper extends IBindable
|
||||
// method wrappers //
|
||||
//=================//
|
||||
|
||||
float getShade(ELodDirection lodDirection);
|
||||
float getShade(EDhDirection lodDirection);
|
||||
|
||||
boolean hasSinglePlayerServer();
|
||||
boolean clientConnectedToDedicatedServer();
|
||||
|
||||
@@ -275,10 +275,14 @@
|
||||
"Distance Generator Mode",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.distantGeneratorMode.@tooltip":
|
||||
"How complicated the generation should be when generating LODs outside the vanilla render distance.\n\n§6§6Fastest:§r Biome only\n§6Best Quality:§r Features (suggested)",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.lightingEngine":
|
||||
"distanthorizons.config.client.advanced.worldGenerator.worldGenLightingEngine":
|
||||
"Lighting Engine",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.lightingEngine.@tooltip":
|
||||
"distanthorizons.config.client.advanced.worldGenerator.worldGenLightingEngine.@tooltip":
|
||||
"§6Minecraft:§r use Minecraft's lighting engine, gives accurate lighting.\n§6Distant Horizons:§r estimates lighting, shadows won't be as smooth, but is more stable.\n\nIf the LODs appear black, set this to §6Distant Horizons§r.",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.worldGenerationTimeoutLengthInSeconds":
|
||||
"Timeout Length In Seconds",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.worldGenerationTimeoutLengthInSeconds.@tooltip":
|
||||
"How long should a world generator thread run for before timing out? \nNote: If you are experiencing timeout errors it is better to lower your CPU usage first \nvia the thread config before changing this value.",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.generationPriority":
|
||||
"Generation Priority",
|
||||
"distanthorizons.config.client.advanced.worldGenerator.generationPriority.@tooltip":
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#version 150 core
|
||||
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec3 vertexWorldPos;
|
||||
in float vertexYPos;
|
||||
in vec4 vPos;
|
||||
//in vec2 TexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
@@ -30,6 +27,20 @@ float mixFogThickness(float near, float far, float height);
|
||||
// =========================================================
|
||||
|
||||
|
||||
// Puts steps in a float
|
||||
// EG. setting stepSize to 4 then this would be the result of this function
|
||||
// In: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, ..., 1.1, 1.2, 1.3
|
||||
// Out: 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, ..., 1.0, 1.0, 1.25
|
||||
float quantize(float val, int stepSize) {
|
||||
return floor(val*stepSize)/stepSize;
|
||||
}
|
||||
|
||||
// The modulus function dosnt exist in GLSL so I made my own
|
||||
// To speed up the mod function, this only accepts full numbers for y
|
||||
float mod(float x, int y) {
|
||||
return x - y * floor(x/y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -39,19 +50,39 @@ float mixFogThickness(float near, float far, float height);
|
||||
* version: 2023-6-21
|
||||
*/
|
||||
void main() {
|
||||
float horizontalDist = length(vertexWorldPos.xz) * fogScale;
|
||||
float heightDist = calculateHeightFogDepth(
|
||||
if (fullFogMode != 0) {
|
||||
fragColor = vec4(fogColor.r, fogColor.g, fogColor.b, 1.);
|
||||
} else {
|
||||
float horizontalDist = length(vertexWorldPos.xz) * fogScale;
|
||||
float heightDist = calculateHeightFogDepth(
|
||||
vertexWorldPos.y, vertexYPos) * fogVerticalScale;
|
||||
float farDist = calculateFarFogDepth(horizontalDist,
|
||||
float farDist = calculateFarFogDepth(horizontalDist,
|
||||
length(vertexWorldPos.xyz) * fogScale, nearFogStart);
|
||||
|
||||
float nearFogThickness = getNearFogThickness(horizontalDist);
|
||||
float farFogThickness = getFarFogThickness(farDist);
|
||||
float heightFogThickness = getHeightFogThickness(heightDist);
|
||||
float mixedFogThickness = clamp(mixFogThickness(
|
||||
float nearFogThickness = getNearFogThickness(horizontalDist);
|
||||
float farFogThickness = getFarFogThickness(farDist);
|
||||
float heightFogThickness = getHeightFogThickness(heightDist);
|
||||
float mixedFogThickness = clamp(mixFogThickness(
|
||||
nearFogThickness, farFogThickness, heightFogThickness), 0.0, 1.0);
|
||||
|
||||
fragColor = mix(vertexColor, vec4(fogColor.rgb, 1.0), mixedFogThickness);
|
||||
fragColor = vec4(fogColor.r, fogColor.g, fogColor.b, mixedFogThickness);
|
||||
}
|
||||
|
||||
// Testing
|
||||
// if (fragColor.r != 6969.) { // This line is so that the compiler doesnt delete the previos code
|
||||
//// fragColor = vec4(
|
||||
//// mod(vertexWorldPos.x, 1),
|
||||
//// mod(vertexWorldPos.y, 1),
|
||||
//// mod(vertexWorldPos.z, 1),
|
||||
//// 1.
|
||||
//// );
|
||||
// fragColor = vec4(
|
||||
// mod(vertexYPos, 1),
|
||||
// mod(vertexYPos, 1),
|
||||
// mod(vertexYPos, 1),
|
||||
// 1.
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#version 150 core
|
||||
|
||||
|
||||
//uniform vec3 modelOffset;
|
||||
uniform float worldYOffset;
|
||||
|
||||
in vec2 vPos;
|
||||
in uvec4 vPosition;
|
||||
out vec3 vertexWorldPos;
|
||||
out float vertexYPos;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
// vertexWorldPos = vPosition.xyz + modelOffset;
|
||||
vertexYPos = vPosition.y + worldYOffset;
|
||||
|
||||
gl_Position = vec4(vPos, 1.0, 1.0);
|
||||
}
|
||||
@@ -81,11 +81,11 @@ void main() {
|
||||
);
|
||||
|
||||
// For testing
|
||||
if (vertexColor.r != 69420.) {
|
||||
fragColor = vec4(
|
||||
mod(fixedVPos.x, 1),
|
||||
mod(fixedVPos.y, 1),
|
||||
mod(fixedVPos.z, 1),
|
||||
1f);
|
||||
}
|
||||
// if (vertexColor.r != 69420.) {
|
||||
// fragColor = vec4(
|
||||
// mod(fixedVPos.x, 1),
|
||||
// mod(fixedVPos.y, 1),
|
||||
// mod(fixedVPos.z, 1),
|
||||
// 1f);
|
||||
// }
|
||||
}
|
||||
-4
@@ -3,10 +3,6 @@
|
||||
in vec2 vPos;
|
||||
out vec2 TexCoord;
|
||||
|
||||
out vec4 vertexColor;
|
||||
out vec3 vertexWorldPos;
|
||||
out float vertexYPos;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -9,5 +9,5 @@ uniform sampler2D gSSAOMap;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(0.0, 0.0, 0.0, texture(gSSAOMap, TexCoord).r);
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1-texture(gSSAOMap, TexCoord).r);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#version 150 core
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// A test shader that makes everything darker
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(0., 0., 1., 0.5);
|
||||
}
|
||||
Reference in New Issue
Block a user