From e015632cec63749f3b5f43c48b26836c00695b65 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sat, 13 Jan 2024 15:28:06 +1000 Subject: [PATCH] Continued work --- .../cortex/voxelmon/core/DistanceTracker.java | 38 ++++++++++++++++--- .../me/cortex/voxelmon/core/VoxelCore.java | 3 +- .../rendering/AbstractFarWorldRenderer.java | 4 +- .../core/rendering/util/UploadStream.java | 7 +++- .../voxelmon/core/world/other/Mapper.java | 32 +++++++++++++--- 5 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java b/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java index c1fea825..a04a2c24 100644 --- a/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java +++ b/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java @@ -22,12 +22,12 @@ import net.minecraft.client.MinecraftClient; public class DistanceTracker { private final TransitionRing2D[] rings; private final RenderTracker tracker; - public DistanceTracker(RenderTracker tracker, int rings) { + private final int scale; + + public DistanceTracker(RenderTracker tracker, int rings, int scale) { this.rings = new TransitionRing2D[rings]; this.tracker = tracker; - - //NOTE: This is in our render distance units, to convert to chunks at lvl 0 multiply by 2 - int DIST = 16;//24; + this.scale = scale; this.rings[0] = new TransitionRing2D(5, (int) Math.ceil(MinecraftClient.getInstance().gameRenderer.getViewDistance()/16)/2, (x, z)->{ if (false) { @@ -42,9 +42,12 @@ public class DistanceTracker { } }); + //The rings 0+ start at 64 vanilla rd, no matter what the game is set at, that is if the game is set to 32 rd + // there will still be 32 chunks untill the first lod drop + // if the game is set to 16, then there will be 48 chunks until the drop for (int i = 1; i < rings; i++) { int capRing = i; - this.rings[i] = new TransitionRing2D(5+i, DIST, (x, z) -> this.dec(capRing, x, z), (x, z) -> this.inc(capRing, x, z)); + this.rings[i] = new TransitionRing2D(5+i, scale, (x, z) -> this.dec(capRing, x, z), (x, z) -> this.inc(capRing, x, z)); } } @@ -67,7 +70,7 @@ public class DistanceTracker { //if the center suddenly changes (say more than 1<<(7+lodlvl) block) then invalidate the entire ring and recompute // the lod sections public void setCenter(int x, int y, int z) { - for (var ring : rings) { + for (var ring : this.rings) { if (ring != null) { ring.update(x, z); } @@ -75,6 +78,16 @@ public class DistanceTracker { } public void init(int x, int z) { + //Radius of chunks to enqueue + int SIZE = 40; + //Insert highest LOD level + for (int ox = -SIZE; ox <= SIZE; ox++) { + for (int oz = -SIZE; oz <= SIZE; oz++) { + this.inc(4, (x>>(5+this.rings.length-1)) + ox, (z>>(5+this.rings.length-1)) + oz); + } + } + + for (int i = this.rings.length-1; 0 <= i; i--) { if (this.rings[i] != null) { this.rings[i].fill(x, z); @@ -214,6 +227,10 @@ public class DistanceTracker { } public void fill(int x, int z) { + this.fill(x, z, null); + } + + public void fill(int x, int z, Transition2DCallback outsideCallback) { int cx = x>>this.shiftSize; int cz = z>>this.shiftSize; @@ -223,6 +240,15 @@ public class DistanceTracker { for (int c = -b; c <= b; c++) { this.enter.callback(a + cx, c + cz); } + if (outsideCallback != null) { + for (int c = -this.radius; c < -b; c++) { + outsideCallback.callback(a + cx, c + cz); + } + + for (int c = b+1; c <= this.radius; c++) { + outsideCallback.callback(a + cx, c + cz); + } + } } this.currentX = cx; diff --git a/src/main/java/me/cortex/voxelmon/core/VoxelCore.java b/src/main/java/me/cortex/voxelmon/core/VoxelCore.java index 4787410e..5f4e08c6 100644 --- a/src/main/java/me/cortex/voxelmon/core/VoxelCore.java +++ b/src/main/java/me/cortex/voxelmon/core/VoxelCore.java @@ -80,7 +80,8 @@ public class VoxelCore { this.world.setRenderTracker(this.renderTracker); this.renderTracker.setRenderGen(this.renderGen); - this.distanceTracker = new DistanceTracker(this.renderTracker, 5); + //To get to chunk scale multiply the scale by 2, the scale is after how many chunks does the lods halve + this.distanceTracker = new DistanceTracker(this.renderTracker, 5, 16); this.postProcessing = new PostProcessing(); diff --git a/src/main/java/me/cortex/voxelmon/core/rendering/AbstractFarWorldRenderer.java b/src/main/java/me/cortex/voxelmon/core/rendering/AbstractFarWorldRenderer.java index e3b9b0bd..c60add4c 100644 --- a/src/main/java/me/cortex/voxelmon/core/rendering/AbstractFarWorldRenderer.java +++ b/src/main/java/me/cortex/voxelmon/core/rendering/AbstractFarWorldRenderer.java @@ -74,7 +74,6 @@ public abstract class AbstractFarWorldRenderer { //it shouldent matter if its called multiple times a frame however, as its synced with fences UploadStream.INSTANCE.tick(); - //Update the lightmap { long upload = UploadStream.INSTANCE.upload(this.lightDataBuffer, 0, 256*4); @@ -88,7 +87,9 @@ public abstract class AbstractFarWorldRenderer { } } + //Upload any new geometry this.geometry.uploadResults(); + //Upload any block state changes while (!this.stateUpdateQueue.isEmpty()) { var stateUpdate = this.stateUpdateQueue.pop(); @@ -98,6 +99,7 @@ public abstract class AbstractFarWorldRenderer { MemoryUtil.memPutInt(ptr, faceColour); ptr+=4; } } + //Upload any biome changes while (!this.biomeUpdateQueue.isEmpty()) { var biomeUpdate = this.biomeUpdateQueue.pop(); diff --git a/src/main/java/me/cortex/voxelmon/core/rendering/util/UploadStream.java b/src/main/java/me/cortex/voxelmon/core/rendering/util/UploadStream.java index 3a33d8cf..788d47b8 100644 --- a/src/main/java/me/cortex/voxelmon/core/rendering/util/UploadStream.java +++ b/src/main/java/me/cortex/voxelmon/core/rendering/util/UploadStream.java @@ -5,6 +5,7 @@ import me.cortex.voxelmon.core.gl.GlBuffer; import me.cortex.voxelmon.core.gl.GlFence; import me.cortex.voxelmon.core.gl.GlPersistentMappedBuffer; import me.cortex.voxelmon.core.util.AllocationArena; +import org.lwjgl.opengl.GL42; import java.util.ArrayDeque; import java.util.Deque; @@ -16,6 +17,7 @@ import static org.lwjgl.opengl.ARBMapBufferRange.*; import static org.lwjgl.opengl.GL11.glFinish; import static org.lwjgl.opengl.GL42.glMemoryBarrier; import static org.lwjgl.opengl.GL42C.GL_BUFFER_UPDATE_BARRIER_BIT; +import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT; import static org.lwjgl.opengl.GL44.GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT; public class UploadStream { @@ -81,14 +83,15 @@ public class UploadStream { } this.flushList.clear(); } - glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); + glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); + //Execute all the copies for (var entry : this.uploadList) { glCopyNamedBufferSubData(this.uploadBuffer.id, entry.target.id, entry.uploadOffset, entry.targetOffset, entry.size); } this.uploadList.clear(); - glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); this.caddr = -1; this.offset = 0; diff --git a/src/main/java/me/cortex/voxelmon/core/world/other/Mapper.java b/src/main/java/me/cortex/voxelmon/core/world/other/Mapper.java index c342cd20..a3ab39b4 100644 --- a/src/main/java/me/cortex/voxelmon/core/world/other/Mapper.java +++ b/src/main/java/me/cortex/voxelmon/core/world/other/Mapper.java @@ -13,6 +13,7 @@ import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtTagSizeTracker; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.stat.Stat; +import net.minecraft.util.Pair; import net.minecraft.world.biome.Biome; import org.lwjgl.system.MemoryUtil; @@ -32,8 +33,8 @@ public class Mapper { private static final int BIOME_TYPE = 2; private final StorageBackend storage; - public static final int UNKNOWN_MAPPING = -1; - public static final int AIR = 0; + public static final long UNKNOWN_MAPPING = -1; + public static final long AIR = 0; private final Map block2stateEntry = new ConcurrentHashMap<>(2000,0.75f, 10); private final ObjectArrayList blockId2stateEntry = new ObjectArrayList<>(); @@ -62,6 +63,11 @@ public class Mapper { return ((id>>27)&((1<<20)-1)) == 0; } + public static boolean shouldRenderFace(int dirId, long self, long other) { + //TODO: fixme make it be with respect to the type itself e.g. water, glass etc + return isTranslucent(other); + } + public void setCallbacks(Consumer stateCallback, Consumer biomeCallback) { this.newStateCallback = stateCallback; this.newBiomeCallback = biomeCallback; @@ -71,15 +77,17 @@ public class Mapper { var mappings = this.storage.getIdMappings(); List sentries = new ArrayList<>(); List bentries = new ArrayList<>(); + List> sentryErrors = new ArrayList<>(); + for (var entry : mappings.int2ObjectEntrySet()) { int entryType = entry.getIntKey()>>>30; int id = entry.getIntKey() & ((1<<30)-1); if (entryType == BLOCK_STATE_TYPE) { var sentry = StateEntry.deserialize(id, entry.getValue()); if (sentry.state.isAir()) { - System.err.println("Deserialization had air, probably corrupt, Inserting garbage type"); - sentry = new StateEntry(id, Block.STATE_IDS.get(new Random().nextInt(Block.STATE_IDS.size()-1))); - //TODO THIS + System.err.println("Deserialization was air, removed block"); + sentryErrors.add(new Pair<>(entry.getValue(), id)); + continue; } sentries.add(sentry); var oldEntry = this.block2stateEntry.put(sentry.state, sentry); @@ -97,6 +105,20 @@ public class Mapper { } } + { + //Insert garbage types into the mapping for those blocks, TODO:FIXME: Need to upgrade the type or have a solution to error blocks + var rand = new Random(); + for (var error : sentryErrors) { + while (true) { + var state = new StateEntry(error.getRight(), Block.STATE_IDS.get(rand.nextInt(Block.STATE_IDS.size() - 1))); + if (this.block2stateEntry.put(state.state, state) == null) { + sentries.add(state); + break; + } + } + } + } + //Insert into the arrays sentries.stream().sorted(Comparator.comparing(a->a.id)).forEach(entry -> { if (this.blockId2stateEntry.size() != entry.id) {