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..2ca650ef1 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/opengl/QuadIBO.java @@ -0,0 +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; + +/** + * 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 e845b3ac5..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,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.resizeIfNecessary(vbo.vertexCount/4); + GL32.glDrawElements(GL32.GL_TRIANGLES, (vbo.vertexCount/4)*6, QuadIBO.GLOBAL.type, 0); //LodRenderer.tickLogger.info("Vertex buffer: {}", vbo); } return hasRendered; 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);