more jank

This commit is contained in:
mcrcortex
2025-05-02 23:08:28 +10:00
parent e82d2a875c
commit 7c4a3fe7b4

View File

@@ -2,6 +2,7 @@ package me.cortex.voxy.client.core.rendering;
import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import me.cortex.voxy.client.core.gl.GlBuffer; import me.cortex.voxy.client.core.gl.GlBuffer;
import me.cortex.voxy.client.core.gl.GlFramebuffer; import me.cortex.voxy.client.core.gl.GlFramebuffer;
import me.cortex.voxy.client.core.gl.GlTexture; import me.cortex.voxy.client.core.gl.GlTexture;
@@ -45,23 +46,31 @@ public class ChunkBoundRenderer {
private GlTexture depthBuffer = new GlTexture().store(GL_DEPTH_COMPONENT24, 1, 128, 128); private GlTexture depthBuffer = new GlTexture().store(GL_DEPTH_COMPONENT24, 1, 128, 128);
private final GlFramebuffer frameBuffer = new GlFramebuffer().bind(GL_DEPTH_ATTACHMENT, this.depthBuffer).verify(); private final GlFramebuffer frameBuffer = new GlFramebuffer().bind(GL_DEPTH_ATTACHMENT, this.depthBuffer).verify();
private final Long2ByteOpenHashMap updates = new Long2ByteOpenHashMap(); private final LongOpenHashSet addQueue = new LongOpenHashSet();
private final LongOpenHashSet remQueue = new LongOpenHashSet();
public ChunkBoundRenderer() { public ChunkBoundRenderer() {
this.chunk2idx.defaultReturnValue(-1); this.chunk2idx.defaultReturnValue(-1);
} }
public void addSection(long pos) { public void addSection(long pos) {
this.updates.addTo(pos, (byte) 1); this.addQueue.add(pos);
this.remQueue.remove(pos);
} }
public void removeSection(long pos) { public void removeSection(long pos) {
this.updates.addTo(pos, (byte) -1); this.remQueue.add(pos);
this.addQueue.remove(pos);
} }
//Bind and render, changing as little gl state as possible so that the caller may configure how it wants to render //Bind and render, changing as little gl state as possible so that the caller may configure how it wants to render
public void render(Viewport<?> viewport) { public void render(Viewport<?> viewport) {
if (this.chunk2idx.isEmpty() && this.updates.isEmpty()) return; if (!this.remQueue.isEmpty()) {
this.remQueue.forEach(this::_remPos);
this.remQueue.clear();
}
if (this.chunk2idx.isEmpty() && this.addQueue.isEmpty()) return;
if (this.depthBuffer.getWidth() != viewport.width || this.depthBuffer.getHeight() != viewport.height) { if (this.depthBuffer.getWidth() != viewport.width || this.depthBuffer.getHeight() != viewport.height) {
this.depthBuffer.free(); this.depthBuffer.free();
@@ -121,37 +130,23 @@ public class ChunkBoundRenderer {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
this.processUpdates();
if (!this.addQueue.isEmpty()) {
this.addQueue.forEach(this::_addPos);
this.addQueue.clear();
}
} }
private void processUpdates() { private void _remPos(long pos) {
if (this.updates.isEmpty()) return;
var iter = this.updates.long2ByteEntrySet().fastIterator();
while (iter.hasNext()) {
var entry = iter.next();
if (entry.getByteValue()==0) continue;
long pos = entry.getLongKey();
if (0<entry.getByteValue()) {
if (this.chunk2idx.containsKey(pos)) {
//Logger.warn("Chunk already in map: " + new ChunkPos(pos));
continue;
}
this.ensureSize1();//Resize if needed
int idx = this.chunk2idx.size();
this.chunk2idx.put(pos, idx);
this.idx2chunk[idx] = pos;
this.put(idx, pos);
} else {
int idx = this.chunk2idx.remove(pos); int idx = this.chunk2idx.remove(pos);
if (idx == -1) { if (idx == -1) {
//Logger.warn("Chunk not in map: " + new ChunkPos(pos)); Logger.warn("Chunk not in map: " + pos);
continue; return;
} }
if (idx == this.chunk2idx.size()) { if (idx == this.chunk2idx.size()) {
//Dont need to do anything as heap is already compact //Dont need to do anything as heap is already compact
continue; return;
} }
if (this.idx2chunk[idx] != pos) { if (this.idx2chunk[idx] != pos) {
throw new IllegalStateException(); throw new IllegalStateException();
@@ -167,8 +162,19 @@ public class ChunkBoundRenderer {
//Put the end pos into the new idx //Put the end pos into the new idx
this.put(idx, ePos); this.put(idx, ePos);
} }
private void _addPos(long pos) {
if (this.chunk2idx.containsKey(pos)) {
Logger.warn("Chunk already in map: " + pos);
return;
} }
this.updates.clear(); this.ensureSize1();//Resize if needed
int idx = this.chunk2idx.size();
this.chunk2idx.put(pos, idx);
this.idx2chunk[idx] = pos;
this.put(idx, pos);
} }
private void ensureSize1() { private void ensureSize1() {