Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a314f0fe79 | |||
| d8091ab62a | |||
| c5a2944d68 | |||
| 1405b7a433 | |||
| be00670b7e | |||
| 6f2c02d283 | |||
| 309526e7b9 |
@@ -7,7 +7,7 @@ allowing for an increased view distance without harming performance.
|
||||
Or in other words: this mod lets you see farther without turning your game into a slide show.\
|
||||
If you want to see a quick demo, check out a video covering the mod here:
|
||||
|
||||
[](https://www.youtube.com/watch?v=MDWcEvdUGUE)
|
||||
<a href="https://www.youtube.com/watch?v=H2tnvEVbO1c" target="_blank"></a>
|
||||
|
||||
|
||||
Forge version: 1.16.5-36.1.0
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ apply plugin: 'eclipse'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
|
||||
version = 'a1.5.0'
|
||||
version = 'a1.5.1'
|
||||
group = 'com.seibel.lod'
|
||||
archivesBaseName = 'Distant-Horizons_1.16.5'
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
* @author James Seibel
|
||||
* @version 7-3-2021
|
||||
*/
|
||||
@Mod(ModInfo.MODID)
|
||||
@Mod(ModInfo.ID)
|
||||
public class LodMain
|
||||
{
|
||||
public static LodMain instance;
|
||||
|
||||
@@ -22,12 +22,14 @@ package com.seibel.lod;
|
||||
/**
|
||||
* This file is similar to mcmod.info
|
||||
* @author James Seibel
|
||||
* @version 10-16-2021
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
public final class ModInfo
|
||||
{
|
||||
public static final String MODID = "lod";
|
||||
public static final String MODNAME = "DistantHorizons";
|
||||
public static final String MODAPI = "LodAPI";
|
||||
public static final String VERSION = "a1.5.0";
|
||||
public static final String ID = "lod";
|
||||
public static final String NAME = "DistantHorizons";
|
||||
/** Human readable version of MOD_NAME */
|
||||
public static final String READABLE_NAME = "Distant Horizons";
|
||||
public static final String API = "LodAPI";
|
||||
public static final String VERSION = "a1.5.1";
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL15C;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
import org.lwjgl.opengl.GL45;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
@@ -40,6 +40,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.lod.builders.bufferBuilding.lodTemplates.Box;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.GlProxyContext;
|
||||
import com.seibel.lod.enums.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.VanillaOverdraw;
|
||||
import com.seibel.lod.objects.LodDimension;
|
||||
import com.seibel.lod.objects.LodRegion;
|
||||
@@ -67,7 +68,7 @@ import net.minecraft.world.LightType;
|
||||
/**
|
||||
* This object is used to create NearFarBuffer objects.
|
||||
* @author James Seibel
|
||||
* @version 10-10-2021
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
public class LodBufferBuilder
|
||||
{
|
||||
@@ -109,14 +110,6 @@ public class LodBufferBuilder
|
||||
/** The OpenGL IDs of the storage buffers used by the drawableVbos */
|
||||
public int[][][] drawableStorageBufferIds;
|
||||
|
||||
/** used to debug how the buildableStorageBuffers are growing */
|
||||
public int[][][] bufferPreviousCapacity;
|
||||
/**
|
||||
* This is toggled when the buffers are swapped, so we only
|
||||
* display the expansion log for one set of buffers
|
||||
*/
|
||||
public boolean printExpansionLog = true;
|
||||
|
||||
/** Used when building new VBOs */
|
||||
public volatile VertexBuffer[][][] buildableVbos;
|
||||
/** VBOs that are sent over to the LodNodeRenderer */
|
||||
@@ -542,6 +535,8 @@ public class LodBufferBuilder
|
||||
*/
|
||||
public void setupBuffers(LodDimension lodDimension)
|
||||
{
|
||||
GlProxy glProxy = GlProxy.getInstance();
|
||||
|
||||
bufferLock.lock();
|
||||
int numbRegionsWide = lodDimension.getWidth();
|
||||
long regionMemoryRequired;
|
||||
@@ -554,10 +549,11 @@ public class LodBufferBuilder
|
||||
buildableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide][];
|
||||
drawableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide][];
|
||||
|
||||
buildableStorageBufferIds = new int[numbRegionsWide][numbRegionsWide][];
|
||||
drawableStorageBufferIds = new int[numbRegionsWide][numbRegionsWide][];
|
||||
|
||||
bufferPreviousCapacity = new int[numbRegionsWide][numbRegionsWide][];
|
||||
if (glProxy.bufferStorageSupported)
|
||||
{
|
||||
buildableStorageBufferIds = new int[numbRegionsWide][numbRegionsWide][];
|
||||
drawableStorageBufferIds = new int[numbRegionsWide][numbRegionsWide][];
|
||||
}
|
||||
|
||||
for (int x = 0; x < numbRegionsWide; x++)
|
||||
{
|
||||
@@ -579,9 +575,11 @@ public class LodBufferBuilder
|
||||
buildableVbos[x][z] = new VertexBuffer[numberOfBuffers];
|
||||
drawableVbos[x][z] = new VertexBuffer[numberOfBuffers];
|
||||
|
||||
buildableStorageBufferIds[x][z] = new int[numberOfBuffers];
|
||||
drawableStorageBufferIds[x][z] = new int[numberOfBuffers];
|
||||
bufferPreviousCapacity[x][z] = new int[numberOfBuffers];
|
||||
if (glProxy.bufferStorageSupported)
|
||||
{
|
||||
buildableStorageBufferIds[x][z] = new int[numberOfBuffers];
|
||||
drawableStorageBufferIds[x][z] = new int[numberOfBuffers];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -591,16 +589,16 @@ public class LodBufferBuilder
|
||||
buildableVbos[x][z] = new VertexBuffer[1];
|
||||
drawableVbos[x][z] = new VertexBuffer[1];
|
||||
|
||||
buildableStorageBufferIds[x][z] = new int[1];
|
||||
drawableStorageBufferIds[x][z] = new int[1];
|
||||
bufferPreviousCapacity[x][z] = new int[1];
|
||||
if (glProxy.bufferStorageSupported)
|
||||
{
|
||||
buildableStorageBufferIds[x][z] = new int[1];
|
||||
drawableStorageBufferIds[x][z] = new int[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < numberOfBuffersPerRegion[x][z]; i++)
|
||||
{
|
||||
bufferPreviousCapacity[x][z][i] = (int) regionMemoryRequired;
|
||||
|
||||
buildableBuffers[x][z][i] = new BufferBuilder((int) regionMemoryRequired);
|
||||
|
||||
buildableVbos[x][z][i] = new VertexBuffer(LodUtil.LOD_VERTEX_FORMAT);
|
||||
@@ -609,24 +607,27 @@ public class LodBufferBuilder
|
||||
|
||||
// create the initial mapped buffers (system memory)
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableVbos[x][z][i].id);
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL45.GL_DYNAMIC_DRAW);
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL15.GL_DYNAMIC_DRAW);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, drawableVbos[x][z][i].id);
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL45.GL_DYNAMIC_DRAW);
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, GL15.GL_DYNAMIC_DRAW);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
||||
// create the buffer storage (GPU memory)
|
||||
buildableStorageBufferIds[x][z][i] = GL45.glGenBuffers();
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableStorageBufferIds[x][z][i]);
|
||||
GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, 0); // the 0 flag means to create the storage in the GPUs memory
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
drawableStorageBufferIds[x][z][i] = GL45.glGenBuffers();
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, drawableStorageBufferIds[x][z][i]);
|
||||
GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, 0);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
if (glProxy.bufferStorageSupported)
|
||||
{
|
||||
// create the buffer storage (GPU memory)
|
||||
buildableStorageBufferIds[x][z][i] = GL15.glGenBuffers();
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buildableStorageBufferIds[x][z][i]);
|
||||
GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, 0); // the 0 flag means to create the storage in the GPUs memory
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
drawableStorageBufferIds[x][z][i] = GL15.glGenBuffers();
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, drawableStorageBufferIds[x][z][i]);
|
||||
GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, regionMemoryRequired, 0);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -665,8 +666,8 @@ public class LodBufferBuilder
|
||||
// was called from (if any).
|
||||
RenderSystem.recordRenderCall(() ->
|
||||
{
|
||||
GL45.glDeleteBuffers(buildableId);
|
||||
GL45.glDeleteBuffers(drawableId);
|
||||
GL15.glDeleteBuffers(buildableId);
|
||||
GL15.glDeleteBuffers(drawableId);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -708,9 +709,9 @@ public class LodBufferBuilder
|
||||
RenderSystem.recordRenderCall(() ->
|
||||
{
|
||||
if (buildableId != 0)
|
||||
GL45.glDeleteBuffers(buildableId);
|
||||
GL15.glDeleteBuffers(buildableId);
|
||||
if (drawableId != 0)
|
||||
GL45.glDeleteBuffers(drawableId);
|
||||
GL15.glDeleteBuffers(drawableId);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -773,6 +774,16 @@ public class LodBufferBuilder
|
||||
// this helps prevent interference (IE stuttering) with the Minecraft context.
|
||||
glProxy.setGlContext(GlProxyContext.LOD_BUILDER);
|
||||
|
||||
// determine the upload method
|
||||
GpuUploadMethod uploadMethod = LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get();
|
||||
if (!glProxy.bufferStorageSupported && uploadMethod == GpuUploadMethod.BUFFER_STORAGE)
|
||||
{
|
||||
// if buffer storage isn't supported
|
||||
// default to SUB_DATA
|
||||
LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(GpuUploadMethod.SUB_DATA);
|
||||
uploadMethod = GpuUploadMethod.SUB_DATA;
|
||||
}
|
||||
|
||||
// actually upload the buffers
|
||||
for (int x = 0; x < buildableVbos.length; x++)
|
||||
{
|
||||
@@ -783,7 +794,7 @@ public class LodBufferBuilder
|
||||
for (int i = 0; i < buildableBuffers[x][z].length; i++)
|
||||
{
|
||||
ByteBuffer uploadBuffer = buildableBuffers[x][z][i].popNextBuffer().getSecond();
|
||||
vboUpload(buildableVbos[x][z][i], buildableStorageBufferIds[x][z][i], uploadBuffer, x, z, i, true);
|
||||
vboUpload(buildableVbos[x][z][i], buildableStorageBufferIds[x][z][i], uploadBuffer, true, uploadMethod);
|
||||
lodDim.setRegenRegionBufferByArrayIndex(x, z, false);
|
||||
}
|
||||
}
|
||||
@@ -807,11 +818,10 @@ public class LodBufferBuilder
|
||||
}
|
||||
}
|
||||
|
||||
/** Uploads the uploadBuffer into the VBO and then into GPU memory. */
|
||||
/** Uploads the uploadBuffer so the GPU can use it.
|
||||
* @param uploadMethod */
|
||||
private void vboUpload(VertexBuffer vbo, int storageBufferId, ByteBuffer uploadBuffer,
|
||||
int xVboIndex, int zVboIndex, int iVboIndex, boolean allowBufferExpansion)
|
||||
// x/zVboIndex are just used for the debugging console logging
|
||||
// and should be removed when the logger is removed.
|
||||
boolean allowBufferExpansion, GpuUploadMethod uploadMethod)
|
||||
{
|
||||
// this shouldn't happen, but just to be safe
|
||||
if (vbo.id != -1 && GlProxy.getInstance().getGlContext() == GlProxyContext.LOD_BUILDER)
|
||||
@@ -820,63 +830,98 @@ public class LodBufferBuilder
|
||||
vbo.vertexCount = (uploadBuffer.capacity() / vbo.format.getVertexSize());
|
||||
|
||||
|
||||
GL45.glBindBuffer(GL45.GL_ARRAY_BUFFER, vbo.id);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id);
|
||||
try
|
||||
{
|
||||
// get a pointer to the buffer in system memory
|
||||
ByteBuffer vboBuffer = GL45.glMapBufferRange(GL45.GL_ARRAY_BUFFER, 0, uploadBuffer.capacity(), GL45.GL_MAP_WRITE_BIT | GL45.GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
if (vboBuffer == null)
|
||||
// if possible use the faster buffer storage route
|
||||
if (uploadMethod == GpuUploadMethod.BUFFER_STORAGE)
|
||||
{
|
||||
int previousCapacity = uploadBuffer.capacity();
|
||||
|
||||
// only expand the buffers if the uploadBuffer actually
|
||||
// has something in it and expansion is allowed
|
||||
if (previousCapacity != 0 && allowBufferExpansion)
|
||||
// get a pointer to the buffer in system memory
|
||||
ByteBuffer vboBuffer = GL30.glMapBufferRange(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer.capacity(), GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
if (vboBuffer == null)
|
||||
{
|
||||
// the buffer(s) aren't big enough, expand them.
|
||||
// This does cause lag/stuttering, so it should be avoided!
|
||||
int previousCapacity = uploadBuffer.capacity();
|
||||
|
||||
// expand the buffer in system memory
|
||||
GL45.glBufferData(GL45.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL45.GL_DYNAMIC_DRAW);
|
||||
GL45.glBufferSubData(GL45.GL_ARRAY_BUFFER, 0, uploadBuffer);
|
||||
|
||||
// un-bind the system memory buffer
|
||||
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// expand the buffer storage
|
||||
GL45.glDeleteBuffers(storageBufferId);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, storageBufferId);
|
||||
GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), 0);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
||||
// recursively try to upload into the newly created buffer storage
|
||||
// but don't recurse again if that fails
|
||||
// (we don't want an infinitely expanding buffer!)
|
||||
vboUpload(vbo, storageBufferId, uploadBuffer, xVboIndex, zVboIndex, iVboIndex, false);
|
||||
|
||||
|
||||
|
||||
/*if (printExpansionLog)
|
||||
// only expand the buffers if the uploadBuffer actually
|
||||
// has something in it and expansion is allowed
|
||||
if (previousCapacity != 0 && allowBufferExpansion)
|
||||
{
|
||||
// NOTE: this will display twice because we are double buffering
|
||||
// (using 1 buffer to generate into and one to draw)
|
||||
ClientProxy.LOGGER.info("vbo (" + xVboIndex + "," + zVboIndex + ") expanded: " + bufferPreviousCapacity[xVboIndex][zVboIndex][iVboIndex] + " -> " + (int)(uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER));
|
||||
bufferPreviousCapacity[xVboIndex][zVboIndex][iVboIndex] = (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER);
|
||||
}*/
|
||||
// the buffer(s) aren't big enough, expand them.
|
||||
// This does cause lag/stuttering, so it should be avoided!
|
||||
|
||||
// expand the buffer in system memory
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_DYNAMIC_DRAW);
|
||||
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
|
||||
|
||||
// un-bind the system memory buffer
|
||||
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// expand the buffer storage
|
||||
GL15.glDeleteBuffers(storageBufferId);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, storageBufferId);
|
||||
GL45.glBufferStorage(GL15.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), 0);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
|
||||
// recursively try to upload into the newly created buffer storage
|
||||
// but don't recurse again if that fails
|
||||
// (we don't want an infinitely expanding buffer!)
|
||||
vboUpload(vbo, storageBufferId, uploadBuffer, false, uploadMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// upload the buffer into system memory...
|
||||
vboBuffer.put(uploadBuffer);
|
||||
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
|
||||
// ...then upload into GPU memory
|
||||
// (uploading into GPU memory directly can only be done
|
||||
// through the glCopyBufferSubData/glCopyNamed... methods)
|
||||
GL45.glCopyNamedBufferSubData(vbo.id, storageBufferId, 0, 0, uploadBuffer.capacity());
|
||||
}
|
||||
}
|
||||
else if (uploadMethod == GpuUploadMethod.BUFFER_MAPPING)
|
||||
{
|
||||
// no stuttering but high GPU usage
|
||||
// stores everything in system memory instead of GPU memory
|
||||
// making rendering much slower.
|
||||
// Unless the user is running integrated graphics,
|
||||
// in that case this will actually work better than SUB_DATA.
|
||||
|
||||
|
||||
ByteBuffer vboBuffer = null;
|
||||
|
||||
// map buffer range is better since it can be explicitly unsynchronized
|
||||
if (GlProxy.getInstance().mapBufferRangeSupported)
|
||||
vboBuffer = GL30.glMapBufferRange(GL30.GL_ARRAY_BUFFER, 0, uploadBuffer.capacity(), GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
else
|
||||
vboBuffer = GL15.glMapBuffer(GL30.GL_ARRAY_BUFFER, uploadBuffer.capacity());
|
||||
|
||||
|
||||
if (vboBuffer == null)
|
||||
{
|
||||
GL15.glBufferData(GL45.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_DYNAMIC_DRAW);
|
||||
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
vboBuffer.put(uploadBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// upload the buffer into system memory...
|
||||
vboBuffer.put(uploadBuffer);
|
||||
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
// hybrid subData/bufferData //
|
||||
// less stutter, low GPU usage
|
||||
|
||||
// ...then upload into GPU memory
|
||||
// (uploading into GPU memory directly can only be done
|
||||
// through the glCopyBufferSubData/glCopyNamed... methods)
|
||||
GL45.glCopyNamedBufferSubData(vbo.id, storageBufferId, 0, 0, uploadBuffer.capacity());
|
||||
//long size = GL31.glGetBufferParameteri64(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE); // hopefully just a int should be long enough
|
||||
long size = GL15.glGetBufferParameteri(GL15.GL_ARRAY_BUFFER, GL15.GL_BUFFER_SIZE);
|
||||
if (size < uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER)
|
||||
{
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, (int) (uploadBuffer.capacity() * BUFFER_EXPANSION_MULTIPLIER), GL15.GL_DYNAMIC_DRAW);
|
||||
}
|
||||
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -886,11 +931,14 @@ public class LodBufferBuilder
|
||||
}
|
||||
finally
|
||||
{
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
if (uploadMethod == GpuUploadMethod.BUFFER_MAPPING)
|
||||
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}//if vbo exists and in correct GL context
|
||||
}//vboUpload
|
||||
|
||||
/** Get the newly created VBOs */
|
||||
public VertexBuffersAndOffset getVertexBuffers()
|
||||
@@ -907,10 +955,6 @@ public class LodBufferBuilder
|
||||
drawableStorageBufferIds = buildableStorageBufferIds;
|
||||
buildableStorageBufferIds = tmpStorage;
|
||||
|
||||
// we only want to print the expansion log for
|
||||
// one set of buffers, not both
|
||||
printExpansionLog = !printExpansionLog;
|
||||
|
||||
drawableCenterChunkPos = buildableCenterChunkPos;
|
||||
|
||||
// the vbos have been swapped
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.seibel.lod.builders.lodBuilding.LodBuilder;
|
||||
import com.seibel.lod.builders.lodBuilding.LodBuilderConfig;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.handlers.ChunkLoader;
|
||||
import com.seibel.lod.objects.LodDimension;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
@@ -190,9 +191,8 @@ public class LodGenWorker implements IWorker
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
/*
|
||||
IChunk loadedChunk = null;
|
||||
if (lodDim.isChunkPreGenerated(pos.x, pos.z) && LodConfig.CLIENT.worldGenerator.useExperimentalPreGenLoading.get())
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.usePregen.get() && lodDim.isChunkPreGenerated(pos.x, pos.z))
|
||||
{
|
||||
// generate a Lod like normal
|
||||
loadedChunk = ChunkLoader.getChunkFromFile(pos);
|
||||
@@ -227,7 +227,7 @@ public class LodGenWorker implements IWorker
|
||||
}
|
||||
}
|
||||
else
|
||||
{*/
|
||||
{
|
||||
switch (generationMode)
|
||||
{
|
||||
case NONE:
|
||||
@@ -251,7 +251,7 @@ public class LodGenWorker implements IWorker
|
||||
generateWithServer();
|
||||
break;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
//lodRenderer.regenerateLODsNextFrame();
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ public class LodWorldGenerator
|
||||
// an easy way to do so.
|
||||
|
||||
// add the near positions
|
||||
if (posToGenerate.getNthDetail(nearIndex, true) != 0 && nearIndex < posToGenerate.getNumberOfNearPos())
|
||||
if (nearIndex < posToGenerate.getNumberOfNearPos() && posToGenerate.getNthDetail(nearIndex, true) != 0)
|
||||
{
|
||||
detailLevel = (byte) (posToGenerate.getNthDetail(nearIndex, true) - 1);
|
||||
posX = posToGenerate.getNthPosX(nearIndex, true);
|
||||
@@ -160,7 +160,7 @@ public class LodWorldGenerator
|
||||
|
||||
|
||||
// add the far positions
|
||||
if (posToGenerate.getNthDetail(farIndex, false) != 0 && farIndex < posToGenerate.getNumberOfFarPos())
|
||||
if (farIndex < posToGenerate.getNumberOfFarPos() && posToGenerate.getNthDetail(farIndex, false) != 0)
|
||||
{
|
||||
detailLevel = (byte) (posToGenerate.getNthDetail(farIndex, false) - 1);
|
||||
posX = posToGenerate.getNthPosX(farIndex, false);
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.FogDistance;
|
||||
import com.seibel.lod.enums.FogDrawOverride;
|
||||
import com.seibel.lod.enums.GenerationPriority;
|
||||
import com.seibel.lod.enums.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.HorizontalQuality;
|
||||
import com.seibel.lod.enums.HorizontalResolution;
|
||||
import com.seibel.lod.enums.HorizontalScale;
|
||||
@@ -51,7 +52,7 @@ import net.minecraftforge.fml.config.ModConfig;
|
||||
/**
|
||||
* This handles any configuration the user has access to.
|
||||
* @author James Seibel
|
||||
* @version 10-19-2021
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
@Mod.EventBusSubscriber
|
||||
public class LodConfig
|
||||
@@ -222,6 +223,8 @@ public class LodConfig
|
||||
|
||||
public final ForgeConfigSpec.EnumValue<VanillaOverdraw> vanillaOverdraw;
|
||||
|
||||
public final ForgeConfigSpec.EnumValue<GpuUploadMethod> gpuUploadMethod;
|
||||
|
||||
AdvancedGraphicsOption(ForgeConfigSpec.Builder builder)
|
||||
{
|
||||
|
||||
@@ -273,6 +276,17 @@ public class LodConfig
|
||||
+ " " + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n"
|
||||
+ " " + VanillaOverdraw.BORDER + ": LODs will render only on the border of vanilla chunks preventing only some holes in the world. \n")
|
||||
.defineEnum("Vanilla Overdraw", VanillaOverdraw.DYNAMIC);
|
||||
|
||||
gpuUploadMethod = builder
|
||||
.comment("\n\n"
|
||||
+ " What method should be used to upload geometry to the GPU? \n\\n"
|
||||
+ ""
|
||||
+ " " + GpuUploadMethod.BUFFER_STORAGE + ": Default if OpenGL 4.5 is supported. Fast rendering, no stuttering. \n"
|
||||
+ " " + GpuUploadMethod.SUB_DATA + ": Default if OpenGL 4.5 is NOT supported. Fast rendering but may stutter when uploading. \n"
|
||||
+ " " + GpuUploadMethod.BUFFER_MAPPING + ": Slow rendering but won't stutter when uploading. Possibly better than " + GpuUploadMethod.SUB_DATA + " if using a integrated GPU. \n")
|
||||
.defineEnum("GPU Upload Method", GpuUploadMethod.BUFFER_STORAGE);
|
||||
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
}
|
||||
@@ -466,12 +480,18 @@ public class LodConfig
|
||||
{
|
||||
public final ForgeConfigSpec.BooleanValue drawLods;
|
||||
public final ForgeConfigSpec.EnumValue<DebugMode> debugMode;
|
||||
public final ForgeConfigSpec.BooleanValue usePregen;
|
||||
public final ForgeConfigSpec.BooleanValue enableDebugKeybindings;
|
||||
|
||||
Debugging(ForgeConfigSpec.Builder builder)
|
||||
{
|
||||
builder.comment("These settings can be used to look for bugs, or see how certain aspects of the mod work.").push(this.getClass().getSimpleName());
|
||||
|
||||
usePregen = builder
|
||||
.comment("\n\n"
|
||||
+ " if true the game will use pregen when possible \n")
|
||||
.define("Use Pregen", false);
|
||||
|
||||
drawLods = builder
|
||||
.comment("\n\n"
|
||||
+ " If true, the mod is enabled and fake chunks will be drawn. \n"
|
||||
@@ -519,7 +539,7 @@ public class LodConfig
|
||||
|
||||
|
||||
/** {@link Path} to the configuration file of this mod */
|
||||
private static final Path CONFIG_PATH = Paths.get("config", ModInfo.MODNAME + ".toml");
|
||||
private static final Path CONFIG_PATH = Paths.get("config", ModInfo.NAME + ".toml");
|
||||
|
||||
public static final ForgeConfigSpec CLIENT_SPEC;
|
||||
public static final Client CLIENT;
|
||||
@@ -540,13 +560,13 @@ public class LodConfig
|
||||
@SubscribeEvent
|
||||
public static void onLoad(final ModConfig.Loading configEvent)
|
||||
{
|
||||
LogManager.getLogger().debug(ModInfo.MODNAME, "Loaded forge config file {}", configEvent.getConfig().getFileName());
|
||||
LogManager.getLogger().debug(ModInfo.NAME, "Loaded forge config file {}", configEvent.getConfig().getFileName());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onFileChange(final ModConfig.Reloading configEvent)
|
||||
{
|
||||
LogManager.getLogger().debug(ModInfo.MODNAME, "Forge config just got changed on the file system!");
|
||||
LogManager.getLogger().debug(ModInfo.NAME, "Forge config just got changed on the file system!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
|
||||
/**
|
||||
* Buffer_Storage, Sub_Data, Buffer_Mapping
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
public enum GpuUploadMethod
|
||||
{
|
||||
/** Default if OpenGL 4.5 is supported. Fast rendering, no stuttering. */
|
||||
BUFFER_STORAGE,
|
||||
|
||||
/** Default if OpenGL 4.5 is NOT supported. Fast rendering but may stutter when uploading. */
|
||||
SUB_DATA,
|
||||
|
||||
/** May end up storing buffers in System memory. Slower rendering but won't stutter when uploading. */
|
||||
BUFFER_MAPPING,
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.GenerationPriority;
|
||||
import com.seibel.lod.enums.VerticalQuality;
|
||||
import com.seibel.lod.handlers.LodDimensionFileHandler;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
@@ -602,6 +603,9 @@ public class LodDimension
|
||||
//if(lodRegion.isChunkPreGenerated(xChunkToCheck,zChunkToCheck))
|
||||
// complexity = DistanceGenerationMode.SERVER.complexity;
|
||||
//else
|
||||
if(LodConfig.CLIENT.advancedModOptions.debugging.usePregen.get() && isChunkPreGenerated(xChunkToCheck, zChunkToCheck))
|
||||
complexity = DistanceGenerationMode.SERVER.complexity;
|
||||
else
|
||||
complexity = LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get().complexity;
|
||||
|
||||
|
||||
@@ -817,15 +821,15 @@ public class LodDimension
|
||||
/**
|
||||
* Return true if the chunk has been pregenerated in game
|
||||
*/
|
||||
//public boolean isChunkPreGenerated(int xChunkPos, int zChunkPos)
|
||||
//{
|
||||
//
|
||||
// LodRegion region = getRegion(LodUtil.CHUNK_DETAIL_LEVEL, xChunkPos, zChunkPos);
|
||||
// if (region == null)
|
||||
// return false;
|
||||
//
|
||||
// return region.isChunkPreGenerated(xChunkPos, zChunkPos);
|
||||
//}
|
||||
public boolean isChunkPreGenerated(int xChunkPos, int zChunkPos)
|
||||
{
|
||||
|
||||
LodRegion region = getRegion(LodUtil.CHUNK_DETAIL_LEVEL, xChunkPos, zChunkPos);
|
||||
if (region == null)
|
||||
return false;
|
||||
|
||||
return region.isChunkPreGenerated(xChunkPos, zChunkPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the region at the given RegionPos
|
||||
|
||||
@@ -25,6 +25,13 @@ import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.storage.RegionFile;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* This object holds all loaded LevelContainers acting as a quad tree
|
||||
@@ -58,7 +65,7 @@ public class LodRegion
|
||||
/**
|
||||
* This chunk Pos has been generated
|
||||
*/
|
||||
//private final boolean[] preGeneratedChunkPos;
|
||||
private final boolean[] preGeneratedChunkPos;
|
||||
|
||||
/**
|
||||
* the generation mode for this region
|
||||
@@ -96,9 +103,9 @@ public class LodRegion
|
||||
|
||||
boolean fileFound = false;
|
||||
|
||||
/*
|
||||
|
||||
preGeneratedChunkPos = new boolean[32 * 32];
|
||||
if (MinecraftWrapper.INSTANCE.hasSinglePlayerServer() && LodConfig.CLIENT.worldGenerator.useExperimentalPreGenLoading.get())
|
||||
if (MinecraftWrapper.INSTANCE.hasSinglePlayerServer())
|
||||
{
|
||||
File regionFileDirHead;
|
||||
File regionFileDirParent;
|
||||
@@ -108,7 +115,7 @@ public class LodRegion
|
||||
|
||||
// provider needs a separate variable to prevent
|
||||
// the compiler from complaining
|
||||
StringBuilder string = new StringBuilder();
|
||||
//StringBuilder string = new StringBuilder();
|
||||
try
|
||||
{
|
||||
ServerChunkProvider provider = serverWorld.getChunkSource();
|
||||
@@ -119,7 +126,7 @@ public class LodRegion
|
||||
{
|
||||
regionFileDirParent = regionFileDirHead.getParentFile();
|
||||
//string.append(regionFileDirParent.toString());
|
||||
string.append(regionFileDirHead);
|
||||
//string.append(regionFileDirHead);
|
||||
RegionFile regionFile = new RegionFile(regionFileDirHead, regionFileDirParent, true);
|
||||
for (int x = 0; x < 32; x++)
|
||||
{
|
||||
@@ -129,7 +136,7 @@ public class LodRegion
|
||||
}
|
||||
}
|
||||
|
||||
string.append("region " + regionPosX + " " + regionPosZ + "\n");
|
||||
/*string.append("region " + regionPosX + " " + regionPosZ + "\n");
|
||||
for (int x = 0; x < 32; x++)
|
||||
{
|
||||
for (int z = 0; z < 32; z++)
|
||||
@@ -137,8 +144,8 @@ public class LodRegion
|
||||
//regionFile.doesChunkExist()
|
||||
string.append(preGeneratedChunkPos[x * 32 + z] + "\t");
|
||||
}
|
||||
string.append("\n");
|
||||
}
|
||||
//string.append("\n");
|
||||
}*/
|
||||
regionFile.close();
|
||||
}
|
||||
}
|
||||
@@ -146,8 +153,8 @@ public class LodRegion
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(string);
|
||||
}*/
|
||||
//System.out.println(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -155,12 +162,12 @@ public class LodRegion
|
||||
/**
|
||||
* Return true if the chunk has been pregenerated in game
|
||||
*/
|
||||
//public boolean isChunkPreGenerated(int xChunkPos, int zChunkPos)
|
||||
//{
|
||||
// xChunkPos = LevelPosUtil.getRegionModule(LodUtil.CHUNK_DETAIL_LEVEL, xChunkPos);
|
||||
// zChunkPos = LevelPosUtil.getRegionModule(LodUtil.CHUNK_DETAIL_LEVEL, zChunkPos);
|
||||
// return preGeneratedChunkPos[xChunkPos * 32 + zChunkPos];
|
||||
//}
|
||||
public boolean isChunkPreGenerated(int xChunkPos, int zChunkPos)
|
||||
{
|
||||
xChunkPos = LevelPosUtil.getRegionModule(LodUtil.CHUNK_DETAIL_LEVEL, xChunkPos);
|
||||
zChunkPos = LevelPosUtil.getRegionModule(LodUtil.CHUNK_DETAIL_LEVEL, zChunkPos);
|
||||
return preGeneratedChunkPos[xChunkPos * 32 + zChunkPos];
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the data point into the region.
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.seibel.lod.proxy;
|
||||
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.util.text.TextComponent;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -53,7 +55,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
* This handles all events sent to the client,
|
||||
* and is the starting point for most of the mod.
|
||||
* @author James_Seibel
|
||||
* @version 10-15-2021
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
public class ClientProxy
|
||||
{
|
||||
@@ -176,6 +178,8 @@ public class ClientProxy
|
||||
// LodConfig.CLIENT.graphics.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
|
||||
// LodConfig.CLIENT.graphics.shadingMode.set(ShadingMode.DARKEN_SIDES);
|
||||
// LodConfig.CLIENT.graphics.vanillaOverdraw.set(VanillaOverdraw.HALF);
|
||||
|
||||
// LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(GpuUploadMethod.BUFFER_STORAGE);
|
||||
|
||||
// LodConfig.CLIENT.worldGenerator.distanceGenerationMode.set(DistanceGenerationMode.SURFACE);
|
||||
// LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.set(128);
|
||||
@@ -297,6 +301,17 @@ public class ClientProxy
|
||||
{
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.drawLods.set(!LodConfig.CLIENT.advancedModOptions.debugging.drawLods.get());
|
||||
}
|
||||
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get()
|
||||
&& event.getKey() == GLFW.GLFW_KEY_F7 && event.getAction() == GLFW.GLFW_PRESS)
|
||||
{
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.usePregen.set(!LodConfig.CLIENT.advancedModOptions.debugging.usePregen.get());
|
||||
ClientPlayerEntity player = MinecraftWrapper.INSTANCE.getPlayer();
|
||||
if(LodConfig.CLIENT.advancedModOptions.debugging.usePregen.get())
|
||||
player.sendMessage(new StringTextComponent("pregen activated."),player.getUUID());
|
||||
else
|
||||
player.sendMessage(new StringTextComponent("pregen de-activated."),player.getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GLCapabilities;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.lod.ModInfo;
|
||||
import com.seibel.lod.enums.GlProxyContext;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
|
||||
/**
|
||||
* A singleton that holds references to different openGL contexts
|
||||
@@ -38,12 +40,14 @@ import com.seibel.lod.enums.GlProxyContext;
|
||||
* https://gamedev.stackexchange.com/questions/91995/edit-vbo-data-or-create-a-new-one <br><br>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 10-2-2021
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
public class GlProxy
|
||||
{
|
||||
private static GlProxy instance = null;
|
||||
|
||||
private static MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
|
||||
|
||||
/** Minecraft's GLFW window */
|
||||
public final long minecraftGlContext;
|
||||
/** Minecraft's GL context */
|
||||
@@ -63,16 +67,22 @@ public class GlProxy
|
||||
/** Does this computer's GPU support fancy fog? */
|
||||
public final boolean fancyFogAvailable;
|
||||
|
||||
/** Requires OpenGL 4.5, and offers the best buffer uploading */
|
||||
public final boolean bufferStorageSupported;
|
||||
|
||||
/** Requires OpenGL 3.0 */
|
||||
public final boolean mapBufferRangeSupported;
|
||||
|
||||
|
||||
private GlProxy()
|
||||
{
|
||||
ClientProxy.LOGGER.error("Creating " + GlProxy.class.getSimpleName() + "... If this is the last message you see in the log there must have been a OpenGL error.");
|
||||
|
||||
// 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!");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//============================//
|
||||
@@ -101,6 +111,30 @@ public class GlProxy
|
||||
|
||||
|
||||
|
||||
//==============================//
|
||||
// determine the OpenGL version //
|
||||
//==============================//
|
||||
|
||||
bufferStorageSupported = minecraftGlCapabilities.OpenGL45;
|
||||
mapBufferRangeSupported = minecraftGlCapabilities.OpenGL30;
|
||||
|
||||
if (!minecraftGlCapabilities.OpenGL15)
|
||||
{
|
||||
String errorMessage = ModInfo.READABLE_NAME + " was initializing " + GlProxy.class.getSimpleName() + " and discoverd this GPU doesn't support OpenGL 1.5 or greater.";
|
||||
mc.crashMinecraft(errorMessage + " Sorry I couldn't tell you sooner :(", new UnsupportedOperationException("This GPU doesn't support OpenGL 1.5 or greater."));
|
||||
}
|
||||
|
||||
if (!bufferStorageSupported)
|
||||
{
|
||||
String fallBackVersion = mapBufferRangeSupported ? "3.0" : "1.5";
|
||||
|
||||
ClientProxy.LOGGER.error("This GPU doesn't support OpenGL 4.5, falling back to OpenGL " + fallBackVersion + ". This may cause stuttering and reduced performance.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==================================//
|
||||
// get any GPU related capabilities //
|
||||
//==================================//
|
||||
@@ -110,6 +144,12 @@ public class GlProxy
|
||||
|
||||
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.");
|
||||
|
||||
|
||||
|
||||
|
||||
// GlProxy creation success
|
||||
ClientProxy.LOGGER.error(GlProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day.");
|
||||
}
|
||||
|
||||
|
||||
@@ -188,15 +228,8 @@ public class GlProxy
|
||||
|
||||
public static GlProxy getInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (instance == null)
|
||||
instance = new GlProxy();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (instance == null)
|
||||
instance = new GlProxy();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.enums.FogDistance;
|
||||
import com.seibel.lod.enums.FogDrawOverride;
|
||||
import com.seibel.lod.enums.FogQuality;
|
||||
import com.seibel.lod.enums.GpuUploadMethod;
|
||||
import com.seibel.lod.handlers.ReflectionHandler;
|
||||
import com.seibel.lod.objects.LodDimension;
|
||||
import com.seibel.lod.objects.NearFarFogSettings;
|
||||
@@ -64,7 +65,7 @@ import net.minecraft.util.math.vector.Vector3d;
|
||||
* This is where LODs are draw to the world.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 10-19-2021
|
||||
* @version 10-23-2021
|
||||
*/
|
||||
public class LodRenderer
|
||||
{
|
||||
@@ -157,6 +158,7 @@ public class LodRenderer
|
||||
* @param mcMatrixStack This matrix stack should come straight from MC's renderChunkLayer (or future equivalent) method
|
||||
* @param partialTicks how far into the current tick this method was called.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void drawLODs(LodDimension lodDim, MatrixStack mcMatrixStack, float partialTicks, IProfiler newProfiler)
|
||||
{
|
||||
if (lodDim == null)
|
||||
@@ -276,6 +278,7 @@ public class LodRenderer
|
||||
Vector3d cameraDir = new Vector3d(renderInfo.getLookVector());
|
||||
|
||||
boolean cullingDisabled = LodConfig.CLIENT.graphics.advancedGraphicsOption.disableDirectionalCulling.get();
|
||||
boolean renderBufferStorage = LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get() == GpuUploadMethod.BUFFER_STORAGE && GlProxy.getInstance().bufferStorageSupported;
|
||||
|
||||
// used to determine what type of fog to render
|
||||
int halfWidth = vbos.length / 2;
|
||||
@@ -292,6 +295,7 @@ public class LodRenderer
|
||||
RegionPos vboPos = new RegionPos(
|
||||
x + vboCenterRegionPos.x - (lodDim.getWidth() / 2),
|
||||
z + vboCenterRegionPos.z - (lodDim.getWidth() / 2));
|
||||
|
||||
if (cullingDisabled || RenderUtil.isRegionInViewFrustum(renderInfo.getBlockPosition(), cameraDir, vboPos.blockPos()))
|
||||
{
|
||||
if ((x > halfWidth - quarterWidth && x < halfWidth + quarterWidth)
|
||||
@@ -301,10 +305,12 @@ public class LodRenderer
|
||||
setupFog(fogSettings.far.distance, fogSettings.far.quality);
|
||||
|
||||
|
||||
for (int i = 0; i < storageBufferIds[x][z].length; i++)
|
||||
{
|
||||
drawBuffer(vbos[x][z][i], storageBufferIds[x][z][i], modelViewMatrix);
|
||||
}
|
||||
if (storageBufferIds != null && renderBufferStorage)
|
||||
for (int i = 0; i < storageBufferIds[x][z].length; i++)
|
||||
drawStorageBuffer(vbos[x][z][i], storageBufferIds[x][z][i], modelViewMatrix);
|
||||
else
|
||||
for (int i = 0; i < vbos[x][z].length; i++)
|
||||
drawVertexBuffer(vbos[x][z][i], modelViewMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,12 +351,29 @@ public class LodRenderer
|
||||
|
||||
|
||||
/** This is where the actual drawing happens. */
|
||||
private void drawBuffer(VertexBuffer vbo, int bufferStorageId, Matrix4f modelViewMatrix)
|
||||
private void drawStorageBuffer(VertexBuffer vbo, int bufferStorageId, Matrix4f modelViewMatrix)
|
||||
{
|
||||
if (vbo == null)
|
||||
return;
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferStorageId);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferStorageId);
|
||||
// 0L is the starting pointer
|
||||
LodUtil.LOD_VERTEX_FORMAT.setupBufferState(0L);
|
||||
|
||||
vbo.draw(modelViewMatrix, GL11.GL_QUADS);
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
LodUtil.LOD_VERTEX_FORMAT.clearBufferState();
|
||||
}
|
||||
|
||||
|
||||
/** This is where the actual drawing happens. */
|
||||
private void drawVertexBuffer(VertexBuffer vbo, Matrix4f modelViewMatrix)
|
||||
{
|
||||
if (vbo == null)
|
||||
return;
|
||||
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id);
|
||||
// 0L is the starting pointer
|
||||
LodUtil.LOD_VERTEX_FORMAT.setupBufferState(0L);
|
||||
|
||||
@@ -446,6 +469,7 @@ public class LodRenderer
|
||||
/**
|
||||
* Revert any changes that were made to the fog.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void cleanupFog(NearFarFogSettings fogSettings,
|
||||
float defaultFogStartDist, float defaultFogEndDist,
|
||||
int defaultFogMode, int defaultFogDistance)
|
||||
|
||||
@@ -22,6 +22,8 @@ package com.seibel.lod.wrappers;
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
|
||||
import com.seibel.lod.ModInfo;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
import net.minecraft.client.GameSettings;
|
||||
@@ -36,6 +38,7 @@ import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.model.ModelManager;
|
||||
import net.minecraft.client.renderer.texture.NativeImage;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
@@ -235,4 +238,20 @@ public class MinecraftWrapper
|
||||
{
|
||||
return mc.levelRenderer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Crashes Minecraft, displaying the given errorMessage <br> <br>
|
||||
* In the following format: <br>
|
||||
*
|
||||
* The game crashed whilst <strong>errorMessage</strong> <br>
|
||||
* Error: <strong>java.lang.ExceptionClass: exceptionErrorMessage</strong> <br>
|
||||
* Exit Code: -1 <br>
|
||||
*/
|
||||
public void crashMinecraft(String errorMessage, Throwable exception)
|
||||
{
|
||||
ClientProxy.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
|
||||
CrashReport report = new CrashReport(errorMessage, exception);
|
||||
Minecraft.crash(report);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ modId="lod" #mandatory
|
||||
#// The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
||||
#//${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
|
||||
#// see the associated build.gradle script for how to populate this completely automatically during a build
|
||||
version="a1.5.0" #mandatory
|
||||
version="a1.5.1" #mandatory
|
||||
|
||||
#// A display name for the mod
|
||||
displayName="Distant Horizons" #mandatory
|
||||
|
||||
Reference in New Issue
Block a user