diff --git a/src/main/java/rs117/hd/utils/Zone.java b/src/main/java/rs117/hd/renderer/Zone.java similarity index 87% rename from src/main/java/rs117/hd/utils/Zone.java rename to src/main/java/rs117/hd/renderer/Zone.java index 80b680093c..2a55ca5a91 100644 --- a/src/main/java/rs117/hd/utils/Zone.java +++ b/src/main/java/rs117/hd/renderer/Zone.java @@ -1,4 +1,4 @@ -package rs117.hd.utils; +package rs117.hd.renderer; import java.nio.IntBuffer; @@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.*; import org.lwjgl.BufferUtils; +import rs117.hd.utils.buffer.GLVBO; import static org.lwjgl.opengl.GL30C.GL_ARRAY_BUFFER; import static org.lwjgl.opengl.GL30C.GL_INT; @@ -30,53 +31,46 @@ @Slf4j @RequiredArgsConstructor -class Zone +public class Zone { - private static final int MAX_VERTEX_COUNT = 6500; - private static final int MAX_DIAMETER = 6000; - private static final int ZSORT_GROUP_SIZE = 1024; // was 512 - - static final int[] distances; - static final char[] distanceFaceCount; - static final char[][] distanceToFaces; - - static - { - distances = new int[MAX_VERTEX_COUNT]; - distanceFaceCount = new char[MAX_DIAMETER]; - distanceToFaces = new char[MAX_DIAMETER][ZSORT_GROUP_SIZE]; - } + public static final int MAX_VERTEX_COUNT = 6500; + public static final int MAX_DIAMETER = 6000; + public static final int ZSORT_GROUP_SIZE = 1024; // was 512 // Zone vertex format + // TODO: Our Zone Format will be different for sure // index 0: -FLOAT.MAX_VALUE (non-array) // index 1: short vec3(x, y, z) // index 2: int abhsl // index 3: short vec4(id, x, y, z) - static final int VERT_SIZE = 20; + public static final int VERT_SIZE = 20; + + private static final char[] distanceFaceCount = new char[MAX_DIAMETER]; + private static final char[][] distanceToFaces = new char[MAX_DIAMETER][ZSORT_GROUP_SIZE]; - int glVao; - int bufLen; + private int glVao; + private int bufLen; - int glVaoA; - int bufLenA; + private int glVaoA; + private int bufLenA; - int sizeO, sizeA; - GLVBO vboO, vboA; + private int sizeO, sizeA; + private GLVBO vboO, vboA; - boolean initialized; // whether the zone vao and vbos are ready - boolean cull; // whether the zone is queued for deletion - boolean dirty; // whether the zone has temporary modifications - boolean invalidate; // whether the zone needs rebuilding + private boolean initialized; // whether the zone vao and vbos are ready + private boolean cull; // whether the zone is queued for deletion + private boolean dirty; // whether the zone has temporary modifications + private boolean invalidate; // whether the zone needs rebuilding - int[] levelOffsets = new int[4]; // buffer pos in ints for the end of the level + private int[] levelOffsets = new int[4]; // buffer pos in ints for the end of the level - int[][] rids; - int[][] roofStart; - int[][] roofEnd; + private int[][] rids; + private int[][] roofStart; + private int[][] roofEnd; - final List alphaModels = new ArrayList<>(0); + private final List alphaModels = new ArrayList<>(0); - void init(GLVBO o, GLVBO a) + public void init(GLVBO o, GLVBO a) { assert glVao == 0; assert glVaoA == 0; @@ -85,18 +79,18 @@ void init(GLVBO o, GLVBO a) { vboO = o; glVao = glGenVertexArrays(); - setupVao(glVao, o.bufId); + setupVao(glVao, o.id); } if (a != null) { vboA = a; glVaoA = glGenVertexArrays(); - setupVao(glVaoA, a.bufId); + setupVao(glVaoA, a.id); } } - void free() + public void destroy() { if (vboO != null) { @@ -127,7 +121,7 @@ void free() alphaModels.clear(); } - void unmap() + public void unmap() { if (vboO != null) { @@ -169,7 +163,7 @@ private void setupVao(int vao, int buffer) glBindBuffer(GL_ARRAY_BUFFER, 0); } - void updateRoofs(Map updates) + public void updateRoofs(Map updates) { for (int level = 0; level < 4; ++level) { @@ -208,7 +202,7 @@ private void convertForDraw(int vertSize) glDrawLength = Arrays.copyOfRange(drawEnd, 0, drawIdx); } - void renderOpaque(int zx, int zz, int minLevel, int currentLevel, int maxLevel, Set hiddenRoofIds) + public void renderOpaque(int zx, int zz, int minLevel, int currentLevel, int maxLevel, Set hiddenRoofIds) { drawIdx = 0; @@ -284,7 +278,7 @@ else if (drawIdx >= NUM_DRAW_RANGES) } } - static class AlphaModel + private static class AlphaModel { int id; int startpos, endpos; @@ -309,9 +303,9 @@ boolean isTemp() } } - static final Queue modelCache = new ArrayDeque<>(); + private static final Queue modelCache = new ArrayDeque<>(); - void addAlphaModel(int vao, Model model, int startpos, int endpos, int x, int y, int z, int lx, int lz, int ux, int uz, int rid, int level, int id) + public void addAlphaModel(int vao, Model model, int startpos, int endpos, int x, int y, int z, int lx, int lz, int ux, int uz, int rid, int level, int id) { AlphaModel m = new AlphaModel(); m.id = id; @@ -415,7 +409,7 @@ void addAlphaModel(int vao, Model model, int startpos, int endpos, int x, int y, alphaModels.add(m); } - void addTempAlphaModel(int vao, int startpos, int endpos, int level, int x, int y, int z) + public void addTempAlphaModel(int vao, int startpos, int endpos, int level, int x, int y, int z) { AlphaModel m = modelCache.poll(); if (m == null) @@ -437,7 +431,7 @@ void addTempAlphaModel(int vao, int startpos, int endpos, int level, int x, int alphaModels.add(m); } - void removeTemp() + public void removeTemp() { for (int i = alphaModels.size() - 1; i >= 0; --i) { @@ -463,7 +457,7 @@ void removeTemp() private static int lastVao; private static int lastzx, lastzz; - void alphaSort(int zx, int zz, int cx, int cy, int cz) + public void alphaSort(int zx, int zz, int cx, int cy, int cz) { alphaModels.sort(Comparator.comparingInt((AlphaModel m) -> { @@ -478,7 +472,7 @@ void alphaSort(int zx, int zz, int cx, int cy, int cz) ); } - void renderAlpha(int zx, int zz, int cyaw, int cpitch, int minLevel, int currentLevel, int maxLevel, int level, Set hiddenRoofIds) + public void renderAlpha(int zx, int zz, int cyaw, int cpitch, int minLevel, int currentLevel, int maxLevel, int level, Set hiddenRoofIds) { drawIdx = 0; alphaElements.clear(); @@ -597,7 +591,7 @@ private void flush() // TODO: Figure out drawing, since we can't exactly follow 1-1 how gpue works } - void multizoneLocs(Scene scene, int zx, int zz, int cx, int cz, Zone[][] zones) + public void multizoneLocs(Scene scene, int zx, int zz, int cx, int cz, Zone[][] zones) { int offset = scene.getWorldViewId() == -1 ? SCENE_OFFSET >> 3 : 0; for (AlphaModel m : alphaModels) diff --git a/src/main/java/rs117/hd/renderer/ZoneCluster.java b/src/main/java/rs117/hd/renderer/ZoneCluster.java new file mode 100644 index 0000000000..fe5d63082c --- /dev/null +++ b/src/main/java/rs117/hd/renderer/ZoneCluster.java @@ -0,0 +1,41 @@ +package rs117.hd.renderer; + +import rs117.hd.utils.buffer.GLVAOList; + +public class ZoneCluster { + public final int sizeX, sizeZ; + public Zone[][] zones; + public GLVAOList vaoO, vaoA; + public GLVAOList vaoPO; + + public ZoneCluster(int sizeX, int sizeZ) + { + this.sizeX = sizeX; + this.sizeZ = sizeZ; + zones = new Zone[sizeX][sizeZ]; + for (int x = 0; x < sizeX; ++x) + { + for (int z = 0; z < sizeZ; ++z) + { + zones[x][z] = new Zone(); + } + } + vaoO = new GLVAOList(); + vaoA = new GLVAOList(); + vaoPO = new GLVAOList(); + } + + public void destroy() + { + for (int x = 0; x < sizeX; ++x) + { + for (int z = 0; z < sizeZ; ++z) + { + zones[x][z].destroy(); + } + } + vaoO.destroy(); + vaoA.destroy(); + vaoPO.destroy(); + } +} diff --git a/src/main/java/rs117/hd/utils/GLVAO.java b/src/main/java/rs117/hd/utils/buffer/GLVAO.java similarity index 54% rename from src/main/java/rs117/hd/utils/GLVAO.java rename to src/main/java/rs117/hd/utils/buffer/GLVAO.java index f536832902..a5d5cf8bb5 100644 --- a/src/main/java/rs117/hd/utils/GLVAO.java +++ b/src/main/java/rs117/hd/utils/buffer/GLVAO.java @@ -1,8 +1,4 @@ -package rs117.hd.utils; - -import java.util.ArrayList; -import java.util.List; -import lombok.extern.slf4j.Slf4j; +package rs117.hd.utils.buffer; import static org.lwjgl.opengl.GL11C.GL_FLOAT; import static org.lwjgl.opengl.GL11C.GL_INT; @@ -17,7 +13,7 @@ import static org.lwjgl.opengl.GL30C.glVertexAttribI3i; import static org.lwjgl.opengl.GL30C.glVertexAttribIPointer; -class GLVAO +public class GLVAO { // Temporary vertex format // index 0: vec3(x, y, z) @@ -29,18 +25,18 @@ class GLVAO final GLVBO vbo; int vao; - GLVAO(int size) + GLVAO(String name) { - vbo = new GLVBO(size); + vbo = new GLVBO(name); } - void init() + public void initialize(int size) { vao = glGenVertexArrays(); glBindVertexArray(vao); - vbo.init(); - glBindBuffer(GL_ARRAY_BUFFER, vbo.bufId); + vbo.initialize(size); + glBindBuffer(GL_ARRAY_BUFFER, vbo.id); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, false, VERT_SIZE, 0); @@ -63,69 +59,4 @@ void destroy() glDeleteVertexArrays(vao); vao = 0; } -} - -@Slf4j -class GLVAOList -{ - // this needs to be larger than the largest single model - // private static final int VAO_SIZE = 16 * 1024 * 1024; - private static final int VAO_SIZE = 1024 * 1024; - - private int curIdx; - private final List vaos = new ArrayList<>(); - - GLVAO get(int size) - { - assert size <= VAO_SIZE; - - while (curIdx < vaos.size()) - { - GLVAO vao = vaos.get(curIdx); - if (!vao.vbo.mapped) - { - vao.vbo.map(); - } - - int rem = vao.vbo.vb.remaining() * Integer.BYTES; - if (size <= rem) - { - return vao; - } - - curIdx++; - } - - GLVAO vao = new GLVAO(VAO_SIZE); - vao.init(); - vao.vbo.map(); - vaos.add(vao); - log.trace("Allocated VAO {}", vao.vao); - return vao; - } - - List unmap() - { - int sz = 0; - for (GLVAO vao : vaos) - { - if (vao.vbo.mapped) - { - ++sz; - vao.vbo.unmap(); - } - } - curIdx = 0; - return vaos.subList(0, sz); - } - - void free() - { - for (GLVAO vao : vaos) - { - vao.destroy(); - } - vaos.clear(); - curIdx = 0; - } -} +} \ No newline at end of file diff --git a/src/main/java/rs117/hd/utils/buffer/GLVAOList.java b/src/main/java/rs117/hd/utils/buffer/GLVAOList.java new file mode 100644 index 0000000000..3ac0c4450a --- /dev/null +++ b/src/main/java/rs117/hd/utils/buffer/GLVAOList.java @@ -0,0 +1,70 @@ +package rs117.hd.utils.buffer; + +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GLVAOList +{ + // this needs to be larger than the largest single model + // private static final int VAO_SIZE = 16 * 1024 * 1024; + private static final int VAO_SIZE = 1024 * 1024; + + private int curIdx; + private final List vaos = new ArrayList<>(); + + public GLVAO get(int size) + { + assert size <= VAO_SIZE; + + while (curIdx < vaos.size()) + { + GLVAO vao = vaos.get(curIdx); + if (!vao.vbo.mapped) + { + vao.vbo.map(); + } + + int rem = vao.vbo.vb.remaining() * Integer.BYTES; + if (size <= rem) + { + return vao; + } + + curIdx++; + } + + GLVAO vao = new GLVAO(""); + vao.initialize(VAO_SIZE); + vao.vbo.map(); + vaos.add(vao); + log.trace("Allocated VAO {}", vao.vao); + return vao; + } + + public List unmap() + { + int sz = 0; + for (GLVAO vao : vaos) + { + if (vao.vbo.mapped) + { + ++sz; + vao.vbo.unmap(); + } + } + curIdx = 0; + return vaos.subList(0, sz); + } + + public void destroy() + { + for (GLVAO vao : vaos) + { + vao.destroy(); + } + vaos.clear(); + curIdx = 0; + } +} \ No newline at end of file diff --git a/src/main/java/rs117/hd/utils/GLVBO.java b/src/main/java/rs117/hd/utils/buffer/GLVBO.java similarity index 57% rename from src/main/java/rs117/hd/utils/GLVBO.java rename to src/main/java/rs117/hd/utils/buffer/GLVBO.java index ac54c04d6f..e45115a2fd 100644 --- a/src/main/java/rs117/hd/utils/GLVBO.java +++ b/src/main/java/rs117/hd/utils/buffer/GLVBO.java @@ -1,4 +1,4 @@ -package rs117.hd.utils; +package rs117.hd.utils.buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; @@ -6,71 +6,56 @@ import static org.lwjgl.opengl.GL15C.GL_ARRAY_BUFFER; import static org.lwjgl.opengl.GL15C.GL_DYNAMIC_DRAW; import static org.lwjgl.opengl.GL15C.glBindBuffer; -import static org.lwjgl.opengl.GL15C.glBufferData; -import static org.lwjgl.opengl.GL15C.glDeleteBuffers; -import static org.lwjgl.opengl.GL15C.glGenBuffers; import static org.lwjgl.opengl.GL15C.glUnmapBuffer; import static org.lwjgl.opengl.GL30C.GL_MAP_INVALIDATE_BUFFER_BIT; import static org.lwjgl.opengl.GL30C.GL_MAP_UNSYNCHRONIZED_BIT; import static org.lwjgl.opengl.GL30C.GL_MAP_WRITE_BIT; import static org.lwjgl.opengl.GL30C.glMapBufferRange; -public class GLVBO { - final int size; - int bufId; // TODO: We should make this inherit from GLBuffer +public class GLVBO extends GLBuffer { private ByteBuffer buffer; - IntBuffer vb; - int len; - boolean mapped; + public IntBuffer vb; + public int len; + public boolean mapped; - GLVBO(int size) + public GLVBO(String name) { - this.size = size; + super(name, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW); } - void init() - { - bufId = glGenBuffers(); - - glBindBuffer(GL_ARRAY_BUFFER, bufId); - glBufferData(GL_ARRAY_BUFFER, size, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - - void destroy() + public void destroy() { if (mapped) { - glBindBuffer(GL_ARRAY_BUFFER, bufId); + glBindBuffer(GL_ARRAY_BUFFER, id); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); mapped = false; } - glDeleteBuffers(bufId); - bufId = 0; + super.destroy(); } - void map() + public void map() { assert !mapped; - glBindBuffer(GL_ARRAY_BUFFER, bufId); + glBindBuffer(GL_ARRAY_BUFFER, id); buffer = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT, buffer); if (buffer == null) { - throw new RuntimeException("unable to map GL buffer " + bufId + " size " + size); + throw new RuntimeException("unable to map GL buffer " + id + " size " + size); } this.vb = buffer.asIntBuffer(); glBindBuffer(GL_ARRAY_BUFFER, 0); mapped = true; } - void unmap() + public void unmap() { assert mapped; len = vb.position(); vb = null; - glBindBuffer(GL_ARRAY_BUFFER, bufId); + glBindBuffer(GL_ARRAY_BUFFER, id); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); mapped = false;