diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 1cf15ddf7..ad24f4f68 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -82,9 +82,6 @@ public class LodBufferBuilder */ public volatile VertexBuffer[][] drawableVbos; - public GlProxyContext buildingContext = GlProxyContext.ALPHA; - public GlProxyContext renderContext = GlProxyContext.BETA; - /** * if this is true the LOD buffers are currently being * regenerated. @@ -459,8 +456,11 @@ public class LodBufferBuilder */ private void uploadBuffers(boolean fullRegen, LodDimension lodDim) { - GlProxy.getInstance().setGlContext(buildingContext); - // used to prevent debug printing multiple times per upload cycle + GlProxy glProxy = GlProxy.getInstance(); + // make sure we are uploading to a different OpenGL context, + // to prevent interference (IE stuttering) with the Minecraft context. + glProxy.setGlContext(GlProxyContext.LOD_BUILDER); + // only print console debugging for vboUpload once per upload cycle boolean bufferMapFail = false; @@ -481,7 +481,7 @@ public class LodBufferBuilder // make sure all the buffers have been uploaded. // this probably is necessary, but it makes me feel good :) GL11.glFlush(); - GlProxy.getInstance().setGlContext(GlProxyContext.NONE); + glProxy.setGlContext(GlProxyContext.NONE); } /** @@ -520,7 +520,7 @@ public class LodBufferBuilder // only print to console once per upload cycle if (!bufferMapFail) - ClientProxy.LOGGER.debug("LOD buffer upload glMapBuffer failed, using slower glBufferData."); + ClientProxy.LOGGER.debug("LOD buffer upload: glMapBuffer failed, used slower glBufferData."); bufferMapFail = true; } @@ -547,10 +547,6 @@ public class LodBufferBuilder drawableVbos = buildableVbos; buildableVbos = tmpVbo; - GlProxyContext tmpContext = renderContext; - renderContext = buildingContext; - buildingContext = tmpContext; - drawableCenterChunkPos = buildableCenterChunkPos; // the vbos have been swapped @@ -558,7 +554,7 @@ public class LodBufferBuilder bufferLock.unlock(); } - return new VertexBuffersAndOffset(drawableVbos, drawableCenterChunkPos, renderContext); + return new VertexBuffersAndOffset(drawableVbos, drawableCenterChunkPos); } /** @@ -568,13 +564,11 @@ public class LodBufferBuilder { public VertexBuffer[][] vbos; public ChunkPos drawableCenterChunkPos; - public GlProxyContext drawingContext; - public VertexBuffersAndOffset(VertexBuffer[][] newVbos, ChunkPos newDrawableCenterChunkPos, GlProxyContext newDrawingContext) + public VertexBuffersAndOffset(VertexBuffer[][] newVbos, ChunkPos newDrawableCenterChunkPos) { vbos = newVbos; drawableCenterChunkPos = newDrawableCenterChunkPos; - drawingContext = newDrawingContext; } } diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 6a908b308..68f2918a1 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -27,7 +27,6 @@ import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker; import com.seibel.lod.builders.worldGeneration.LodWorldGenerator; import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; -import com.seibel.lod.enums.LodDetail; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodWorld; import com.seibel.lod.objects.RegionPos; @@ -47,15 +46,17 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; /** * This handles all events sent to the client, - * and is the starting point for most of this program. + * and is the starting point for most of the mod. * * @author James_Seibel - * @version 8-24-2021 + * @version 9-14-2021 */ public class ClientProxy { public static final Logger LOGGER = LogManager.getLogger("LOD"); + private boolean firstTimeSetupComplete = false; + private static LodWorld lodWorld = new LodWorld(); private static LodBuilder lodBuilder = new LodBuilder(); private static LodBufferBuilder lodBufferBuilder = new LodBufferBuilder(); @@ -64,7 +65,7 @@ public class ClientProxy private boolean configOverrideReminderPrinted = false; - MinecraftWrapper mc = MinecraftWrapper.INSTANCE; + private MinecraftWrapper mc = MinecraftWrapper.INSTANCE; /** @@ -99,7 +100,13 @@ public class ClientProxy */ public void renderLods(float partialTicks) { - GlProxy.getInstance(); + // only run the first time setup once + if (firstTimeSetupComplete) + { + firstFrameSetup(); + } + + DetailDistanceUtil.updateSettings(); if (mc == null || mc.getPlayer() == null || !lodWorld.getIsWorldLoaded()) @@ -113,8 +120,6 @@ public class ClientProxy playerMoveEvent(lodDim); - //System.out.println("memory needed " + lodDim.getMinMemoryNeeded() + " byte"); - //System.out.println(lodDim); lodDim.treeCutter((int) mc.getPlayer().getX(), (int) mc.getPlayer().getZ()); lodDim.treeGenerator((int) mc.getPlayer().getX(), (int) mc.getPlayer().getZ()); @@ -135,7 +140,7 @@ public class ClientProxy renderer.drawLODs(lodDim, partialTicks, mc.getProfiler()); profiler.pop(); // end LOD - profiler.push("terrain"); // restart "terrain" + profiler.push("terrain"); // go back into "terrain" // these can't be set until after the buffers are built (in renderer.drawLODs) @@ -157,8 +162,8 @@ public class ClientProxy //LodConfig.CLIENT.drawLODs.set(true); //LodConfig.CLIENT.debugMode.set(true); - LodConfig.CLIENT.graphics.maxDrawDetail.set(LodDetail.FULL); - LodConfig.CLIENT.worldGenerator.maxGenerationDetail.set(LodDetail.FULL); +// LodConfig.CLIENT.graphics.maxDrawDetail.set(LodDetail.FULL); +// LodConfig.CLIENT.worldGenerator.maxGenerationDetail.set(LodDetail.FULL); // LodConfig.CLIENT.graphics.fogDistance.set(FogDistance.FAR); // LodConfig.CLIENT.graphics.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY); @@ -167,14 +172,14 @@ public class ClientProxy // LodConfig.CLIENT.graphics.saturationMultiplier.set(1.0); // LodConfig.CLIENT.worldGenerator.distanceGenerationMode.set(DistanceGenerationMode.SURFACE); - LodConfig.CLIENT.graphics.lodChunkRenderDistance.set(256); +// LodConfig.CLIENT.graphics.lodChunkRenderDistance.set(64); // LodConfig.CLIENT.worldGenerator.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR); - LodConfig.CLIENT.graphics.lodQuality.set(3); +// LodConfig.CLIENT.graphics.lodQuality.set(2); // LodConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.set(false); - LodConfig.CLIENT.buffers.bufferRebuildPlayerMoveTimeout.set(2000); // 2000 - LodConfig.CLIENT.buffers.bufferRebuildChunkChangeTimeout.set(1000); // 1000 - LodConfig.CLIENT.buffers.bufferRebuildLodChangeTimeout.set(5000); // 5000 +// LodConfig.CLIENT.buffers.bufferRebuildPlayerMoveTimeout.set(2000); // 2000 +// LodConfig.CLIENT.buffers.bufferRebuildChunkChangeTimeout.set(1000); // 1000 +// LodConfig.CLIENT.buffers.bufferRebuildLodChangeTimeout.set(5000); // 5000 LodConfig.CLIENT.debugging.enableDebugKeybinding.set(true); } @@ -267,10 +272,9 @@ public class ClientProxy } - - //==================// - // frame LOD events // - //==================// + //============// + // LOD events // + //============// /** * Re-centers the given LodDimension if it needs to be. @@ -315,6 +319,20 @@ public class ClientProxy DetailDistanceUtil.updateSettings(); } + + /** + * This event is called once during the first frame Minecraft renders in the world. + */ + public void firstFrameSetup() + { + // make sure the GlProxy is created before the LodBufferBuilder + GlProxy.getInstance(); + + + + firstTimeSetupComplete = true; + } + //================// diff --git a/src/main/java/com/seibel/lod/proxy/GlProxy.java b/src/main/java/com/seibel/lod/proxy/GlProxy.java index 8a9ffddf8..bc529943c 100644 --- a/src/main/java/com/seibel/lod/proxy/GlProxy.java +++ b/src/main/java/com/seibel/lod/proxy/GlProxy.java @@ -7,7 +7,8 @@ import org.lwjgl.opengl.WGL; import com.mojang.blaze3d.systems.RenderSystem; /** - * A singleton that holds references to different openGL contexts. + * A singleton that holds references to different openGL contexts + * and GPU capabilities. * *
* Helpful OpenGL resources:
@@ -31,8 +32,13 @@ public class GlProxy
public long lodBuilderGlContext;
public GLCapabilities lodBuilderGlCapabilities;
- public long lodRenderGlContext;
- public GLCapabilities lodRenderGlCapabilities;
+
+ /**
+ * Does this computer's GPU support fancy fog?
+ */
+ public final boolean fancyFogAvailable;
+
+
private GlProxy()
{
@@ -42,6 +48,12 @@ public class GlProxy
throw new IllegalStateException(GlProxy.class.getSimpleName() + " was created outside the render thread!");
+
+
+ //============================//
+ // create the builder context //
+ //============================//
+
minecraftGlContext = WGL.wglGetCurrentContext();
minecraftGlCapabilities = GL.getCapabilities();
deviceContext = WGL.wglGetCurrentDC();
@@ -50,22 +62,28 @@ public class GlProxy
if (!WGL.wglShareLists(minecraftGlContext, lodBuilderGlContext))
throw new IllegalStateException("Unable to share lists between Minecraft and builder contexts.");
if (!WGL.wglMakeCurrent(deviceContext, lodBuilderGlContext))
- throw new IllegalStateException("Unable to change OpenGL contexts! tried to change to [" + GlProxyContext.ALPHA.toString() + "] from [" + GlProxyContext.MINECRAFT.toString() + "]");
+ throw new IllegalStateException("Unable to change OpenGL contexts! tried to change to [" + GlProxyContext.LOD_BUILDER.toString() + "] from [" + GlProxyContext.MINECRAFT.toString() + "]");
lodBuilderGlCapabilities = GL.createCapabilities();
WGL.wglMakeCurrent(deviceContext, 0L);
-
-
-
- lodRenderGlContext = WGL.wglCreateContext(deviceContext);
- if (!WGL.wglShareLists(minecraftGlContext, lodRenderGlContext))
- throw new IllegalStateException("Unable to share lists between builder and render contexts.");
- if (!WGL.wglMakeCurrent(deviceContext, lodRenderGlContext))
- throw new IllegalStateException("Unable to change OpenGL contexts! tried to change to [" + GlProxyContext.ALPHA.toString() + "] from [" + GlProxyContext.BETA.toString() + "]");
- lodRenderGlCapabilities = GL.createCapabilities();
// Since this is called on the render thread, make sure the Minecraft context is used in the end
WGL.wglMakeCurrent(deviceContext, minecraftGlContext);
+
+
+
+
+ //==================================//
+ // get any GPU related capabilities //
+ //==================================//
+
+ // see if this GPU can run fancy fog
+ fancyFogAvailable = GL.getCapabilities().GL_NV_fog_distance;
+
+ if (!fancyFogAvailable)
+ {
+ ClientProxy.LOGGER.info("This GPU does not support GL_NV_fog_distance. This means that the fancy fog option will not be available.");
+ }
}
@@ -80,14 +98,10 @@ public class GlProxy
GLCapabilities newGlCapabilities = null;
switch(context)
{
- case ALPHA:
+ case LOD_BUILDER:
contextPointer = lodBuilderGlContext;
newGlCapabilities = lodBuilderGlCapabilities;
break;
- case BETA:
- contextPointer = lodRenderGlContext;
- newGlCapabilities = lodRenderGlCapabilities;
- break;
case MINECRAFT:
contextPointer = minecraftGlContext;
newGlCapabilities = minecraftGlCapabilities;
@@ -111,11 +125,7 @@ public class GlProxy
long currentContext = WGL.wglGetCurrentContext();
if(currentContext == lodBuilderGlContext)
{
- return GlProxyContext.ALPHA;
- }
- else if(currentContext == lodRenderGlContext)
- {
- return GlProxyContext.BETA;
+ return GlProxyContext.LOD_BUILDER;
}
else if(currentContext == minecraftGlContext)
{
@@ -130,8 +140,7 @@ public class GlProxy
public enum GlProxyContext
{
MINECRAFT,
- ALPHA,
- BETA,
+ LOD_BUILDER,
/** used to un-bind threads */
NONE,
diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java
index 6b80091fd..918281b1f 100644
--- a/src/main/java/com/seibel/lod/render/LodRenderer.java
+++ b/src/main/java/com/seibel/lod/render/LodRenderer.java
@@ -23,7 +23,6 @@ import java.nio.FloatBuffer;
import java.util.HashSet;
import java.util.Iterator;
-import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL15C;
@@ -95,13 +94,7 @@ public class LodRenderer
* https://stackoverflow.com/questions/50499238/bytebuffer-allocatedirect-and-xmx
*/
public static final int MAX_ALOCATEABLE_DIRECT_MEMORY = 64 * 1024 * 1024;
-
- /**
- * Does this computer's GPU support fancy fog?
- */
- private static Boolean fancyFogAvailable = null;
- private static GlProxy glProxy;
-
+
/**
* If true the LODs colors will be replaced with
* a checkerboard, this can be used for debugging.
@@ -189,25 +182,8 @@ public class LodRenderer
profiler = newProfiler;
profiler.push("LOD setup");
-
-
- // only check the GPU capability's once
- if (fancyFogAvailable == null)
- {
- //TODO add this to the GlProxy
- // see if this GPU can run fancy fog
- fancyFogAvailable = GL.getCapabilities().GL_NV_fog_distance;
-
- if (!fancyFogAvailable)
- {
- ClientProxy.LOGGER.info("This GPU does not support GL_NV_fog_distance. This means that fancy fog options will not be available.");
- }
-
- // create the GlProxy TODO this should probably be done somewhere else
- glProxy = GlProxy.getInstance();
- }
-
-
+
+
// TODO move the buffer regeneration logic into its own class (probably called in the client proxy instead)
// starting here...
determineIfLodsShouldRegenerate(lodDim);
@@ -243,11 +219,6 @@ public class LodRenderer
swapBuffers();
}
- if (renderContext == null)
- {
- return;
- }
-
//===========================//
@@ -738,7 +709,7 @@ public class LodRenderer
// only use fancy fog if the user's GPU can deliver
- if (!fancyFogAvailable && quality == FogQuality.FANCY)
+ if (!GlProxy.getInstance().fancyFogAvailable && quality == FogQuality.FANCY)
{
quality = FogQuality.FAST;
}