diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java index bfe5cfeee..e8ff9818e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java @@ -21,6 +21,7 @@ package com.seibel.distanthorizons.core.api.internal; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelUnloadEvent; +import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.generation.DhLightingEngine; import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; @@ -143,6 +144,12 @@ public class ServerApi public void serverChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper level) { + if (Config.Client.Advanced.Debugging.skipChunkLoadUpdates.get()) + { + return; + } + + // the world should always be non-null, this != null is just in case the world was removed accidentally AbstractDhWorld dhWorld = SharedApi.getAbstractDhWorld(); if (dhWorld != null) @@ -156,6 +163,12 @@ public class ServerApi } public void serverChunkSaveEvent(IChunkWrapper chunkWrapper, ILevelWrapper level) { + if (Config.Client.Advanced.Debugging.skipChunkUnloadUpdates.get()) + { + return; + } + + AbstractDhWorld dhWorld = SharedApi.getAbstractDhWorld(); if (dhWorld == null) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index 1f4f92eb0..62d552d73 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -1176,6 +1176,24 @@ public class Config + "") .build(); + public static ConfigEntry skipChunkLoadUpdates = new ConfigEntry.Builder() + .set(false) + .comment("") + .build(); + + public static ConfigEntry skipChunkUnloadUpdates = new ConfigEntry.Builder() + .set(false) + .comment("") + .build(); + + public static ConfigEntry skipFullDataUpdateQueue = new ConfigEntry.Builder() + .set(false) + .comment("") + .build(); + + + + // can be set to public inorder to show in the config file and UI public static ConfigCategory exampleConfigScreen = new ConfigCategory.Builder() .set(ExampleConfigScreen.class) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java index 469504ffe..168c3e283 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java @@ -76,10 +76,6 @@ public class ColumnRenderBufferBuilder IDhClientLevel clientLevel, Reference renderBufferRef, ColumnRenderSource renderSource, ColumnRenderSource[] adjData) { -/* if (isBusy()) - { - return null; - }*/ //LOGGER.info("RenderRegion startBuild @ "+renderSource.sectionPos); return CompletableFuture.supplyAsync(() -> { @@ -94,11 +90,16 @@ public class ColumnRenderBufferBuilder // FIXME: Clamp also to the max world height. skyLightCullingBelow = Math.max(skyLightCullingBelow, clientLevel.getMinY()); - LodQuadBuilder builder = new LodQuadBuilder(enableSkyLightCulling, - (short) (skyLightCullingBelow - clientLevel.getMinY()), enableTransparency); + long builderStartTime = System.currentTimeMillis(); + + LodQuadBuilder builder = new LodQuadBuilder(enableSkyLightCulling, (short) (skyLightCullingBelow - clientLevel.getMinY()), enableTransparency); makeLodRenderData(builder, renderSource, adjData); - EVENT_LOGGER.trace("RenderRegion end QuadBuild @ " + renderSource.sectionPos); + + long builderEndTime = System.currentTimeMillis(); + long buildMs = builderEndTime - builderStartTime; + LOGGER.debug("RenderRegion end QuadBuild @ " + renderSource.sectionPos + " took: " + buildMs); + return builder; } catch (UncheckedInterruptedException e) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java index 77217e141..11e06b209 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java @@ -51,15 +51,8 @@ public class LodQuadBuilder @SuppressWarnings("unchecked") private final ArrayList[] transparentQuads = (ArrayList[]) new ArrayList[6]; - /** Used to turn transparent LODs above the void opaque to prevent seeing the void. */ - private final short[] minOpaqueHeightByRelativePos = new short[SECTION_WIDTH * SECTION_WIDTH]; - /** See {@link LodQuadBuilder#minOpaqueHeightByRelativePos} */ - private final short[] minTransparentHeightByRelativePos = new short[SECTION_WIDTH * SECTION_WIDTH]; - private final boolean doTransparency; - private static int SECTION_WIDTH = 4096; - public static final int[][][] DIRECTION_VERTEX_IBO_QUAD = new int[][][] @@ -131,13 +124,6 @@ public class LodQuadBuilder this.skipQuadsWithZeroSkylight = enableSkylightCulling; this.skyLightCullingBelow = skyLightCullingBelow; - // set the default values - for (int i = 0; i < SECTION_WIDTH * SECTION_WIDTH; i++) - { - // the default height is MAX_VALUE to preserve the comparison logic later - this.minOpaqueHeightByRelativePos[i] = Short.MAX_VALUE; - this.minTransparentHeightByRelativePos[i] = Short.MAX_VALUE; - } } @@ -177,49 +163,25 @@ public class LodQuadBuilder } // XZ - public void addQuadUp(short x, short y, 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 skylight, byte blocklight) // TODO argument names are wrong { // cave culling - if (this.skipQuadsWithZeroSkylight && skylight == 0 && y < this.skyLightCullingBelow) + if (this.skipQuadsWithZeroSkylight && skylight == 0 && maxY < this.skyLightCullingBelow) { return; } - BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, EDhDirection.UP); + BufferQuad quad = new BufferQuad(x, maxY, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, EDhDirection.UP); boolean isTransparent = (this.doTransparency && ColorUtil.getAlpha(color) < 255); ArrayList quadList = isTransparent ? this.transparentQuads[EDhDirection.UP.ordinal()] : this.opaqueQuads[EDhDirection.UP.ordinal()]; - // update the minimum relative height for this quad's positions - for (int xRel = x; xRel < (x + widthEastWest); xRel++) - { - for (int zRel = z; zRel < (z + widthNorthSouthOrUpDown); zRel++) - { - int relPosIndex = relativeQuadPosToIndex(xRel, zRel); - - short[] minHeightByRelativePos = isTransparent ? this.minTransparentHeightByRelativePos : this.minOpaqueHeightByRelativePos; - - try - { - short currentHeight = minHeightByRelativePos[relPosIndex]; - minHeightByRelativePos[relPosIndex] = (short) Math.min(currentHeight, quad.y); - } - catch (IndexOutOfBoundsException e) - { - // shouldn't happen normally, just in case James screwed up something. - // This can be removed once the indexes have been proven not to go outside the expected range - LOGGER.error("Relative Pos index out of bounds. Array length: ["+minHeightByRelativePos.length+"], given index: ["+relPosIndex+"], xRel: ["+xRel+"], zRel: ["+zRel+"], max expected rel value: ["+ SECTION_WIDTH +"].", e); - } - } - } - - // attempt to merge this quad with adjacent ones if (!quadList.isEmpty() && ( - quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.EastWest) - || quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown)) - ) + quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.EastWest) + || quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown)) + ) { this.premergeCount++; return; @@ -339,14 +301,7 @@ public class LodQuadBuilder //=================// /** runs any final data cleanup, merging, etc. */ - public void finalizeData() - { - this.mergeQuads(); - if (this.doTransparency) - { - this.fixTransparencyOverVoid(); // should happen after merging - } - } + public void finalizeData() { this.mergeQuads(); } /** Uses Greedy meshing to merge this builder's Quads. */ public void mergeQuads() @@ -414,38 +369,6 @@ public class LodQuadBuilder } - /** makes any transparent LODs that are over the void opaque to prevent seeing the void through them. */ - public void fixTransparencyOverVoid() - { - // make transparent LODs opaque if they are over the void - ListIterator iter = this.transparentQuads[EDhDirection.UP.ordinal()].listIterator(); - if (iter.hasNext()) - { - BufferQuad currentQuad = iter.next(); - while (iter.hasNext()) - { - int relPosIndex = relativeQuadPosToIndex(currentQuad.x, currentQuad.z); - - short minOpaqueHeight = this.minOpaqueHeightByRelativePos[relPosIndex]; - short minTransHeight = this.minTransparentHeightByRelativePos[relPosIndex]; - - - if (currentQuad.y < minOpaqueHeight && currentQuad.y == minTransHeight) - { - // transparent quad is at the bottom, make it opaque to prevent seeing through the world - currentQuad.color = ColorUtil.setAlpha(currentQuad.color, 255); - - // 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[EDhDirection.UP.ordinal()].add(currentQuad); - } - - currentQuad = iter.next(); - } - } - } - - //==============// // buffer setup // @@ -799,14 +722,4 @@ public class LodQuadBuilder return MathUtil.ceilDiv(this.getCurrentTransparentQuadsCount(), AbstractRenderBuffer.MAX_QUADS_PER_BUFFER); } - - - //================// - // helper methods // - //================// - - /** Converts a 2D position into a 1D array index. */ - public static int relativeQuadPosToIndex(int xRel, int zRel) { return xRel + zRel * SECTION_WIDTH; } - - } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java index d9278e32a..43fa3825a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java @@ -28,6 +28,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantReadWriteLock; +import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource; @@ -508,6 +509,11 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I @SuppressWarnings("resource") // due to DataObjTracker and DataObjSoftTracker being created outside a try-catch block private CompletableFuture applyWriteQueueAndSaveAsync(IFullDataSource fullDataSourceToUpdate) { + if (Config.Client.Advanced.Debugging.skipFullDataUpdateQueue.get()) + { + return CompletableFuture.completedFuture(fullDataSourceToUpdate); + } + CompletableFuture completionFuture = new CompletableFuture<>(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java index 2971ac581..5d0e01e52 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java @@ -34,8 +34,10 @@ public class GLState public int activeTextureNumber; public int texture0; public boolean blend; - public int blendSrc; - public int blendDst; + public int blendSrcColor; + public int blendSrcAlpha; + public int blendDstColor; + public int blendDstAlpha; public boolean depth; public boolean writeToDepthBuffer; public int depthFunc; @@ -64,8 +66,10 @@ public class GLState this.texture0 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); GL32.glActiveTexture(this.activeTextureNumber); this.blend = GL32.glIsEnabled(GL32.GL_BLEND); - this.blendSrc = GL32.glGetInteger(GL32.GL_BLEND_SRC); - this.blendDst = GL32.glGetInteger(GL32.GL_BLEND_DST); + this.blendSrcColor = GL32.glGetInteger(GL32.GL_BLEND_SRC_RGB); + this.blendSrcAlpha = GL32.glGetInteger(GL32.GL_BLEND_SRC_ALPHA); + this.blendDstColor = GL32.glGetInteger(GL32.GL_BLEND_DST_RGB); + this.blendDstAlpha = GL32.glGetInteger(GL32.GL_BLEND_DST_ALPHA); this.depth = GL32.glIsEnabled(GL32.GL_DEPTH_TEST); this.writeToDepthBuffer = GL32.glGetInteger(GL32.GL_DEPTH_WRITEMASK) == GL32.GL_TRUE; this.depthFunc = GL32.glGetInteger(GL32.GL_DEPTH_FUNC); @@ -86,7 +90,7 @@ public class GLState return "GLState{" + "prog=" + this.prog + ", vao=" + this.vao + ", vbo=" + this.vbo + ", ebo=" + this.ebo + ", fbo=" + this.fbo + ", text=" + GLEnums.getString(this.texture2D) + "@" + this.activeTextureNumber + ", text0=" + GLEnums.getString(this.texture0) + - ", blend=" + this.blend + ", blendMode=" + GLEnums.getString(this.blendSrc) + "," + GLEnums.getString(this.blendDst) + + ", blend=" + this.blend + ", blendMode=" + GLEnums.getString(this.blendSrcColor) + "," + GLEnums.getString(this.blendDstColor) + ", depth=" + this.depth + ", depthFunc=" + GLEnums.getString(this.depthFunc) + ", stencil=" + this.stencil + ", stencilFunc=" + GLEnums.getString(this.stencilFunc) + ", stencilRef=" + this.stencilRef + ", stencilMask=" + this.stencilMask + @@ -119,7 +123,9 @@ public class GLState GL32.glUseProgram(GL32.glIsProgram(this.prog) ? this.prog : 0); GL32.glDepthMask(this.writeToDepthBuffer); - GL32.glBlendFunc(this.blendSrc, this.blendDst); + //GL32.glBlendFunc(this.blendSrcColor, this.blendDstColor); + GL32.glBlendFuncSeparate(this.blendSrcColor, this.blendDstColor, this.blendSrcAlpha, this.blendDstAlpha); + if (this.depth) { GL32.glEnable(GL32.GL_DEPTH_TEST);