From a7e174cf744da8e87bcd8a1009f1f5f5076984d1 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Wed, 13 Apr 2022 23:07:02 +1000 Subject: [PATCH 1/4] Changed to using IBO drawElements for quads --- .../bufferBuilding/LodQuadBuilder.java | 26 ++------- .../lod/core/objects/opengl/QuadIBO.java | 58 +++++++++++++++++++ .../objects/opengl/SimpleRenderBuffer.java | 5 +- 3 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/LodQuadBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/LodQuadBuilder.java index 557e55406..1d91cc3fb 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/LodQuadBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/LodQuadBuilder.java @@ -45,7 +45,7 @@ import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER; public class LodQuadBuilder { static final int MAX_BUFFER_SIZE = (1024 * 1024); - static final int QUAD_BYTE_SIZE = (12 * 6); + static final int QUAD_BYTE_SIZE = (12 * 4); static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE; static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); @@ -62,18 +62,12 @@ public class LodQuadBuilder { 1, 0 }, // 0 { 1, 1 }, // 1 { 0, 1 }, // 2 - - { 1, 0 }, // 0 - { 0, 1 }, // 2 { 0, 0 }, // 3 }, { // DOWN { 0, 0 }, // 0 { 0, 1 }, // 1 { 1, 1 }, // 2 - - { 0, 0 }, // 0 - { 1, 1 }, // 2 { 1, 0 }, // 3 }, @@ -82,18 +76,14 @@ public class LodQuadBuilder { 0, 0 }, // 0 { 0, 1 }, // 1 { 1, 1 }, // 2 - - { 0, 0 }, // 0 - { 1, 1 }, // 2 + { 1, 0 }, // 3 }, { // SOUTH { 1, 0 }, // 0 { 1, 1 }, // 1 { 0, 1 }, // 2 - - { 1, 0 }, // 0 - { 0, 1 }, // 2 + { 0, 0 }, // 3 }, @@ -102,18 +92,14 @@ public class LodQuadBuilder { 0, 0 }, // 0 { 1, 0 }, // 1 { 1, 1 }, // 2 - - { 0, 0 }, // 0 - { 1, 1 }, // 2 + { 0, 1 }, // 3 }, { // EAST { 0, 1 }, // 0 { 1, 1 }, // 1 { 1, 0 }, // 2 - - { 0, 1 }, // 0 - { 1, 0 }, // 2 + { 0, 0 }, // 3 }, }; @@ -406,7 +392,7 @@ public class LodQuadBuilder } bb.rewind(); vbo.unmapBuffer(method); - vbo.vertexCount = numOfQuads * 6; + vbo.vertexCount = numOfQuads * 4; return dir < 6; } diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java new file mode 100644 index 000000000..dc907021b --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java @@ -0,0 +1,58 @@ +package com.seibel.lod.core.objects.opengl; + +import org.lwjgl.system.MemoryUtil; + +import static org.lwjgl.opengl.GL11C.GL_UNSIGNED_INT; +import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; +import static org.lwjgl.opengl.GL45.*; + +public class QuadIBO { + //Datatype of the stored indices (can be GL_UNSIGNED_INT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE) + public int type; + //IBO object + int id; + //Current capacity (in quads) + int ccap; + + //Global object, used for sharing the IBO for any draw calls + public static QuadIBO GLOBAL = new QuadIBO(); + + public QuadIBO() { + id = glCreateBuffers(); + } + + public void resize(int cap) { + //If requested capacity is less than or equal to current capacity, ignore + if (cap <= ccap) + return; + //Not really necessary, just to stop constant resizes + cap *= 1.5; + System.out.println("Resizing from "+ccap+" to " + cap); + + ccap = cap; + + //TODO: DO DYNAMIC TYPES, just makes things more efficent + type = GL_UNSIGNED_INT; + int DT_SIZE = 4;//Datatype size (int: 4, short: 2, byte: 1) + + //Resize the buffer + glNamedBufferData(id, (long) DT_SIZE * 6 * cap, GL_STATIC_DRAW);// 4L is datatype + //Map and write the index data to the buffer + long ptr = nglMapNamedBuffer(id, GL_WRITE_ONLY); + for (int base = 0; base < cap; base++) { + //Write index's + MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*0),(int)(base*4 + 0)); + MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*1),(int)(base*4 + 1)); + MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*2),(int)(base*4 + 2)); + MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*3),(int)(base*4 + 2)); + MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*4),(int)(base*4 + 3)); + MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*5),(int)(base*4 + 0)); + } + glUnmapNamedBuffer(id); + } + + public void bind(int capacity) { + resize(capacity); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); + } +} diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java b/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java index e845b3ac5..b2f8864b2 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java @@ -23,7 +23,9 @@ import java.nio.ByteBuffer; import java.util.Iterator; import java.util.concurrent.TimeUnit; +import com.mojang.authlib.minecraft.client.MinecraftClient; import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; +import net.minecraft.client.Minecraft; import org.lwjgl.opengl.GL32; import com.seibel.lod.core.api.ApiShared; @@ -80,7 +82,8 @@ public class SimpleRenderBuffer extends RenderBuffer hasRendered = true; GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, vbo.id); shaderProgram.bindVertexBuffer(vbo.id); - GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, vbo.vertexCount); + QuadIBO.GLOBAL.bind(vbo.vertexCount/4); + GL32.glDrawElements(GL32.GL_TRIANGLES, (vbo.vertexCount/4)*6, QuadIBO.GLOBAL.type, 0); //LodRenderer.tickLogger.info("Vertex buffer: {}", vbo); } return hasRendered; From 351decad3401bb1acc3527dd1e31669fb9b3857d Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Wed, 13 Apr 2022 23:18:13 +1000 Subject: [PATCH 2/4] Removed accidental imports --- .../com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java b/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java index b2f8864b2..ceb4eb147 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java @@ -23,9 +23,7 @@ import java.nio.ByteBuffer; import java.util.Iterator; import java.util.concurrent.TimeUnit; -import com.mojang.authlib.minecraft.client.MinecraftClient; import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; -import net.minecraft.client.Minecraft; import org.lwjgl.opengl.GL32; import com.seibel.lod.core.api.ApiShared; From c19e2613b4e1a64d574ffa36708ab7f859a5aa1a Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Wed, 13 Apr 2022 23:24:36 +1000 Subject: [PATCH 3/4] Swapped GL 4.3 direct state accesses with GL 3.1 core features --- .../com/seibel/lod/core/objects/opengl/QuadIBO.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java index dc907021b..0fe9c7ed3 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java @@ -3,8 +3,8 @@ package com.seibel.lod.core.objects.opengl; import org.lwjgl.system.MemoryUtil; import static org.lwjgl.opengl.GL11C.GL_UNSIGNED_INT; -import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; -import static org.lwjgl.opengl.GL45.*; +import static org.lwjgl.opengl.GL15.*; +import static org.lwjgl.opengl.GL31.GL_COPY_WRITE_BUFFER; public class QuadIBO { //Datatype of the stored indices (can be GL_UNSIGNED_INT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE) @@ -18,7 +18,7 @@ public class QuadIBO { public static QuadIBO GLOBAL = new QuadIBO(); public QuadIBO() { - id = glCreateBuffers(); + id = glGenBuffers(); } public void resize(int cap) { @@ -35,10 +35,11 @@ public class QuadIBO { type = GL_UNSIGNED_INT; int DT_SIZE = 4;//Datatype size (int: 4, short: 2, byte: 1) + glBindBuffer(GL_COPY_WRITE_BUFFER, id); //Resize the buffer - glNamedBufferData(id, (long) DT_SIZE * 6 * cap, GL_STATIC_DRAW);// 4L is datatype + glBufferData(GL_COPY_WRITE_BUFFER, (long) DT_SIZE * 6 * cap, GL_STATIC_DRAW);// 4L is datatype //Map and write the index data to the buffer - long ptr = nglMapNamedBuffer(id, GL_WRITE_ONLY); + long ptr = nglMapBuffer(GL_COPY_WRITE_BUFFER, GL_WRITE_ONLY); for (int base = 0; base < cap; base++) { //Write index's MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*0),(int)(base*4 + 0)); @@ -48,7 +49,7 @@ public class QuadIBO { MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*4),(int)(base*4 + 3)); MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*5),(int)(base*4 + 0)); } - glUnmapNamedBuffer(id); + glUnmapBuffer(GL_COPY_WRITE_BUFFER); } public void bind(int capacity) { From f012ac44a77e5cae1f294fddd9a7d93631fbc457 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 13 Apr 2022 21:06:47 -0500 Subject: [PATCH 4/4] Reformat comment and optimize the bind/unbind calls --- .../lod/core/objects/opengl/QuadIBO.java | 147 ++++++++++++------ .../objects/opengl/SimpleRenderBuffer.java | 2 +- .../seibel/lod/core/render/LodRenderer.java | 5 + 3 files changed, 103 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java index 0fe9c7ed3..2ca650ef1 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java @@ -1,59 +1,106 @@ +/* + * This file is part of the Distant Horizons mod (formerly the LOD Mod), + * licensed under the GNU GPL v3 License. + * + * Copyright (C) 2020-2022 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 . + */ + package com.seibel.lod.core.objects.opengl; +import com.seibel.lod.core.api.ApiShared; import org.lwjgl.system.MemoryUtil; import static org.lwjgl.opengl.GL11C.GL_UNSIGNED_INT; import static org.lwjgl.opengl.GL15.*; import static org.lwjgl.opengl.GL31.GL_COPY_WRITE_BUFFER; -public class QuadIBO { - //Datatype of the stored indices (can be GL_UNSIGNED_INT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE) - public int type; - //IBO object - int id; - //Current capacity (in quads) - int ccap; - - //Global object, used for sharing the IBO for any draw calls - public static QuadIBO GLOBAL = new QuadIBO(); - - public QuadIBO() { - id = glGenBuffers(); - } - - public void resize(int cap) { - //If requested capacity is less than or equal to current capacity, ignore - if (cap <= ccap) - return; - //Not really necessary, just to stop constant resizes - cap *= 1.5; - System.out.println("Resizing from "+ccap+" to " + cap); - - ccap = cap; - - //TODO: DO DYNAMIC TYPES, just makes things more efficent - type = GL_UNSIGNED_INT; - int DT_SIZE = 4;//Datatype size (int: 4, short: 2, byte: 1) - - glBindBuffer(GL_COPY_WRITE_BUFFER, id); - //Resize the buffer - glBufferData(GL_COPY_WRITE_BUFFER, (long) DT_SIZE * 6 * cap, GL_STATIC_DRAW);// 4L is datatype - //Map and write the index data to the buffer - long ptr = nglMapBuffer(GL_COPY_WRITE_BUFFER, GL_WRITE_ONLY); - for (int base = 0; base < cap; base++) { - //Write index's - MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*0),(int)(base*4 + 0)); - MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*1),(int)(base*4 + 1)); - MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*2),(int)(base*4 + 2)); - MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*3),(int)(base*4 + 2)); - MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*4),(int)(base*4 + 3)); - MemoryUtil.memPutInt(ptr+(base*6*DT_SIZE+DT_SIZE*5),(int)(base*4 + 0)); - } - glUnmapBuffer(GL_COPY_WRITE_BUFFER); - } - - public void bind(int capacity) { - resize(capacity); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); - } +/** + * Represents a OpenGL Index Buffer Object. + * + * @author Cotex + * @version 4-13-2022 + */ +public class QuadIBO +{ + /** + * Datatype of the stored indices + * (can be GL_UNSIGNED_INT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE) + */ + public int type; + + /** OpenGL ID of this IBO object */ + int id; + + /** Current capacity (in quads) */ + int currentQuadCapacity; + + /** Global IBO object, used for sharing the IBO for any draw calls */ + public static QuadIBO GLOBAL = new QuadIBO(); + + + + public QuadIBO() + { + id = glGenBuffers(); + } + + + /** Should only be called on a thread that has a OpenGL context. */ + public void resizeIfNecessary(int newQuadCapacity) + { + //If the requested capacity is less than or equal to current capacity, ignore + if (newQuadCapacity <= currentQuadCapacity) + return; + + // create the new capacity bigger than necessary to prevent constant updates + newQuadCapacity *= 1.5; + ApiShared.LOGGER.info("Quad IBO Resizing from [" + currentQuadCapacity + "] to [" + newQuadCapacity + "]"); + + currentQuadCapacity = newQuadCapacity; + + //TODO: DO DYNAMIC TYPES, just makes things more efficient + type = GL_UNSIGNED_INT; + int DT_SIZE = 4; //Datatype size (int: 4, short: 2, byte: 1) + + glBindBuffer(GL_COPY_WRITE_BUFFER, id); + //Resize the buffer + glBufferData(GL_COPY_WRITE_BUFFER, (long) DT_SIZE * 6 * newQuadCapacity, GL_STATIC_DRAW);// 4L is datatype + //Map and write the index data to the buffer + long arrayPointer = nglMapBuffer(GL_COPY_WRITE_BUFFER, GL_WRITE_ONLY); + for (int base = 0; base < newQuadCapacity; base++) + { + // Add the new quad's indices + MemoryUtil.memPutInt(arrayPointer + (base * 6L * DT_SIZE + DT_SIZE * 0), (int) (base * 4 + 0)); + MemoryUtil.memPutInt(arrayPointer + (base * 6L * DT_SIZE + DT_SIZE * 1), (int) (base * 4 + 1)); + MemoryUtil.memPutInt(arrayPointer + (base * 6L * DT_SIZE + DT_SIZE * 2), (int) (base * 4 + 2)); + MemoryUtil.memPutInt(arrayPointer + (base * 6L * DT_SIZE + DT_SIZE * 3), (int) (base * 4 + 2)); + MemoryUtil.memPutInt(arrayPointer + (base * 6L * DT_SIZE + DT_SIZE * 4), (int) (base * 4 + 3)); + MemoryUtil.memPutInt(arrayPointer + (base * 6L * DT_SIZE + DT_SIZE * 5), (int) (base * 4 + 0)); + } + glUnmapBuffer(GL_COPY_WRITE_BUFFER); + } + + /** Binds the IBO */ + public void bind() + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); + } + + /** Unbinds the IBO */ + public void unbind() + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } } diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java b/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java index ceb4eb147..a0bd14e04 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/SimpleRenderBuffer.java @@ -80,7 +80,7 @@ public class SimpleRenderBuffer extends RenderBuffer hasRendered = true; GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, vbo.id); shaderProgram.bindVertexBuffer(vbo.id); - QuadIBO.GLOBAL.bind(vbo.vertexCount/4); + QuadIBO.GLOBAL.resizeIfNecessary(vbo.vertexCount/4); GL32.glDrawElements(GL32.GL_TRIANGLES, (vbo.vertexCount/4)*6, QuadIBO.GLOBAL.type, 0); //LodRenderer.tickLogger.info("Vertex buffer: {}", vbo); } diff --git a/src/main/java/com/seibel/lod/core/render/LodRenderer.java b/src/main/java/com/seibel/lod/core/render/LodRenderer.java index 699723980..d1af156a9 100644 --- a/src/main/java/com/seibel/lod/core/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/core/render/LodRenderer.java @@ -29,6 +29,7 @@ import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.logging.SpamReducedLogger; import com.seibel.lod.core.objects.BoolType; import com.seibel.lod.core.objects.Pos2D; +import com.seibel.lod.core.objects.opengl.QuadIBO; import com.seibel.lod.core.render.objects.GLState; import com.seibel.lod.core.util.*; import com.seibel.lod.core.util.gridList.*; @@ -318,6 +319,9 @@ public class LodRenderer LagSpikeCatcher drawFillLightmap = new LagSpikeCatcher(); ILightMapWrapper lightmap = MC_RENDER.getLightmapWrapper(); lightmap.bind(); + + QuadIBO.GLOBAL.bind(); + //lightmapTexture.fillData(MC_RENDER.getLightmapTextureWidth(), MC_RENDER.getLightmapTextureHeight(), MC_RENDER.getLightmapPixels()); drawFillLightmap.end("drawFillLightmap"); drawFillData.end("DrawFillData"); @@ -372,6 +376,7 @@ public class LodRenderer profiler.popPush("LOD cleanup"); LagSpikeCatcher drawCleanup = new LagSpikeCatcher(); lightmap.unbind(); + QuadIBO.GLOBAL.unbind(); GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0);