Improve rendering performance and improve buffer building stability
Specifically improve the rendering speed so we can get over 100 fps again.
This commit is contained in:
@@ -26,14 +26,13 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.seibel.lod.enums.LodQualityMode;
|
||||
import com.seibel.lod.util.*;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL15C;
|
||||
|
||||
import com.seibel.lod.builders.lodTemplates.Box;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.LodQualityMode;
|
||||
import com.seibel.lod.objects.LodDimension;
|
||||
import com.seibel.lod.objects.LodRegion;
|
||||
import com.seibel.lod.objects.PosToRenderContainer;
|
||||
@@ -42,9 +41,12 @@ import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.proxy.GlProxy;
|
||||
import com.seibel.lod.proxy.GlProxy.GlProxyContext;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodThreadFactory;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.vertex.VertexBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
@@ -53,7 +55,7 @@ import net.minecraft.util.math.ChunkPos;
|
||||
* This object is used to create NearFarBuffer objects.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 9-14-2021
|
||||
* @version 9-15-2021
|
||||
*/
|
||||
public class LodBufferBuilder
|
||||
{
|
||||
@@ -370,6 +372,9 @@ public class LodBufferBuilder
|
||||
e.printStackTrace();
|
||||
} finally
|
||||
{
|
||||
// make sure the context is disabled
|
||||
GlProxy.getInstance().setGlContext(GlProxyContext.NONE);
|
||||
|
||||
// regardless of if we successfully created the buffers
|
||||
// we are done generating.
|
||||
generatingBuffers = false;
|
||||
@@ -512,43 +517,27 @@ public class LodBufferBuilder
|
||||
// this shouldn't happen, but just to be safe
|
||||
if (vbo.id != -1)
|
||||
{
|
||||
vbo.vertexCount = uploadBuffer.remaining() / vbo.format.getVertexSize();
|
||||
|
||||
|
||||
// this is how many points will be rendered
|
||||
vbo.vertexCount = (uploadBuffer.remaining() / vbo.format.getVertexSize());
|
||||
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id);
|
||||
|
||||
|
||||
// make sure enough space is allocated to fit the builderBuffer
|
||||
GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, uploadBuffer.capacity(), GL15C.GL_DYNAMIC_DRAW);
|
||||
// try to get a pointer to the VBO's byteBuffer in GPU memory
|
||||
ByteBuffer vboBuffer = GL15C.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
||||
|
||||
// upload the builderBuffer to the GPU
|
||||
if (vboBuffer != null)
|
||||
{
|
||||
// This is the best way to upload lots of data, since writes directly to GPU
|
||||
// memory, and doesn't pause OpenGL.
|
||||
vboBuffer.put(uploadBuffer);
|
||||
} else
|
||||
{
|
||||
// Sometimes the vboBuffer is null (I think it may be due to buffer sizes
|
||||
// changing or a setup process that didn't complete), so in that case
|
||||
// we have to use this method which is slower and pauses OpenGL,
|
||||
// but always succeeds.
|
||||
GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, uploadBuffer, GL15C.GL_DYNAMIC_DRAW);
|
||||
|
||||
// only print to console once per upload cycle
|
||||
if (!bufferMapFail)
|
||||
ClientProxy.LOGGER.debug("LOD buffer upload: glMapBuffer failed, used slower glBufferData.");
|
||||
bufferMapFail = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// subData only works if the memory is allocated beforehand.
|
||||
GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, uploadBuffer.remaining(), GL15C.GL_DYNAMIC_DRAW);
|
||||
|
||||
// interestingly bufferSubData renders faster than glMapBuffer
|
||||
// even though OpenGLInsights-AsynchronousBufferTransfers says glMapBuffer
|
||||
// is faster for transferring data. They must put the data in different memory
|
||||
// or something.
|
||||
GL15C.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
|
||||
|
||||
|
||||
GL15C.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// just used to improve debug printing
|
||||
return bufferMapFail;
|
||||
}
|
||||
|
||||
@@ -166,8 +166,11 @@ 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);
|
||||
// requires a world restart?
|
||||
// LodConfig.CLIENT.worldGenerator.lodQualityMode.set(LodQualityMode.HEIGHTMAP);
|
||||
|
||||
// LodConfig.CLIENT.graphics.fogDistance.set(FogDistance.FAR);
|
||||
// LodConfig.CLIENT.graphics.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
*
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 9-14-2021
|
||||
* @version 9-15-2021
|
||||
*/
|
||||
public class GlProxy
|
||||
{
|
||||
@@ -90,13 +90,18 @@ public class GlProxy
|
||||
/**
|
||||
* A simple wrapper function to make switching contexts easier
|
||||
*/
|
||||
public void setGlContext(GlProxyContext context)
|
||||
public void setGlContext(GlProxyContext newContext)
|
||||
{
|
||||
GlProxyContext currentContext = getGlContext();
|
||||
|
||||
// we don't have to change the context, we're already there.
|
||||
if (currentContext == newContext)
|
||||
return;
|
||||
|
||||
|
||||
long contextPointer = 0L;
|
||||
GLCapabilities newGlCapabilities = null;
|
||||
switch(context)
|
||||
switch(newContext)
|
||||
{
|
||||
case LOD_BUILDER:
|
||||
contextPointer = lodBuilderGlContext;
|
||||
@@ -116,10 +121,11 @@ public class GlProxy
|
||||
}
|
||||
|
||||
if (!WGL.wglMakeCurrent(deviceContext, contextPointer))
|
||||
throw new IllegalStateException("Unable to change OpenGL contexts! tried to change to [" + context.toString() + "] from [" + currentContext.toString() + "]");
|
||||
throw new IllegalStateException("Unable to change OpenGL contexts! tried to change to [" + newContext.toString() + "] from [" + currentContext.toString() + "]");
|
||||
|
||||
GL.setCapabilities(newGlCapabilities);
|
||||
}
|
||||
|
||||
public GlProxyContext getGlContext()
|
||||
{
|
||||
long currentContext = WGL.wglGetCurrentContext();
|
||||
@@ -136,6 +142,7 @@ public class GlProxy
|
||||
return GlProxyContext.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/** Minecraft, Alpha, Beta, None */
|
||||
public enum GlProxyContext
|
||||
{
|
||||
|
||||
@@ -267,6 +267,7 @@ public class LodRenderer
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
profiler.popPush("LOD draw");
|
||||
|
||||
if (vbos != null)
|
||||
|
||||
Reference in New Issue
Block a user