Continued work

This commit is contained in:
mcrcortex
2024-01-13 15:28:06 +10:00
parent 79cfe99e8d
commit e015632cec
5 changed files with 69 additions and 15 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -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;

View File

@@ -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<BlockState, StateEntry> block2stateEntry = new ConcurrentHashMap<>(2000,0.75f, 10);
private final ObjectArrayList<StateEntry> 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<StateEntry> stateCallback, Consumer<BiomeEntry> biomeCallback) {
this.newStateCallback = stateCallback;
this.newBiomeCallback = biomeCallback;
@@ -71,15 +77,17 @@ public class Mapper {
var mappings = this.storage.getIdMappings();
List<StateEntry> sentries = new ArrayList<>();
List<BiomeEntry> bentries = new ArrayList<>();
List<Pair<byte[], Integer>> 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) {