Fully add multi-context uploading
This commit is contained in:
@@ -30,7 +30,6 @@ import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL15C;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.seibel.lod.builders.lodTemplates.Box;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.objects.DataPoint;
|
||||
@@ -55,7 +54,7 @@ import net.minecraft.util.math.ChunkPos;
|
||||
* This object is used to create NearFarBuffer objects.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 8-24-2021
|
||||
* @version 9-14-2021
|
||||
*/
|
||||
public class LodBufferBuilder
|
||||
{
|
||||
@@ -68,7 +67,6 @@ public class LodBufferBuilder
|
||||
*/
|
||||
public static ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfBufferBuilderThreads.get(), new LodThreadFactory(LodBufferBuilder.class.getSimpleName() + " - builder"));
|
||||
|
||||
public volatile ByteBuffer clearByteBuffer;
|
||||
/**
|
||||
* The buffers that are used to create LODs using far fog
|
||||
*/
|
||||
@@ -84,8 +82,8 @@ public class LodBufferBuilder
|
||||
*/
|
||||
public volatile VertexBuffer[][] drawableVbos;
|
||||
|
||||
public GlProxyContext buildingContext = GlProxyContext.BUILDER;
|
||||
public GlProxyContext renderContext = GlProxyContext.RENDER;
|
||||
public GlProxyContext buildingContext = GlProxyContext.ALPHA;
|
||||
public GlProxyContext renderContext = GlProxyContext.BETA;
|
||||
|
||||
/**
|
||||
* if this is true the LOD buffers are currently being
|
||||
@@ -397,8 +395,6 @@ public class LodBufferBuilder
|
||||
buildableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide];
|
||||
drawableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide];
|
||||
|
||||
clearByteBuffer = new BufferBuilder(bufferMaxCapacity).buffer;
|
||||
clearByteBuffer.position(clearByteBuffer.limit()-1);
|
||||
|
||||
for (int x = 0; x < numbRegionsWide; x++)
|
||||
{
|
||||
@@ -406,17 +402,8 @@ public class LodBufferBuilder
|
||||
{
|
||||
buildableBuffers[x][z] = new BufferBuilder(bufferMaxCapacity);
|
||||
|
||||
|
||||
buildableVbos[x][z] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
|
||||
drawableVbos[x][z] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableVbos[x][z].id);
|
||||
GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, bufferMaxCapacity, GL15C.GL_DYNAMIC_DRAW);
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, drawableVbos[x][z].id);
|
||||
GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, bufferMaxCapacity, GL15C.GL_DYNAMIC_DRAW);
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,6 +432,7 @@ public class LodBufferBuilder
|
||||
private void startBuffers(boolean fullRegen, LodDimension lodDim)
|
||||
{
|
||||
for (int x = 0; x < buildableBuffers.length; x++)
|
||||
{
|
||||
for (int z = 0; z < buildableBuffers.length; z++)
|
||||
{
|
||||
if (fullRegen || lodDim.regen[x][z])
|
||||
@@ -452,6 +440,7 @@ public class LodBufferBuilder
|
||||
buildableBuffers[x][z].begin(GL11.GL_QUADS, LodRenderer.LOD_VERTEX_FORMAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,86 +450,88 @@ public class LodBufferBuilder
|
||||
{
|
||||
for (int x = 0; x < buildableBuffers.length; x++)
|
||||
for (int z = 0; z < buildableBuffers.length; z++)
|
||||
|
||||
if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building() && (fullRegen || lodDim.regen[x][z]))
|
||||
{
|
||||
buildableBuffers[x][z].end();
|
||||
}
|
||||
buildableBuffers[x][z].end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the LodRenderer to create the
|
||||
* BufferBuilders at the right size.
|
||||
* Upload all buildableBuffers to the GPU.
|
||||
*/
|
||||
private void uploadBuffers(boolean fullRegen, LodDimension lodDim)
|
||||
{
|
||||
GlProxy.getInstance().setGlContext(buildingContext);
|
||||
// used to prevent debug printing multiple times per upload cycle
|
||||
boolean bufferMapFail = false;
|
||||
|
||||
|
||||
for (int x = 0; x < buildableVbos.length; x++)
|
||||
{
|
||||
for (int z = 0; z < buildableVbos.length; z++)
|
||||
{
|
||||
// if (fullRegen || lodDim.regen[x][z])
|
||||
// {
|
||||
vboUpload(x, z, lodDim, buildableVbos);
|
||||
if (fullRegen || lodDim.regen[x][z])
|
||||
{
|
||||
ByteBuffer builderBuffer = buildableBuffers[x][z].popNextBuffer().getSecond();
|
||||
bufferMapFail = vboUpload(buildableVbos[x][z], builderBuffer, bufferMapFail);
|
||||
lodDim.regen[x][z] = false;
|
||||
// }// regen region
|
||||
}// z
|
||||
}// x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
public void vboUpload(int xLocal, int zLocal, LodDimension lodDim, VertexBuffer[][] buildableVbos)
|
||||
/**
|
||||
* Uploads the uploadBuffer into the VBO in GPU memory.
|
||||
*/
|
||||
private boolean vboUpload(VertexBuffer vbo, ByteBuffer uploadBuffer, boolean bufferMapFail)
|
||||
{
|
||||
VertexBuffer vbo = buildableVbos[xLocal][zLocal];
|
||||
BufferBuilder bufferBuilder = buildableBuffers[xLocal][zLocal];
|
||||
GlProxyContext test = GlProxy.getInstance().getGlContext();
|
||||
|
||||
long start = System.nanoTime();
|
||||
long end = start;
|
||||
|
||||
// this shouldn't happen, but just to be safe
|
||||
if (vbo.id != -1)
|
||||
{
|
||||
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popNextBuffer();
|
||||
|
||||
ByteBuffer bytebuffer = pair.getSecond();
|
||||
vbo.vertexCount = bytebuffer.remaining() / vbo.format.getVertexSize();
|
||||
|
||||
if (xLocal == 0 && zLocal == 0) while (GL11.glGetError() != GL11.GL_NO_ERROR) {}
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id); // 34962 = 0x8892 = GL_ARRAY_BUFFER
|
||||
// ByteBuffer vboBuffer = GL15C.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
||||
|
||||
GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, bytebuffer, GL15C.GL_STATIC_DRAW);
|
||||
|
||||
// clearByteBuffer.position(0);
|
||||
// clearByteBuffer.position(clearByteBuffer.limit()-1);
|
||||
//clearByteBuffer
|
||||
|
||||
// GL15C.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0L, clearByteBuffer);
|
||||
GL15C.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0L, bytebuffer);
|
||||
vbo.vertexCount = uploadBuffer.remaining() / vbo.format.getVertexSize();
|
||||
|
||||
|
||||
// long bufferSize = GL43C.glGetBufferParameteri64(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
|
||||
// GL43C.glClearBufferSubData(GL15.GL_ARRAY_BUFFER, GL43., 0, bufferSize, GL11.GL_RGB, GL11.GL_FLOAT, (ByteBuffer) null);
|
||||
// if (xLocal == 0 && zLocal == 0) ClientProxy.LOGGER.info("err: " + GL11.glGetError());
|
||||
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, using slower glBufferData.");
|
||||
bufferMapFail = true;
|
||||
}
|
||||
|
||||
|
||||
GL15C.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
// GL15C.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
end = System.nanoTime();
|
||||
|
||||
|
||||
|
||||
if (xLocal == 0 && zLocal == 0)
|
||||
{
|
||||
double time = (end - start) * 0.000001 * lodDim.getWidth() * lodDim.getWidth();
|
||||
ClientProxy.LOGGER.info("upload: " + time + "\t" + test);
|
||||
}
|
||||
// just used to improve debug printing
|
||||
return bufferMapFail;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -552,24 +543,21 @@ public class LodBufferBuilder
|
||||
// since this is called on the main render thread
|
||||
if (bufferLock.tryLock())
|
||||
{
|
||||
VertexBuffer[][] tmp = drawableVbos;
|
||||
VertexBuffer[][] tmpVbo = drawableVbos;
|
||||
drawableVbos = buildableVbos;
|
||||
buildableVbos = tmp;
|
||||
buildableVbos = tmpVbo;
|
||||
|
||||
GlProxyContext context = renderContext;
|
||||
GlProxyContext tmpContext = renderContext;
|
||||
renderContext = buildingContext;
|
||||
buildingContext = context;
|
||||
buildingContext = tmpContext;
|
||||
|
||||
drawableCenterChunkPos = buildableCenterChunkPos;
|
||||
|
||||
// the vbos have been swapped
|
||||
switchVbos = false;
|
||||
bufferLock.unlock();
|
||||
|
||||
// ClientProxy.LOGGER.info("Get vertex Buffers: " + GlProxy.getInstance().getGlContext());
|
||||
}
|
||||
|
||||
// ClientProxy.LOGGER.info("Get vbo first: " + drawableVbos[0][0].id + "\t" + GlProxy.getInstance().getGlContext());
|
||||
return new VertexBuffersAndOffset(drawableVbos, drawableCenterChunkPos, renderContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
package com.seibel.lod.proxy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
import org.lwjgl.opengl.WGL;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.lod.builders.LodBufferBuilder;
|
||||
|
||||
/**
|
||||
* A singleton that holds references to different openGL contexts.
|
||||
*
|
||||
* <p>
|
||||
* Helpful OpenGL resources: <br><br>
|
||||
*
|
||||
* https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf <br>
|
||||
* https://learnopengl.com/Advanced-OpenGL/Advanced-Data <br>
|
||||
* https://gamedev.stackexchange.com/questions/91995/edit-vbo-data-or-create-a-new-one <br><br>
|
||||
*
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 9-9-2021
|
||||
* @version 9-14-2021
|
||||
*/
|
||||
public class GlProxy
|
||||
{
|
||||
@@ -36,57 +36,35 @@ public class GlProxy
|
||||
|
||||
private GlProxy()
|
||||
{
|
||||
GLFWErrorCallback errorfun = GLFWErrorCallback.createPrint();
|
||||
GLFW.glfwSetErrorCallback(errorfun);
|
||||
|
||||
|
||||
// getting Minecraft's context has to be done on the render thread,
|
||||
// where the GL context is
|
||||
if (!RenderSystem.isOnRenderThread())
|
||||
throw new IllegalStateException(GlProxy.class.getSimpleName() + " was created outside the render thread!");
|
||||
|
||||
|
||||
minecraftGlContext = WGL.wglGetCurrentContext();
|
||||
minecraftGlCapabilities = GL.getCapabilities();
|
||||
deviceContext = WGL.wglGetCurrentDC();
|
||||
|
||||
|
||||
Callable<Void> callable = () ->
|
||||
{
|
||||
lodBuilderGlContext = WGL.wglCreateContext(deviceContext);
|
||||
// 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.BUILDER.toString() + "] from [" + GlProxyContext.MINECRAFT.toString() + "]");
|
||||
lodBuilderGlCapabilities = GL.createCapabilities();
|
||||
WGL.wglMakeCurrent(deviceContext, 0L);
|
||||
lodBuilderGlContext = WGL.wglCreateContext(deviceContext);
|
||||
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() + "]");
|
||||
lodBuilderGlCapabilities = GL.createCapabilities();
|
||||
WGL.wglMakeCurrent(deviceContext, 0L);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
ArrayList<Callable<Void>> list = new ArrayList<Callable<Void>>();
|
||||
list.add(callable);
|
||||
try
|
||||
{
|
||||
List<Future<Void>> futuresBuffer = LodBufferBuilder.mainGenThread.invokeAll(list);
|
||||
|
||||
for (Future<Void> future : futuresBuffer)
|
||||
if (!future.isDone())
|
||||
ClientProxy.LOGGER.error("GLProxy failed to setup.");
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
lodRenderGlContext = WGL.wglCreateContext(deviceContext);
|
||||
// if (!WGL.wglShareLists(lodBuilderGlContext, lodRenderGlContext))
|
||||
// throw new IllegalStateException("Unable to share lists between builder and render contexts.");
|
||||
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.BUILDER.toString() + "] from [" + GlProxyContext.RENDER.toString() + "]");
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -102,11 +80,11 @@ public class GlProxy
|
||||
GLCapabilities newGlCapabilities = null;
|
||||
switch(context)
|
||||
{
|
||||
case BUILDER:
|
||||
case ALPHA:
|
||||
contextPointer = lodBuilderGlContext;
|
||||
newGlCapabilities = lodBuilderGlCapabilities;
|
||||
break;
|
||||
case RENDER:
|
||||
case BETA:
|
||||
contextPointer = lodRenderGlContext;
|
||||
newGlCapabilities = lodRenderGlCapabilities;
|
||||
break;
|
||||
@@ -133,11 +111,11 @@ public class GlProxy
|
||||
long currentContext = WGL.wglGetCurrentContext();
|
||||
if(currentContext == lodBuilderGlContext)
|
||||
{
|
||||
return GlProxyContext.BUILDER;
|
||||
return GlProxyContext.ALPHA;
|
||||
}
|
||||
else if(currentContext == lodRenderGlContext)
|
||||
{
|
||||
return GlProxyContext.RENDER;
|
||||
return GlProxyContext.BETA;
|
||||
}
|
||||
else if(currentContext == minecraftGlContext)
|
||||
{
|
||||
@@ -152,8 +130,8 @@ public class GlProxy
|
||||
public enum GlProxyContext
|
||||
{
|
||||
MINECRAFT,
|
||||
BUILDER,
|
||||
RENDER,
|
||||
ALPHA,
|
||||
BETA,
|
||||
|
||||
/** used to un-bind threads */
|
||||
NONE,
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL15C;
|
||||
import org.lwjgl.opengl.NVFogDistance;
|
||||
import org.lwjgl.opengl.WGL;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
@@ -47,7 +46,6 @@ import com.seibel.lod.objects.NearFarFogSettings;
|
||||
import com.seibel.lod.objects.RegionPos;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.proxy.GlProxy;
|
||||
import com.seibel.lod.proxy.GlProxy.GlProxyContext;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
@@ -75,7 +73,7 @@ import net.minecraft.util.math.vector.Vector3f;
|
||||
* This is where LODs are draw to the world.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 9-7-2021
|
||||
* @version 9-14-2021
|
||||
*/
|
||||
public class LodRenderer
|
||||
{
|
||||
@@ -103,7 +101,6 @@ public class LodRenderer
|
||||
*/
|
||||
private static Boolean fancyFogAvailable = null;
|
||||
private static GlProxy glProxy;
|
||||
private GlProxyContext renderContext = null;
|
||||
|
||||
/**
|
||||
* If true the LODs colors will be replaced with
|
||||
@@ -208,7 +205,6 @@ public class LodRenderer
|
||||
|
||||
// create the GlProxy TODO this should probably be done somewhere else
|
||||
glProxy = GlProxy.getInstance();
|
||||
ClientProxy.LOGGER.error("share lists renderer: " + WGL.wglShareLists(GlProxy.getInstance().minecraftGlContext, GlProxy.getInstance().lodBuilderGlContext));
|
||||
}
|
||||
|
||||
|
||||
@@ -251,8 +247,6 @@ public class LodRenderer
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GlProxy.getInstance().setGlContext(renderContext);
|
||||
|
||||
|
||||
|
||||
@@ -262,8 +256,6 @@ public class LodRenderer
|
||||
|
||||
// set the required open GL settings
|
||||
|
||||
GlProxy.getInstance().setGlContext(renderContext);
|
||||
|
||||
if (LodConfig.CLIENT.debugging.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME)
|
||||
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
|
||||
else
|
||||
@@ -365,8 +357,6 @@ public class LodRenderer
|
||||
// over the LODs
|
||||
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
GlProxy.getInstance().setGlContext(GlProxyContext.MINECRAFT);
|
||||
|
||||
// replace the buffers used to draw and build,
|
||||
// this is only done when the createLodBufferGenerationThread
|
||||
// has finished executing on a parallel thread.
|
||||
@@ -691,7 +681,6 @@ public class LodRenderer
|
||||
VertexBuffersAndOffset result = lodBufferBuilder.getVertexBuffers();
|
||||
vbos = result.vbos;
|
||||
vbosCenter = result.drawableCenterChunkPos;
|
||||
renderContext = result.drawingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -92,7 +92,7 @@ public class RenderUtil
|
||||
public static int getBufferMemoryForRegion()
|
||||
{
|
||||
// calculate the max amount of buffer memory needed (in bytes)
|
||||
return LodUtil.REGION_WIDTH_IN_CHUNKS * LodUtil.REGION_WIDTH_IN_CHUNKS *
|
||||
return LodUtil.REGION_WIDTH_IN_CHUNKS * LodUtil.REGION_WIDTH_IN_CHUNKS * 6 * // TODO this really needs to be more accurate
|
||||
LodConfig.CLIENT.graphics.lodTemplate.get().getBufferMemoryForSingleLod();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user