Added hud debug entry, added support for tinting in dark dimensions, attempted to add/fix auto updating block data from older versions (wip)

This commit is contained in:
mcrcortex
2025-10-02 18:01:37 +10:00
parent da5d7bc95e
commit 83eea856e1
10 changed files with 114 additions and 45 deletions

View File

@@ -117,7 +117,7 @@ dependencies {
//modRuntimeOnlyMsk("maven.modrinth:modmenu:15.0.0") //modRuntimeOnlyMsk("maven.modrinth:modmenu:15.0.0")
modCompileOnly("maven.modrinth:iris:1.9.3+1.21.9-fabric") modCompileOnly("maven.modrinth:iris:1.9.3+1.21.9-fabric")
modRuntimeOnlyMsk("maven.modrinth:iris:1.9.3+1.21.9-fabric") //modRuntimeOnlyMsk("maven.modrinth:iris:1.9.3+1.21.9-fabric")
//modCompileOnly("maven.modrinth:starlight:1.1.3+1.20.4") //modCompileOnly("maven.modrinth:starlight:1.1.3+1.20.4")

View File

@@ -8,6 +8,8 @@ import me.cortex.voxy.commonImpl.VoxyCommon;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.gui.hud.debug.DebugHudEntries;
import net.minecraft.util.Identifier;
import java.util.HashSet; import java.util.HashSet;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -16,7 +18,6 @@ import java.util.function.Function;
public class VoxyClient implements ClientModInitializer { public class VoxyClient implements ClientModInitializer {
private static final HashSet<String> FREX = new HashSet<>(); private static final HashSet<String> FREX = new HashSet<>();
public static void initVoxyClient() { public static void initVoxyClient() {
Capabilities.init();//Ensure clinit is called Capabilities.init();//Ensure clinit is called
@@ -39,6 +40,7 @@ public class VoxyClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
DebugHudEntries.register(Identifier.of("voxy","debug"), new VoxyDebugScreenEntry());
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> { ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
if (VoxyCommon.isAvailable()) { if (VoxyCommon.isAvailable()) {
dispatcher.register(VoxyCommands.register()); dispatcher.register(VoxyCommands.register());

View File

@@ -0,0 +1,51 @@
package me.cortex.voxy.client;
import me.cortex.voxy.client.core.IGetVoxyRenderSystem;
import me.cortex.voxy.client.core.VoxyRenderSystem;
import me.cortex.voxy.commonImpl.VoxyCommon;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.debug.DebugHudEntry;
import net.minecraft.client.gui.hud.debug.DebugHudLines;
import net.minecraft.util.Colors;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import net.minecraft.world.chunk.WorldChunk;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class VoxyDebugScreenEntry implements DebugHudEntry {
@Override
public void render(DebugHudLines lines, @Nullable World world, @Nullable WorldChunk clientChunk, @Nullable WorldChunk chunk) {
if (!VoxyCommon.isAvailable()) {
lines.addLine(Formatting.RED + "voxy-"+VoxyCommon.MOD_VERSION);//Voxy installed, not avalible
return;
}
var instance = VoxyCommon.getInstance();
if (instance == null) {
lines.addLine(Formatting.YELLOW + "voxy-" + VoxyCommon.MOD_VERSION);//Voxy avalible, no instance active
return;
}
VoxyRenderSystem vrs = null;
var wr = MinecraftClient.getInstance().worldRenderer;
if (wr != null) vrs = ((IGetVoxyRenderSystem) wr).getVoxyRenderSystem();
//Voxy instance active
lines.addLine((vrs==null?Formatting.DARK_GREEN:Formatting.GREEN)+"voxy-"+VoxyCommon.MOD_VERSION);
//lines.addLineToSection();
List<String> instanceLines = new ArrayList<>();
instance.addDebug(instanceLines);
lines.addLinesToSection(Identifier.of("voxy", "instance_debug"), instanceLines);
if (vrs != null) {
List<String> renderLines = new ArrayList<>();
vrs.addDebugInfo(renderLines);
lines.addLinesToSection(Identifier.of("voxy", "render_debug"), renderLines);
}
}
}

View File

@@ -148,6 +148,12 @@ public class VoxyRenderSystem {
for (int i = 0; i < oldBufferBindings.length; i++) { for (int i = 0; i < oldBufferBindings.length; i++) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, oldBufferBindings[i]); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, oldBufferBindings[i]);
} }
for (int i = 0; i < 12; i++) {
GlStateManager._activeTexture(GlConst.GL_TEXTURE0+i);
GlStateManager._bindTexture(0);
glBindSampler(i, 0);
}
} }

View File

@@ -17,6 +17,7 @@ import me.cortex.voxy.client.core.rendering.util.SharedIndexBuffer;
import me.cortex.voxy.client.core.rendering.util.UploadStream; import me.cortex.voxy.client.core.rendering.util.UploadStream;
import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.world.WorldEngine; import me.cortex.voxy.common.world.WorldEngine;
import net.minecraft.client.MinecraftClient;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
@@ -102,6 +103,9 @@ public class MDICSectionRenderer extends AbstractSectionRenderer<MDICViewport, B
var builder = Shader.make() var builder = Shader.make()
.defineIf("TAA_PATCH", taa != null) .defineIf("TAA_PATCH", taa != null)
.defineIf("DEBUG_RENDER", false) .defineIf("DEBUG_RENDER", false)
.defineIf("DARKENED_TINTING", MinecraftClient.getInstance().world.getDimensionEffects().isDarkened())//TODO: FIXME: this is really jank atm
.addSource(ShaderType.VERTEX, vertex); .addSource(ShaderType.VERTEX, vertex);
String frag = ShaderLoader.parse("voxy:lod/gl46/quads.frag"); String frag = ShaderLoader.parse("voxy:lod/gl46/quads.frag");

View File

@@ -1,32 +0,0 @@
package me.cortex.voxy.client.mixin.minecraft;
import me.cortex.voxy.client.core.IGetVoxyRenderSystem;
import me.cortex.voxy.commonImpl.VoxyCommon;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugHud.class)
public class MixinDebugHud {
//TODO: Fix this
/*
@Inject(method = "getRightText", at = @At("RETURN"))
private void injectDebug(CallbackInfoReturnable<List<String>> cir) {
var ret = cir.getReturnValue();
var instance = VoxyCommon.getInstance();
if (instance != null) {
ret.add("");
ret.add("");
instance.addDebug(ret);
}
var renderer = ((IGetVoxyRenderSystem) MinecraftClient.getInstance().worldRenderer).getVoxyRenderSystem();
if (renderer != null) {
renderer.addDebugInfo(ret);
}
}*/
}

View File

@@ -1,12 +1,16 @@
package me.cortex.voxy.common.world.other; package me.cortex.voxy.common.world.other;
import com.mojang.serialization.Dynamic;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.config.IMappingStorage; import me.cortex.voxy.common.config.IMappingStorage;
import net.minecraft.SharedConstants;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock; import net.minecraft.block.LeavesBlock;
import net.minecraft.datafixer.Schemas;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
@@ -95,26 +99,31 @@ public class Mapper {
} }
private void loadFromStorage() { private void loadFromStorage() {
//TODO: FIXME: have/store the minecraft version the mappings are from (the data version)
// SharedConstants.getGameVersion().dataVersion().id()
// then use this to create an update path instead
var mappings = this.storage.getIdMappingsData(); var mappings = this.storage.getIdMappingsData();
List<StateEntry> sentries = new ArrayList<>(); List<StateEntry> sentries = new ArrayList<>();
List<BiomeEntry> bentries = new ArrayList<>(); List<BiomeEntry> bentries = new ArrayList<>();
List<Pair<byte[], Integer>> sentryErrors = new ArrayList<>(); List<Pair<byte[], Integer>> sentryErrors = new ArrayList<>();
boolean[] forceResave = new boolean[1];
for (var entry : mappings.int2ObjectEntrySet()) { for (var entry : mappings.int2ObjectEntrySet()) {
int entryType = entry.getIntKey()>>>30; int entryType = entry.getIntKey()>>>30;
int id = entry.getIntKey() & ((1<<30)-1); int id = entry.getIntKey() & ((1<<30)-1);
if (entryType == BLOCK_STATE_TYPE) { if (entryType == BLOCK_STATE_TYPE) {
var sentry = StateEntry.deserialize(id, entry.getValue()); var sentry = StateEntry.deserialize(id, entry.getValue(), forceResave);
if (sentry.state.isAir()) { if (sentry.state.isAir()) {
Logger.error("Deserialization was air, removed block"); Logger.error("Deserialization was air, removed block");
sentryErrors.add(new Pair<>(entry.getValue(), id)); sentryErrors.add(new Pair<>(entry.getValue(), id));
continue; continue;
} }
sentries.add(sentry); sentries.add(sentry);
var oldEntry = this.block2stateEntry.put(sentry.state, sentry); var oldEntry = this.block2stateEntry.putIfAbsent(sentry.state, sentry);
if (oldEntry != null) { if (oldEntry != null) {
throw new IllegalStateException("Multiple mappings for blockstate"); //forceResave[0] |= true;
Logger.warn("Multiple mappings for blockstate, using old state, expect things to possibly go really badly. " + oldEntry.id + ":" + sentry.id + ":" + sentry.state );
} }
} else if (entryType == BIOME_TYPE) { } else if (entryType == BIOME_TYPE) {
var bentry = BiomeEntry.deserialize(id, entry.getValue()); var bentry = BiomeEntry.deserialize(id, entry.getValue());
@@ -127,7 +136,8 @@ public class Mapper {
} }
} }
{ if (!sentryErrors.isEmpty()) {
forceResave[0] |= true;
//Insert garbage types into the mapping for those blocks, TODO:FIXME: Need to upgrade the type or have a solution to error blocks //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(); var rand = new Random();
for (var error : sentryErrors) { for (var error : sentryErrors) {
@@ -156,6 +166,10 @@ public class Mapper {
this.biomeId2biomeEntry.add(entry); this.biomeId2biomeEntry.add(entry);
}); });
if (forceResave[0]) {
Logger.warn("Forced state resave triggered");
this.forceResaveStates();
}
} }
public final int getBlockStateCount() { public final int getBlockStateCount() {
@@ -357,16 +371,26 @@ public class Mapper {
} }
} }
public static StateEntry deserialize(int id, byte[] data) { public static StateEntry deserialize(int id, byte[] data, boolean[] forceResave) {
try { try {
var compound = NbtIo.readCompressed(new ByteArrayInputStream(data), NbtSizeTracker.ofUnlimitedBytes()); var compound = NbtIo.readCompressed(new ByteArrayInputStream(data), NbtSizeTracker.ofUnlimitedBytes());
if (compound.getInt("id", -1) != id) { if (compound.getInt("id", -1) != id) {
throw new IllegalStateException("Encoded id != expected id"); throw new IllegalStateException("Encoded id != expected id");
} }
var state = BlockState.CODEC.parse(NbtOps.INSTANCE, compound.getCompound("block_state").orElseThrow()); var bsc = compound.getCompound("block_state").orElseThrow();
var state = BlockState.CODEC.parse(NbtOps.INSTANCE, bsc);
if (state.isError()) {
Logger.info("Could not decode blockstate, attempting fixes, error: "+ state.error().get().message());
bsc = (NbtCompound) Schemas.getFixer().update(TypeReferences.BLOCK_STATE, new Dynamic<>(NbtOps.INSTANCE,bsc),0, SharedConstants.getGameVersion().dataVersion().id()).getValue();
state = BlockState.CODEC.parse(NbtOps.INSTANCE, bsc);
if (state.isError()) { if (state.isError()) {
Logger.error("Could not decode blockstate setting to air. id:" + id + " error: " + state.error().get().message()); Logger.error("Could not decode blockstate setting to air. id:" + id + " error: " + state.error().get().message());
return new StateEntry(id, Blocks.AIR.getDefaultState()); return new StateEntry(id, Blocks.AIR.getDefaultState());
} else {
Logger.info("Fixed blockstate to: " + state.getOrThrow());
forceResave[0] |= true;
return new StateEntry(id, state.getOrThrow());
}
} else { } else {
return new StateEntry(id, state.getOrThrow()); return new StateEntry(id, state.getOrThrow());
} }

View File

@@ -183,7 +183,6 @@ public abstract class VoxyInstance {
} }
public void addDebug(List<String> debug) { public void addDebug(List<String> debug) {
debug.add("Voxy Core: " + VoxyCommon.MOD_VERSION);
debug.add("MemoryBuffer, Count/Size (mb): " + MemoryBuffer.getCount() + "/" + (MemoryBuffer.getTotalSize()/1_000_000)); debug.add("MemoryBuffer, Count/Size (mb): " + MemoryBuffer.getCount() + "/" + (MemoryBuffer.getTotalSize()/1_000_000));
debug.add("I/S/AWSC: " + this.ingestService.getTaskCount() + "/" + this.savingService.getTaskCount() + "/[" + this.activeWorlds.values().stream().map(a->""+a.getActiveSectionCount()).collect(Collectors.joining(", ")) + "]");//Active world section count debug.add("I/S/AWSC: " + this.ingestService.getTaskCount() + "/" + this.savingService.getTaskCount() + "/[" + this.activeWorlds.values().stream().map(a->""+a.getActiveSectionCount()).collect(Collectors.joining(", ")) + "]");//Active world section count
} }

View File

@@ -167,6 +167,21 @@ void main() {
} }
//Apply face tint //Apply face tint
#ifdef DARKENED_TINTING
if (isShaded) {
//TODO: make branchless, infact apply ahead of time to the texture itself in ModelManager since that is
// per face
if ((face>>1) == 1) {//NORTH, SOUTH
tinting.xyz *= 0.8f;
} else if ((face>>1) == 2) {//EAST, WEST
tinting.xyz *= 0.6f;
} else {//UP DOWN
tinting.xyz *= 0.9f;
}
} else {
tinting.xyz *= 0.9f;
}
#else
if (isShaded) { if (isShaded) {
//TODO: make branchless, infact apply ahead of time to the texture itself in ModelManager since that is //TODO: make branchless, infact apply ahead of time to the texture itself in ModelManager since that is
// per face // per face
@@ -178,6 +193,7 @@ void main() {
tinting.xyz *= 0.5f; tinting.xyz *= 0.5f;
} }
} }
#endif
setTintingAndExtra(tinting, conditionalTinting, addin|(face<<8)); setTintingAndExtra(tinting, conditionalTinting, addin|(face<<8));
#else #else

View File

@@ -20,7 +20,6 @@
"minecraft.MixinClientChunkManager", "minecraft.MixinClientChunkManager",
"minecraft.MixinClientCommonNetworkHandler", "minecraft.MixinClientCommonNetworkHandler",
"minecraft.MixinClientLoginNetworkHandler", "minecraft.MixinClientLoginNetworkHandler",
"minecraft.MixinDebugHud",
"minecraft.MixinFogRenderer", "minecraft.MixinFogRenderer",
"minecraft.MixinGlDebug", "minecraft.MixinGlDebug",
"minecraft.MixinMinecraftClient", "minecraft.MixinMinecraftClient",