From 3e42541fe902f081294c4203e4570c72ede6697e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 9 Apr 2022 21:28:30 -0500 Subject: [PATCH] Refactor LodQuadBuilder --- .../BufferMergeDirectionEnum.java | 35 + .../bufferBuilding/BufferQuad.java | 278 +++++++ .../bufferBuilding/CubicLodTemplate.java | 4 - .../bufferBuilding/LodQuadBuilder.java | 468 ++++++++++++ .../seibel/lod/core/enums/LodDirection.java | 13 +- .../lod/core/objects/opengl/LodBox.java | 2 +- .../core/objects/opengl/LodQuadBuilder.java | 693 ------------------ .../lod/core/objects/opengl/RenderBuffer.java | 1 + .../lod/core/objects/opengl/RenderRegion.java | 5 +- .../objects/opengl/SimpleRenderBuffer.java | 7 +- 10 files changed, 800 insertions(+), 706 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferMergeDirectionEnum.java create mode 100644 src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferQuad.java create mode 100644 src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/LodQuadBuilder.java delete mode 100644 src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferMergeDirectionEnum.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferMergeDirectionEnum.java new file mode 100644 index 000000000..991987d3f --- /dev/null +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferMergeDirectionEnum.java @@ -0,0 +1,35 @@ +/* + * 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.builders.lodBuilding.bufferBuilding; + +/** + * EastWest
+ * NorthSouthOrUpDown + * + * @author James Seibel + * @version 2022-4-9 + */ +public enum BufferMergeDirectionEnum +{ + EastWest, + + /** NorthSouth and UpDown are merged since */ + NorthSouthOrUpDown +} diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferQuad.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferQuad.java new file mode 100644 index 000000000..5b8131c8f --- /dev/null +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/BufferQuad.java @@ -0,0 +1,278 @@ +/* + * 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.builders.lodBuilding.bufferBuilding; + +import com.seibel.lod.core.enums.LodDirection; +import com.seibel.lod.core.util.ColorUtil; + +import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER; + +/** + * Represents a renderable quad. + * + * @author James Seibel + * @author ? + * @version 4-9-2022 + */ +public class BufferQuad +{ + final short x; + final short y; + final short z; + short widthEastWest; + /** This is both North/South and Up/Down since the merging logic is the same either way */ + short widthNorthSouthOrUpDown; + int color; + final byte skyLight; + final byte blockLight; + final LodDirection direction; + + + BufferQuad(short x, short y, short z, short widthEastWest, short widthNorthSouthOrUpDown, + int color, byte skylight, byte blocklight, + LodDirection direction) + { + if (widthEastWest == 0 || widthNorthSouthOrUpDown == 0) + throw new IllegalArgumentException("Size 0 quad!"); + if (widthEastWest < 0 || widthNorthSouthOrUpDown < 0) + throw new IllegalArgumentException("Negative sized quad!"); + + this.x = x; + this.y = y; + this.z = z; + this.widthEastWest = widthEastWest; + this.widthNorthSouthOrUpDown = widthNorthSouthOrUpDown; + this.color = color; + this.skyLight = skylight; + this.blockLight = blocklight; + this.direction = direction; + } + + + + /** a rough but fast calculation */ + double calculateDistance(double relativeX, double relativeY, double relativeZ) + { + return Math.pow(relativeX - x, 2) + Math.pow(relativeY - y, 2) + Math.pow(relativeZ - z, 2); + } + + + /** compares this quad's position to the given quad */ + public int compare(BufferQuad quad, BufferMergeDirectionEnum compareDirection) + { + if (direction != quad.direction) + throw new IllegalArgumentException("The other quad is not in the same direction: " + quad.direction + " vs " + direction); + + if (compareDirection == BufferMergeDirectionEnum.EastWest) + { + switch (direction.getAxis()) + { + case X: + return threeDimensionalCompare(x, y, z, quad.x, quad.y, quad.z); + case Y: + return threeDimensionalCompare(y, z, x, quad.y, quad.z, quad.x); + case Z: + return threeDimensionalCompare(z, y, x, quad.z, quad.y, quad.x); + + default: + throw new IllegalArgumentException("Invalid Axis enum: " + direction.getAxis()); + } + } + else // if () + { + switch (direction.getAxis()) + { + case X: + return threeDimensionalCompare(x, z, y, quad.x, quad.z, quad.y); + case Y: + return threeDimensionalCompare(y, x, z, quad.y, quad.x, quad.z); + case Z: + return threeDimensionalCompare(z, x, y, quad.z, quad.x, quad.y); + + default: + throw new IllegalArgumentException("Invalid Axis enum: " + direction.getAxis()); + } + } + } + /** + * Compares two 3D points A and B.
+ * The X, Y, and Z coordinates can be passed into parameters 0, 1, and 2 in any order + * provided they are in the same order for both A and B.
+ * With the 0th parameter being the most significant when comparing. + */ + private static int threeDimensionalCompare(short a0, short a1, short a2, short b0, short b1, short b2) + { + long a = (long) a0 << 48 | (long) a1 << 32 | (long) a2 << 16; + long b = (long) b0 << 48 | (long) b1 << 32 | (long) b2 << 16; + return Long.compare(a, b); + } + + + /** + * Attempts to merge the given quad into this one. + * @returns true if the quads were merged, false otherwise. + */ + public boolean tryMerge(BufferQuad quad, BufferMergeDirectionEnum mergeDirection) + { + // only merge quads that are in the same direction + if (direction != quad.direction) + return false; + + // make sure these quads share the same perpendicular axis + if ((mergeDirection == BufferMergeDirectionEnum.EastWest && this.y != quad.y) || + (mergeDirection == BufferMergeDirectionEnum.NorthSouthOrUpDown && this.x != quad.x)) + { + return false; + } + + + // get the position of each quad to compare against + short thisPerpendicularCompareStartPos; // edge perpendicular to the merge direction + short thisParallelCompareStartPos; // edge parallel to the merge direction + short otherPerpendicularCompareStartPos; + short otherParallelCompareStartPos; + switch (this.direction.getAxis()) + { + default: // shouldn't normally happen, just here to make the compiler happy + case X: + if (mergeDirection == BufferMergeDirectionEnum.EastWest) + { + thisPerpendicularCompareStartPos = this.z; + thisParallelCompareStartPos = this.x; + + otherPerpendicularCompareStartPos = quad.z; + otherParallelCompareStartPos = quad.x; + } + else //if (mergeDirection == MergeDirection.NorthSouthOrUpDown) + { + thisPerpendicularCompareStartPos = this.y; + thisParallelCompareStartPos = this.z; + + otherPerpendicularCompareStartPos = quad.y; + otherParallelCompareStartPos = quad.z; + } + break; + + case Y: + if (mergeDirection == BufferMergeDirectionEnum.EastWest) + { + thisPerpendicularCompareStartPos = this.x; + thisParallelCompareStartPos = this.z; + + otherPerpendicularCompareStartPos = quad.x; + otherParallelCompareStartPos = quad.z; + } + else //if (mergeDirection == MergeDirection.NorthSouthOrUpDown) + { + thisPerpendicularCompareStartPos = this.z; + thisParallelCompareStartPos = this.y; + + otherPerpendicularCompareStartPos = quad.z; + otherParallelCompareStartPos = quad.y; + } + break; + + case Z: + if (mergeDirection == BufferMergeDirectionEnum.EastWest) + { + thisPerpendicularCompareStartPos = this.x; + thisParallelCompareStartPos = this.z; + + otherPerpendicularCompareStartPos = quad.x; + otherParallelCompareStartPos = quad.z; + } + else //if (mergeDirection == MergeDirection.NorthSouthOrUpDown) + { + thisPerpendicularCompareStartPos = this.y; + thisParallelCompareStartPos = this.z; + + otherPerpendicularCompareStartPos = quad.y; + otherParallelCompareStartPos = quad.z; + } + break; + } + + // get the width of this quad in the relevant axis + short thisPerpendicularCompareWidth; + short thisParallelCompareWidth; + short otherParallelCompareWidth; + if (mergeDirection == BufferMergeDirectionEnum.EastWest) + { + thisPerpendicularCompareWidth = this.widthEastWest; + + thisParallelCompareWidth = this.widthNorthSouthOrUpDown; + otherParallelCompareWidth = quad.widthNorthSouthOrUpDown; + } + else + { + thisPerpendicularCompareWidth = this.widthNorthSouthOrUpDown; + + thisParallelCompareWidth = this.widthEastWest; + otherParallelCompareWidth = quad.widthEastWest; + } + + + + // check if these quads are adjacent + if (thisPerpendicularCompareStartPos + thisPerpendicularCompareWidth < otherPerpendicularCompareStartPos || + thisParallelCompareStartPos != otherParallelCompareStartPos) + { + // these quads aren't adjacent, they can't be merged + return false; + } + else if (thisPerpendicularCompareStartPos + thisPerpendicularCompareWidth > otherPerpendicularCompareStartPos) + { + // these quads are overlapping, they can't be merged + EVENT_LOGGER.warn("Overlapping quads detected!"); + quad.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + + + // only merge quads that have the same width edges + if (thisParallelCompareWidth != otherParallelCompareWidth) + { + return false; + } + + // do the quads' color, light, etc. match? + if (color != quad.color || + skyLight != quad.skyLight || + blockLight != quad.blockLight) + { + // we can only merge identically colored/lit quads + return false; + } + + // merge the two quads + if (mergeDirection == BufferMergeDirectionEnum.NorthSouthOrUpDown) + { + widthNorthSouthOrUpDown += quad.widthNorthSouthOrUpDown; + } + else // if (mergeDirection == MergeDirection.EastWest) + { + widthEastWest += quad.widthEastWest; + } + + // merge successful + return true; + } + +} diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java index 7cc5c8c6e..21e77830c 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java @@ -19,19 +19,15 @@ package com.seibel.lod.core.builders.lodBuilding.bufferBuilding; -import com.seibel.lod.core.api.ApiShared; import com.seibel.lod.core.enums.rendering.DebugMode; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.objects.opengl.LodBox; -import com.seibel.lod.core.objects.opengl.LodQuadBuilder; import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.util.DataPointUtil; import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; -import java.awt.*; - /** * Builds LODs as rectangular prisms. * @author James Seibel 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 new file mode 100644 index 000000000..557e55406 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/LodQuadBuilder.java @@ -0,0 +1,468 @@ +/* + * 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.builders.lodBuilding.bufferBuilding; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.ListIterator; + +import com.seibel.lod.core.builders.lodBuilding.LodBuilder; +import com.seibel.lod.core.enums.LodDirection; +import com.seibel.lod.core.enums.LodDirection.Axis; +import com.seibel.lod.core.enums.config.GpuUploadMethod; +import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; +import com.seibel.lod.core.objects.opengl.LodVertexBuffer; +import com.seibel.lod.core.util.ColorUtil; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; + +import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER; + +/** + * Used to create the quads before they are converted to renderable buffers. + * + * @version 2022-4-9 + */ +public class LodQuadBuilder +{ + static final int MAX_BUFFER_SIZE = (1024 * 1024); + static final int QUAD_BYTE_SIZE = (12 * 6); + static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE; + + static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + + public final boolean skipQuadsWithZeroSkylight; + public final short skyLightCullingBelow; + + final ArrayList[] quads = (ArrayList[]) new ArrayList[6]; + + public static final int[][][] DIRECTION_VERTEX_QUAD = new int[][][] + { + // X,Z // + { // UP + { 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 + }, + + // X,Y // + { // NORTH + { 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 + }, + + // Z,Y // + { // WEST + { 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 + }, + }; + + + + public LodQuadBuilder(boolean enableSkylightCulling, int skyLightCullingBelow) + { + for (int i = 0; i < 6; i++) + quads[i] = new ArrayList<>(); + + this.skipQuadsWithZeroSkylight = enableSkylightCulling; + this.skyLightCullingBelow = (short) (skyLightCullingBelow - LodBuilder.MIN_WORLD_HEIGHT); + } + + + + + public void addQuadAdj(LodDirection dir, short x, short y, short z, + short widthEastWest, short widthNorthSouthOrUpDown, + int color, byte skylight, byte blocklight) + { + if (dir.ordinal() <= LodDirection.DOWN.ordinal()) + throw new IllegalArgumentException("addQuadAdj() is only for adj direction! Not UP or Down!"); + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[dir.ordinal()].add(new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, dir)); + } + + // XZ + public void addQuadUp(short x, short y, short z, short width, short wz, int color, byte skylight, byte blocklight) + { + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[LodDirection.UP.ordinal()].add(new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, LodDirection.UP)); + } + + public void addQuadDown(short x, short y, short z, short width, short wz, int color, byte skylight, byte blocklight) + { + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[LodDirection.DOWN.ordinal()].add(new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, LodDirection.DOWN)); + } + + // XY + public void addQuadN(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight) + { + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[LodDirection.NORTH.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.NORTH)); + } + + public void addQuadS(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight) + { + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[LodDirection.SOUTH.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.SOUTH)); + } + + // ZY + public void addQuadW(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight) + { + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[LodDirection.WEST.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.WEST)); + } + + public void addQuadE(short x, short y, short z, short width, short wy, int color, byte skylight, byte blocklight) + { + if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow) + return; + quads[LodDirection.EAST.ordinal()].add(new BufferQuad(x, y, z, width, wy, color, skylight, blocklight, LodDirection.EAST)); + } + + + + private static void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight) + { + skylight %= 16; + blocklight %= 16; + + bb.putShort(x); + bb.putShort(y); + bb.putShort(z); + + bb.putShort((short) (skylight | (blocklight << 4))); + byte r = (byte) ColorUtil.getRed(color); + byte g = (byte) ColorUtil.getGreen(color); + byte b = (byte) ColorUtil.getBlue(color); + byte a = (byte) ColorUtil.getAlpha(color); + bb.put(r); + bb.put(g); + bb.put(b); + bb.put(a); + } + + private static void putQuad(ByteBuffer bb, BufferQuad quad) + { + int[][] quadBase = DIRECTION_VERTEX_QUAD[quad.direction.ordinal()]; + short widthEastWest = quad.widthEastWest; + short widthNorthSouth = quad.widthNorthSouthOrUpDown; + Axis axis = quad.direction.getAxis(); + for (int i = 0; i < quadBase.length; i++) + { + short dx, dy, dz; + switch (axis) + { + case X: // ZY + dx = 0; + dy = quadBase[i][1] == 1 ? widthNorthSouth : 0; + dz = quadBase[i][0] == 1 ? widthEastWest : 0; + break; + case Y: // XZ + dx = quadBase[i][0] == 1 ? widthEastWest : 0; + dy = 0; + dz = quadBase[i][1] == 1 ? widthNorthSouth : 0; + break; + case Z: // XY + dx = quadBase[i][0] == 1 ? widthEastWest : 0; + dy = quadBase[i][1] == 1 ? widthNorthSouth : 0; + dz = 0; + break; + default: + throw new IllegalArgumentException("Invalid Axis enum: " + axis); + } + putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz), quad.color, + quad.skyLight, quad.blockLight); + } + } + + /** Uses Greedy meshing to merge this builder's Quads. */ + public void mergeQuads() + { + long mergeCount = 0; + long preQuadsCount = getCurrentQuadsCount(); + if (preQuadsCount <= 1) + return; + + for (int directionIndex = 0; directionIndex < 6; directionIndex++) + { + mergeCount += mergeQuadsInternal(directionIndex, BufferMergeDirectionEnum.EastWest); + + // only merge after the top has been merged + if (directionIndex == 1) + { + long pass2 = mergeQuadsInternal(directionIndex, BufferMergeDirectionEnum.NorthSouthOrUpDown); + mergeCount += pass2; + } + } + long postQuadsCount = getCurrentQuadsCount(); + //if (mergeCount != 0) + EVENT_LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount / (double) preQuadsCount); + } + /** Merges all of this builder's quads for the given directionIndex (up, down, left, etc.) in the given direction */ + private long mergeQuadsInternal(int directionIndex, BufferMergeDirectionEnum mergeDirection) + { + if (quads[directionIndex].size() <= 1) + return 0; + + quads[directionIndex].sort( (objOne, objTwo) -> objOne.compare(objTwo, mergeDirection) ); + + long mergeCount = 0; + ListIterator iter = quads[directionIndex].listIterator(); + BufferQuad currentQuad = iter.next(); + while (iter.hasNext()) + { + BufferQuad nextQuad = iter.next(); + + if (currentQuad.tryMerge(nextQuad, mergeDirection)) + { + // merge successful, attempt to merge the next quad + mergeCount++; + iter.set(null); + } + else + { + // merge fail, move on to the next quad + currentQuad = nextQuad; + } + } + quads[directionIndex].removeIf(o -> o == null); + return mergeCount; + } + + + + public Iterator makeVertexBuffers() + { + return new Iterator() + { + final ByteBuffer bb = ByteBuffer.allocateDirect(MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE) + .order(ByteOrder.nativeOrder()); + int dir = skipEmpty(0); + int quad = 0; + + private int skipEmpty(int d) + { + while (d < 6 && quads[d].isEmpty()) + d++; + return d; + } + + @Override + public boolean hasNext() + { + return dir < 6; + } + + @Override + public ByteBuffer next() + { + if (dir >= 6) + { + return null; + } + bb.clear(); + bb.limit(MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE); + while (bb.hasRemaining() && dir < 6) + { + writeData(); + } + bb.limit(bb.position()); + bb.rewind(); + return bb; + } + + private void writeData() + { + int i = quad; + for (; i < quads[dir].size(); i++) + { + if (!bb.hasRemaining()) + { + break; + } + putQuad(bb, quads[dir].get(i)); + } + + if (i >= quads[dir].size()) + { + quad = 0; + dir++; + dir = skipEmpty(dir); + } + else + { + quad = i; + } + } + }; + } + + public interface BufferFiller + { + /** If true: more data needs to be filled */ + boolean fill(LodVertexBuffer vbo); + } + + public BufferFiller makeBufferFiller(GpuUploadMethod method) + { + return new BufferFiller() + { + int dir = 0; + int quad = 0; + + public boolean fill(LodVertexBuffer vbo) + { + if (dir >= 6) + { + vbo.vertexCount = 0; + return false; + } + + int numOfQuads = _countRemainingQuads(); + if (numOfQuads > MAX_QUADS_PER_BUFFER) + numOfQuads = MAX_QUADS_PER_BUFFER; + if (numOfQuads == 0) + { + vbo.vertexCount = 0; + return false; + } + ByteBuffer bb = vbo.mapBuffer(numOfQuads * QUAD_BYTE_SIZE, method, MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE); + if (bb == null) + throw new NullPointerException("mapBuffer returned null"); + bb.clear(); + bb.limit(numOfQuads * QUAD_BYTE_SIZE); + while (bb.hasRemaining() && dir < 6) + { + writeData(bb); + } + bb.rewind(); + vbo.unmapBuffer(method); + vbo.vertexCount = numOfQuads * 6; + return dir < 6; + } + + private int _countRemainingQuads() + { + int a = quads[dir].size() - quad; + for (int i = dir + 1; i < quads.length; i++) + { + a += quads[i].size(); + } + return a; + } + + private void writeData(ByteBuffer bb) + { + int startQ = quad; + + int i = startQ; + for (i = startQ; i < quads[dir].size(); i++) + { + if (!bb.hasRemaining()) + { + break; + } + putQuad(bb, quads[dir].get(i)); + } + + if (i >= quads[dir].size()) + { + quad = 0; + dir++; + while (dir < 6 && quads[dir].isEmpty()) + dir++; + } + else + { + quad = i; + } + } + }; + } + + + + public int getCurrentQuadsCount() + { + int i = 0; + for (ArrayList qs : quads) + i += qs.size(); + return i; + } + + /** Returns how many Buffers will be needed to render everything in this builder. */ + public int getCurrentNeededVertexBufferCount() + { + return LodUtil.ceilDiv(getCurrentQuadsCount(), MAX_QUADS_PER_BUFFER); + } + +} diff --git a/src/main/java/com/seibel/lod/core/enums/LodDirection.java b/src/main/java/com/seibel/lod/core/enums/LodDirection.java index 7e1b4c2b6..8007ddc00 100644 --- a/src/main/java/com/seibel/lod/core/enums/LodDirection.java +++ b/src/main/java/com/seibel/lod/core/enums/LodDirection.java @@ -28,11 +28,18 @@ import java.util.stream.Collectors; import com.seibel.lod.core.objects.math.Vec3i; /** - * A (almost) exact copy of Minecraft's + * An (almost) exact copy of Minecraft's * Direction enum. - * + * + * Up
+ * Down
+ * North
+ * South
+ * East
+ * West
+ * * @author James Seibel - * @version 11-13-2021 + * @version 2021-11-13 */ public enum LodDirection { diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java index 1cd34b9a2..bdde5c9e3 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java @@ -19,11 +19,11 @@ package com.seibel.lod.core.objects.opengl; +import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; import com.seibel.lod.core.enums.LodDirection; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.util.DataPointUtil; -import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; public class LodBox diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java deleted file mode 100644 index 347e12b8b..000000000 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java +++ /dev/null @@ -1,693 +0,0 @@ -/* - * 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 java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; - -import com.seibel.lod.core.builders.lodBuilding.LodBuilder; -import com.seibel.lod.core.enums.LodDirection; -import com.seibel.lod.core.enums.LodDirection.Axis; -import com.seibel.lod.core.enums.config.GpuUploadMethod; -import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.util.ColorUtil; -import com.seibel.lod.core.util.LodUtil; -import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; - -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 MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE; - //static final int MAX_MERGED_QUAD_SIZE = 64; - - static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); - - public final boolean skipSkylight0Quads; - public final short skyLightCullingBelow; - - static class Quad - { - final short x; - final short y; - final short z; - short w0; - short w1; - int color; - final byte skylight; - final byte blocklight; - final LodDirection dir; - double distance = 0d; - - Quad(short x, short y, short z, short w0, short w1, int color, byte skylight, byte blocklight, - LodDirection dir) - { - if (w0 == 0 || w1 == 0) - throw new IllegalArgumentException("Size 0 quad!"); - if (w0 < 0 || w1 < 0) - throw new IllegalArgumentException("Negative sized quad!"); - this.x = x; - this.y = y; - this.z = z; - this.w0 = w0; - this.w1 = w1; - this.color = color; - this.skylight = skylight; - this.blocklight = blocklight; - this.dir = dir; - } - - private static double pow(double d) - { - return d * d; - } - - // NOTE: This is only a rough but fast calculation! - void calculateDistance(double relativeX, double relativeY, double relativeZ) - { - distance = pow(relativeX - x) + pow(relativeY - y) + pow(relativeZ - z); - } - - private static int _compondCompare(short a0, short a1, short a2, short b0, short b1, short b2) - { - long a = (long) a0 << 48 | (long) a1 << 32 | (long) a2 << 16; - long b = (long) b0 << 48 | (long) b1 << 32 | (long) b2 << 16; - return Long.compare(a, b); - } - - public int compareTo1(Quad o) - { - if (dir != o.dir) - throw new IllegalArgumentException("The other quad is not in the same direction: " + o.dir + " vs " + dir); - switch (dir.getAxis()) - { - case X: - return _compondCompare(x, y, z, o.x, o.y, o.z); - case Y: - return _compondCompare(y, z, x, o.y, o.z, o.x); - case Z: - return _compondCompare(z, y, x, o.z, o.y, o.x); - default: - throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); - } - } - - public int compareTo2(Quad o) - { - if (dir != o.dir) - throw new IllegalArgumentException("The other quad is not in the same direction: " + o.dir + " vs " + dir); - switch (dir.getAxis()) - { - case X: - return _compondCompare(x, z, y, o.x, o.z, o.y); - case Y: - return _compondCompare(y, x, z, o.y, o.x, o.z); - case Z: - return _compondCompare(z, x, y, o.z, o.x, o.y); - default: - throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); - } - } - - public boolean tryMergeWith1(Quad o) - { - if (dir != o.dir) - return false; - //if (w0 >= MAX_MERGED_QUAD_SIZE) return false; - switch (dir.getAxis()) - { - case X: - if (x != o.x || - y != o.y || - z + w0 < o.z) - return false; - if (z + w0 > o.z) - { - EVENT_LOGGER.warn("Overlapping quads detected!"); - o.color = ColorUtil.rgbToInt(255, 0, 0); - return false; - } - if (w1 != o.w1 || - color != o.color || - skylight != o.skylight || - blocklight != o.blocklight) - return false; - - w0 += o.w0; - return true; - case Y: - if (y != o.y || - z != o.z || - x + w0 < o.x) - return false; - if (x + w0 > o.x) - { - EVENT_LOGGER.warn("Overlapping quads detected!"); - o.color = ColorUtil.rgbToInt(255, 0, 0); - return false; - } - if (w1 != o.w1 || - color != o.color || - skylight != o.skylight || - blocklight != o.blocklight) - return false; - - w0 += o.w0; - return true; - case Z: - if (z != o.z || - y != o.y || - x + w0 < o.x) - return false; - if (x + w0 > o.x) - { - EVENT_LOGGER.warn("Overlapping quads detected!"); - o.color = ColorUtil.rgbToInt(255, 0, 0); - return false; - } - if (w1 != o.w1 || - color != o.color || - skylight != o.skylight || - blocklight != o.blocklight) - return false; - - w0 += o.w0; - return true; - default: - throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); - } - } - - public boolean tryMergeWith2(Quad o) - { - if (dir != o.dir) - return false; - //if (w1 >= MAX_MERGED_QUAD_SIZE) return false; - switch (dir.getAxis()) - { - case X: - if (x != o.x || - z != o.z || - y + w1 < o.y) - return false; - if (y + w1 > o.y) - { - EVENT_LOGGER.warn("Overlapping quads detected!"); - o.color = ColorUtil.rgbToInt(255, 0, 0); - return false; - } - if (w0 != o.w0 || - color != o.color || - skylight != o.skylight || - blocklight != o.blocklight) - return false; - w1 += o.w1; - return true; - case Y: - if (y != o.y || - x != o.x || - z + w1 < o.z) - return false; - if (z + w1 > o.z) - { - EVENT_LOGGER.warn("Overlapping quads detected!"); - o.color = ColorUtil.rgbToInt(255, 0, 0); - return false; - } - if (w0 != o.w0 || - color != o.color || - skylight != o.skylight || - blocklight != o.blocklight) - return false; - w1 += o.w1; - return true; - case Z: - if (z != o.z || - x != o.x || - y + w1 < o.y) - return false; - if (y + w1 > o.y) - { - EVENT_LOGGER.warn("Overlapping quads detected!"); - o.color = ColorUtil.rgbToInt(255, 0, 0); - return false; - } - if (w0 != o.w0 || - color != o.color || - skylight != o.skylight || - blocklight != o.blocklight) - return false; - w1 += o.w1; - return true; - default: - throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); - } - } - - } - - final ArrayList[] quads = (ArrayList[]) new ArrayList[6]; - - public LodQuadBuilder(int initialSize, boolean enableSkylightCulling, int skyLightCullingBelow) - { - for (int i = 0; i < 6; i++) - quads[i] = new ArrayList(); - this.skipSkylight0Quads = enableSkylightCulling; - this.skyLightCullingBelow = (short) (skyLightCullingBelow - LodBuilder.MIN_WORLD_HEIGHT); - } - - public void addQuadAdj(LodDirection dir, short x, short y, short z, short w0, short wy, int color, byte skylight, - byte blocklight) - { - if (dir.ordinal() <= LodDirection.DOWN.ordinal()) - throw new IllegalArgumentException("addQuadAdj() is only for adj direction! Not UP or Down!"); - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[dir.ordinal()].add(new Quad(x, y, z, w0, wy, color, skylight, blocklight, dir)); - } - - // XZ - public void addQuadUp(short x, short y, short z, short wx, short wz, int color, byte skylight, byte blocklight) - { - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[LodDirection.UP.ordinal()].add(new Quad(x, y, z, wx, wz, color, skylight, blocklight, LodDirection.UP)); - } - - public void addQuadDown(short x, short y, short z, short wx, short wz, int color, byte skylight, byte blocklight) - { - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[LodDirection.DOWN.ordinal()].add(new Quad(x, y, z, wx, wz, color, skylight, blocklight, LodDirection.DOWN)); - } - - // XY - public void addQuadN(short x, short y, short z, short wx, short wy, int color, byte skylight, byte blocklight) - { - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[LodDirection.NORTH.ordinal()].add(new Quad(x, y, z, wx, wy, color, skylight, blocklight, LodDirection.NORTH)); - } - - public void addQuadS(short x, short y, short z, short wx, short wy, int color, byte skylight, byte blocklight) - { - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[LodDirection.SOUTH.ordinal()].add(new Quad(x, y, z, wx, wy, color, skylight, blocklight, LodDirection.SOUTH)); - } - - // ZY - public void addQuadW(short x, short y, short z, short wz, short wy, int color, byte skylight, byte blocklight) - { - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[LodDirection.WEST.ordinal()].add(new Quad(x, y, z, wz, wy, color, skylight, blocklight, LodDirection.WEST)); - } - - public void addQuadE(short x, short y, short z, short wz, short wy, int color, byte skylight, byte blocklight) - { - if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow) - return; - quads[LodDirection.EAST.ordinal()].add(new Quad(x, y, z, wz, wy, color, skylight, blocklight, LodDirection.EAST)); - } - - private static void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight) - { - skylight %= 16; - blocklight %= 16; - - bb.putShort(x); - bb.putShort(y); - bb.putShort(z); - - bb.putShort((short) (skylight | (blocklight << 4))); - byte r = (byte) ColorUtil.getRed(color); - byte g = (byte) ColorUtil.getGreen(color); - byte b = (byte) ColorUtil.getBlue(color); - byte a = (byte) ColorUtil.getAlpha(color); - bb.put(r); - bb.put(g); - bb.put(b); - bb.put(a); - } - - private static void putQuad(ByteBuffer bb, Quad quad) - { - int[][] quadBase = DIRECTION_VERTEX_QUAD[quad.dir.ordinal()]; - short d0 = quad.w0; - short d1 = quad.w1; - Axis axis = quad.dir.getAxis(); - for (int i = 0; i < quadBase.length; i++) - { - short dx, dy, dz; - switch (axis) - { - case X: // ZY - dx = 0; - dz = quadBase[i][0] == 1 ? d0 : 0; - dy = quadBase[i][1] == 1 ? d1 : 0; - break; - case Y: // XZ - dy = 0; - dx = quadBase[i][0] == 1 ? d0 : 0; - dz = quadBase[i][1] == 1 ? d1 : 0; - break; - case Z: // XY - dz = 0; - dx = quadBase[i][0] == 1 ? d0 : 0; - dy = quadBase[i][1] == 1 ? d1 : 0; - break; - default: - throw new IllegalArgumentException("Invalid Axis enum: " + axis); - } - putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz), quad.color, - quad.skylight, quad.blocklight); - } - } - - public void sort(double dPlayerPosX, double dPlayerPosY, double dPlayerPosZ) - { - - } - - private long mergeQuadsPass1(int dir) - { - if (quads[dir].size() <= 1) - return 0; - quads[dir].sort(Quad::compareTo1); - ListIterator iter = quads[dir].listIterator(); - long mergeCount = 0; - Quad currentQuad = iter.next(); - while (iter.hasNext()) - { - Quad nextQuad = iter.next(); - if (currentQuad.tryMergeWith1(nextQuad)) - { - mergeCount++; - iter.set(null); - } - else - { - currentQuad = nextQuad; - } - } - quads[dir].removeIf(o -> o == null); - return mergeCount; - } - - private long mergeQuadsPass2(int dir) - { - if (quads[dir].size() <= 1) - return 0; - quads[dir].sort(Quad::compareTo2); - ListIterator iter = quads[dir].listIterator(); - long mergeCount = 0; - Quad currentQuad = iter.next(); - while (iter.hasNext()) - { - Quad nextQuad = iter.next(); - if (currentQuad.tryMergeWith2(nextQuad)) - { - mergeCount++; - iter.set(null); - } - else - { - currentQuad = nextQuad; - } - } - quads[dir].removeIf(o -> o == null); - return mergeCount; - } - - - - public void mergeQuads() - { - long mergeCount = 0; - long preQuadsCount = getCurrentQuadsCount(); - if (preQuadsCount <= 1) - return; - for (int i = 0; i < 6; i++) - { - mergeCount += mergeQuadsPass1(i); - if (i >= 2) - { - continue; - //long pass2 = mergeQuadsPass2(i); - //mergeCount += pass2; - //skipperMerge += pass2; - } - else - { - long pass2 = mergeQuadsPass2(i); - mergeCount += pass2; - } - } - long postQuadsCount = getCurrentQuadsCount(); - //if (mergeCount != 0) - EVENT_LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount / (double) preQuadsCount); - } - - public Iterator makeVertexBuffers() - { - return new Iterator() - { - final ByteBuffer bb = ByteBuffer.allocateDirect(MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE) - .order(ByteOrder.nativeOrder()); - int dir = skipEmpty(0); - int quad = 0; - - private int skipEmpty(int d) - { - while (d < 6 && quads[d].isEmpty()) - d++; - return d; - } - - @Override - public boolean hasNext() - { - return dir < 6; - } - - @Override - public ByteBuffer next() - { - if (dir >= 6) - { - return null; - } - bb.clear(); - bb.limit(MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE); - while (bb.hasRemaining() && dir < 6) - { - writeData(); - } - bb.limit(bb.position()); - bb.rewind(); - return bb; - } - - private void writeData() - { - int startQ = quad; - - int i = startQ; - for (i = startQ; i < quads[dir].size(); i++) - { - if (!bb.hasRemaining()) - { - break; - } - putQuad(bb, quads[dir].get(i)); - } - - if (i >= quads[dir].size()) - { - quad = 0; - dir++; - dir = skipEmpty(dir); - } - else - { - quad = i; - } - } - }; - } - - public interface BufferFiller - { - boolean fill(LodVertexBuffer vbo); // If true: means more data is needed to be filled - } - - public BufferFiller makeBufferFiller(GpuUploadMethod method) - { - return new BufferFiller() - { - int dir = 0; - int quad = 0; - - public boolean fill(LodVertexBuffer vbo) - { - if (dir >= 6) - { - vbo.vertexCount = 0; - return false; - } - - int numOfQuads = _countRemainingQuads(); - if (numOfQuads > MAX_QUADS_PER_BUFFER) - numOfQuads = MAX_QUADS_PER_BUFFER; - if (numOfQuads == 0) - { - vbo.vertexCount = 0; - return false; - } - ByteBuffer bb = vbo.mapBuffer(numOfQuads * QUAD_BYTE_SIZE, method, MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE); - if (bb == null) - throw new NullPointerException("mapBuffer returned null"); - bb.clear(); - bb.limit(numOfQuads * QUAD_BYTE_SIZE); - while (bb.hasRemaining() && dir < 6) - { - writeData(bb); - } - bb.rewind(); - vbo.unmapBuffer(method); - vbo.vertexCount = numOfQuads * 6; - return dir < 6; - } - - private int _countRemainingQuads() - { - int a = quads[dir].size() - quad; - for (int i = dir + 1; i < quads.length; i++) - { - a += quads[i].size(); - } - return a; - } - - private void writeData(ByteBuffer bb) - { - int startQ = quad; - - int i = startQ; - for (i = startQ; i < quads[dir].size(); i++) - { - if (!bb.hasRemaining()) - { - break; - } - putQuad(bb, quads[dir].get(i)); - } - - if (i >= quads[dir].size()) - { - quad = 0; - dir++; - while (dir < 6 && quads[dir].isEmpty()) - dir++; - } - else - { - quad = i; - } - } - }; - } - - public int getCurrentQuadsCount() - { - int i = 0; - for (ArrayList qs : quads) - i += qs.size(); - return i; - } - - public int getCurrentNeededVertexBuffers() - { - return LodUtil.ceilDiv(getCurrentQuadsCount(), MAX_QUADS_PER_BUFFER); - } - - public static final int[][][] DIRECTION_VERTEX_QUAD = new int[][][] { - // X,Z - { // UP - { 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 - }, - // X,Y - { // NORTH - { 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 - }, - // Z,Y - { // WEST - { 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 - }, }; - -} diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/RenderBuffer.java b/src/main/java/com/seibel/lod/core/objects/opengl/RenderBuffer.java index 09d89206a..2651879d3 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/RenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/RenderBuffer.java @@ -21,6 +21,7 @@ package com.seibel.lod.core.objects.opengl; import java.util.ConcurrentModificationException; +import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; import com.seibel.lod.core.enums.config.GpuUploadMethod; import com.seibel.lod.core.render.LodRenderProgram; import com.seibel.lod.core.util.StatsMap; diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/RenderRegion.java b/src/main/java/com/seibel/lod/core/objects/opengl/RenderRegion.java index 6d4b29113..310816b8b 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/RenderRegion.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/RenderRegion.java @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicReference; import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.CubicLodTemplate; import com.seibel.lod.core.builders.lodBuilding.LodBuilder; +import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; import com.seibel.lod.core.enums.LodDirection; import com.seibel.lod.core.enums.config.GpuUploadMethod; import com.seibel.lod.core.enums.rendering.DebugMode; @@ -160,7 +161,7 @@ public class RenderRegion implements AutoCloseable private void recreateBuffer(LodQuadBuilder builder) { if (renderBufferBack != null) throw new RuntimeException("Assert Error"); - boolean useSimpleBuffer = (builder.getCurrentNeededVertexBuffers() <= 6) || true; + boolean useSimpleBuffer = (builder.getCurrentNeededVertexBufferCount() <= 6) || true; renderBufferBack = useSimpleBuffer ? new SimpleRenderBuffer() : null; //new ComplexRenderRegion(regPos); @@ -192,7 +193,7 @@ public class RenderRegion implements AutoCloseable int skyLightCullingBelow = CONFIG.client().graphics().advancedGraphics().getCaveCullingHeight(); // FIXME: Clamp also to the max world height. skyLightCullingBelow = Math.max(skyLightCullingBelow, LodBuilder.MIN_WORLD_HEIGHT); - LodQuadBuilder builder = new LodQuadBuilder(10, useSkylightCulling, skyLightCullingBelow); + LodQuadBuilder builder = new LodQuadBuilder(useSkylightCulling, skyLightCullingBelow); Runnable buildRun = ()->{ makeLodRenderData(builder, region, adjRegions, playerPosX, playerPosZ); }; 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 1f2d2353e..e845b3ac5 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,13 +23,14 @@ import java.nio.ByteBuffer; import java.util.Iterator; import java.util.concurrent.TimeUnit; +import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; import org.lwjgl.opengl.GL32; import com.seibel.lod.core.api.ApiShared; import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodBufferBuilderFactory; import com.seibel.lod.core.enums.config.GpuUploadMethod; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.objects.opengl.LodQuadBuilder.BufferFiller; +import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder.BufferFiller; import com.seibel.lod.core.render.GLProxy; import com.seibel.lod.core.render.LodRenderProgram; import com.seibel.lod.core.util.LodUtil; @@ -112,7 +113,7 @@ public class SimpleRenderBuffer extends RenderBuffer } private void _uploadBuffersDirect(LodQuadBuilder builder, GpuUploadMethod method) { - resize(builder.getCurrentNeededVertexBuffers()); + resize(builder.getCurrentNeededVertexBufferCount()); long remainingNS = 0; long BPerNS = CONFIG.client().advanced().buffers().getGpuUploadPerMegabyteInMilliseconds(); @@ -147,7 +148,7 @@ public class SimpleRenderBuffer extends RenderBuffer private void _uploadBuffersMapped(LodQuadBuilder builder, GpuUploadMethod method) { - resize(builder.getCurrentNeededVertexBuffers()); + resize(builder.getCurrentNeededVertexBufferCount()); for (int i=0; i