Skip to content

Commit

Permalink
Improvements to render type handling (#529)
Browse files Browse the repository at this point in the history
* Move to neo 47.1.84

* Separate pixelmon compat from main mixins

* Register config factory

* Fix error message

* Update mods.toml

* Use Forge delegates as map keys instead of blocks themselves

Theoretically fixes issues around registry replacement

* Redirect getRenderTypes calls from the Sodium & vanilla chunk meshers

Fixes glass not being translucent with mods like XyCraft, as they
override these methods

---------

Co-authored-by: dima_dencep <[email protected]>
  • Loading branch information
embeddedt and dima-dencep authored Jan 13, 2024
1 parent c37a355 commit b613f2e
Show file tree
Hide file tree
Showing 18 changed files with 160 additions and 38 deletions.
7 changes: 5 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ loom {
"mixins.oculus.compat.indigo.json",
"mixins.oculus.compat.dh.json",
"mixins.oculus.compat.indium.json",
"mixins.oculus.compat.json"
"mixins.oculus.compat.pixelmon.json"
]
}
mixin.defaultRefmapName = "oculus-mixins-refmap.json"
Expand Down Expand Up @@ -94,13 +94,16 @@ repositories {
maven {
url "https://maven.blamejared.com/"
}
maven {
url "https://maven.neoforged.net/releases"
}
mavenCentral()
}

dependencies {
minecraft "com.mojang:minecraft:${minecraft_version}"
mappings loom.officialMojangMappings()
forge "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
forge "net.neoforged:forge:${minecraft_version}-${forge_version}"

modCompileOnly "org.embeddedt:embeddium-${minecraft_version}:${embeddium_version}"
compileOnly "maven.modrinth:distanthorizons:2.0.1-a-1.20.1"
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ loom.platform = forge
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.20.1
forge_version= 47.2.0
forge_version=47.1.84

# Mod Properties
mod_version = 1.6.13
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pluginManagement {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
maven { url "https://maven.architectury.dev/" }
maven { url "https://maven.architectury.dev/" }
maven { url "https://maven.minecraftforge.net" }
mavenCentral()
gradlePluginPortal()
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/coderbot/iris/Iris.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.common.MinecraftForge;
Expand Down Expand Up @@ -111,6 +112,7 @@ public Iris() {

IRIS_VERSION = ModList.get().getModContainerById(MODID).get().getModInfo().getVersion().toString();

ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> new ConfigScreenHandler.ConfigScreenFactory((mc, screen) -> new ShaderPackScreen(screen)));
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true));
}catch (Exception ignored) {
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/coderbot/iris/LaunchWarn.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class LaunchWarn {
public static void main(String[] args) {
// TODO: make this translatable
String message = "This file is the Forge version of Oculus, meant to be installed as a mod. Would you like to get the Forge Installer instead?";
String fallback = "This file is the Forge version of Oculus, meant to be installed as a mod. Please download the Forge Installer from https://files.minecraftforge.net.";
String fallback = "This file is the Forge version of Oculus, meant to be installed as a mod. Please download the Forge Installer from https://neoforged.net/";
if (GraphicsEnvironment.isHeadless()) {
System.err.println(fallback);
} else {
Expand All @@ -27,7 +27,7 @@ public static void main(String[] args) {

if (option == JOptionPane.YES_OPTION) {
try {
Desktop.getDesktop().browse(URI.create("https://files.minecraftforge.net"));
Desktop.getDesktop().browse(URI.create("https://neoforged.net"));
} catch (IOException e) {
e.printStackTrace();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.coderbot.iris.Iris;
import net.coderbot.iris.shaderpack.materialmap.BlockEntry;
import net.coderbot.iris.shaderpack.materialmap.BlockRenderType;
import net.coderbot.iris.shaderpack.materialmap.NamespacedId;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
Expand All @@ -18,10 +19,12 @@
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraftforge.client.ChunkRenderTypeSet;
import net.minecraftforge.registries.ForgeRegistries;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class BlockMaterialMapping {
public static Object2IntMap<BlockState> createBlockStateIdMap(Int2ObjectMap<List<BlockEntry>> blockPropertiesMap) {
Expand All @@ -36,13 +39,13 @@ public static Object2IntMap<BlockState> createBlockStateIdMap(Int2ObjectMap<List
return blockStateIds;
}

public static Map<Block, ChunkRenderTypeSet> createBlockTypeMap(Map<NamespacedId, BlockRenderType> blockPropertiesMap) {
Map<Block, ChunkRenderTypeSet> blockTypeIds = new Reference2ReferenceOpenHashMap<>();
public static Map<Holder.Reference<Block>, ChunkRenderTypeSet> createBlockTypeMap(Map<NamespacedId, BlockRenderType> blockPropertiesMap) {
Map<Holder.Reference<Block>, ChunkRenderTypeSet> blockTypeIds = new Object2ObjectOpenHashMap<>();

blockPropertiesMap.forEach((id, blockType) -> {
ResourceLocation resourceLocation = new ResourceLocation(id.getNamespace(), id.getName());

Block block = BuiltInRegistries.BLOCK.get(resourceLocation);
Holder.Reference<Block> block = ForgeRegistries.BLOCKS.getDelegateOrThrow(resourceLocation);

blockTypeIds.put(block, ChunkRenderTypeSet.of(convertBlockToRenderType(blockType)));
});
Expand All @@ -68,10 +71,15 @@ private static void addBlockStates(BlockEntry entry, Object2IntMap<BlockState> i
NamespacedId id = entry.getId();
ResourceLocation resourceLocation = new ResourceLocation(id.getNamespace(), id.getName());

Block block = BuiltInRegistries.BLOCK.get(resourceLocation);
Optional<Holder.Reference<Block>> delegateOpt = ForgeRegistries.BLOCKS.getDelegate(resourceLocation);

// If the block doesn't exist, by default the registry will return AIR. That probably isn't what we want.
// TODO: Assuming that Registry.BLOCK.getDefaultId() == "minecraft:air" here
if (delegateOpt.isEmpty() || !delegateOpt.get().isBound()) {
return;
}

Block block = delegateOpt.get().get();

if (block == Blocks.AIR) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.coderbot.iris.shaderpack.materialmap.NamespacedId;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Holder;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.ChunkRenderTypeSet;
Expand All @@ -16,7 +17,7 @@ public class BlockRenderingSettings {

private boolean reloadRequired;
private Object2IntMap<BlockState> blockStateIds;
private Map<Block, ChunkRenderTypeSet> blockTypeIds;
private Map<Holder.Reference<Block>, ChunkRenderTypeSet> blockTypeIds;
private Object2IntFunction<NamespacedId> entityIds;
private Object2IntFunction<NamespacedId> itemIds;
private float ambientOcclusionLevel;
Expand Down Expand Up @@ -54,7 +55,7 @@ public Object2IntMap<BlockState> getBlockStateIds() {
}

@Nullable
public Map<Block, ChunkRenderTypeSet> getBlockTypeIds() {
public Map<Holder.Reference<Block>, ChunkRenderTypeSet> getBlockTypeIds() {
return blockTypeIds;
}

Expand All @@ -78,7 +79,7 @@ public void setBlockStateIds(Object2IntMap<BlockState> blockStateIds) {
this.blockStateIds = blockStateIds;
}

public void setBlockTypeIds(Map<Block, ChunkRenderTypeSet> blockTypeIds) {
public void setBlockTypeIds(Map<Holder.Reference<Block>, ChunkRenderTypeSet> blockTypeIds) {
if (this.blockTypeIds != null && this.blockTypeIds.equals(blockTypeIds)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package net.coderbot.iris.mixin.compat.pixelmon;
package net.coderbot.iris.compat.pixelmon.mixin;

import com.mojang.blaze3d.vertex.BufferBuilder;
import org.objectweb.asm.Opcodes;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package net.coderbot.iris.mixin.compat;
package net.coderbot.iris.compat.pixelmon.mixin;

import net.minecraftforge.fml.loading.FMLLoader;
import org.objectweb.asm.tree.ClassNode;
Expand All @@ -8,7 +8,7 @@
import java.util.List;
import java.util.Set;

public class CompatMixinPlugin implements IMixinConfigPlugin {
public class OculusPixelmonCompatMixinPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {

Expand All @@ -21,10 +21,7 @@ public String getRefMapperConfig() {

@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
int startIndex = mixinClassName.indexOf("compat.") + "compat.".length();
int endIndex = mixinClassName.indexOf(".", startIndex);
String modid = mixinClassName.substring(startIndex, endIndex);
return FMLLoader.getLoadingModList().getModFileById(modid) != null;
return FMLLoader.getLoadingModList().getModFileById("pixelmon") != null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package net.coderbot.iris.mixin;

import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Holder;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.ChunkRenderTypeSet;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.registries.ForgeRegistries;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.util.Map;

@Mixin(ChunkRenderDispatcher.RenderChunk.RebuildTask.class)
public class MixinChunkRenderDispatcherRebuildTask {
@Redirect(method = "compile", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/BakedModel;getRenderTypes(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/util/RandomSource;Lnet/minecraftforge/client/model/data/ModelData;)Lnet/minecraftforge/client/ChunkRenderTypeSet;"))
private ChunkRenderTypeSet oculus$overrideRenderTypes(BakedModel instance, BlockState blockState, RandomSource randomSource, ModelData modelData) {
Map<Holder.Reference<Block>, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds();
if (idMap != null) {
ChunkRenderTypeSet type = idMap.get(ForgeRegistries.BLOCKS.getDelegateOrThrow(blockState.getBlock()));
if (type != null) {
return type;
}
}

return instance.getRenderTypes(blockState, randomSource, modelData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.coderbot.iris.mixin;

import net.coderbot.iris.Iris;
import net.coderbot.iris.gl.shader.ShaderCompileException;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPacketListener.class)
public class MixinClientPacketListener {
@Shadow
private Minecraft minecraft;

@Inject(method = "handleLogin", at = @At("TAIL"))
private void iris$showUpdateMessage(ClientboundLoginPacket a, CallbackInfo ci) {
if (this.minecraft.player == null) {
return;
}

Iris.getStoredError().ifPresent(e ->
this.minecraft.player.displayClientMessage(Component.translatable(e instanceof ShaderCompileException ? "iris.load.failure.shader" : "iris.load.failure.generic").append(Component.literal("Copy Info").withStyle(arg -> arg.withUnderlined(true).withColor(ChatFormatting.BLUE).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, e.getMessage())))), false));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Holder;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.ChunkRenderTypeSet;
import net.minecraftforge.registries.ForgeRegistries;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand All @@ -17,9 +19,9 @@
public class MixinItemBlockRenderTypes {
@Inject(method = "getRenderLayers", at = @At("HEAD"), cancellable = true, remap = false)
private static void iris$setCustomRenderType(BlockState arg, CallbackInfoReturnable<ChunkRenderTypeSet> cir) {
Map<Block, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds();
Map<Holder.Reference<Block>, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds();
if (idMap != null) {
ChunkRenderTypeSet type = idMap.get(arg.getBlock());
ChunkRenderTypeSet type = idMap.get(ForgeRegistries.BLOCKS.getDelegateOrThrow(arg.getBlock()));
if (type != null) {
cir.setReturnValue(type);
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ side = "BOTH"

[[dependencies.oculus]]
modId = "embeddium"
mandatory = false
versionRange = "[0.2.14,)"
ordering = "NONE"
side = "CLIENT"
14 changes: 0 additions & 14 deletions src/main/resources/mixins.oculus.compat.json

This file was deleted.

13 changes: 13 additions & 0 deletions src/main/resources/mixins.oculus.compat.pixelmon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"required": true,
"minVersion": "0.8",
"plugin": "net.coderbot.iris.compat.pixelmon.mixin.OculusPixelmonCompatMixinPlugin",
"package": "net.coderbot.iris.compat.pixelmon.mixin",
"compatibilityLevel": "JAVA_8",
"client": [
"MixinNormalizedFace"
],
"injectors": {
"defaultRequire": 1
}
}
2 changes: 2 additions & 0 deletions src/main/resources/mixins.oculus.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"MixinChainedJsonException",
"MixinBooleanState",
"MixinBiomes",
"MixinChunkRenderDispatcherRebuildTask",
"MixinClientLanguage",
"MixinClientPacketListener",
"MixinDebugScreenOverlay",
"MixinTheEndPortalRenderer",
"MixinEntityRenderDispatcher",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package net.coderbot.iris.compat.sodium.mixin.shader_overrides;

import me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Holder;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.ChunkRenderTypeSet;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.registries.ForgeRegistries;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.util.Map;

@Mixin(ChunkBuilderMeshingTask.class)
public class MixinChunkBuilderMeshingTask {
/**
* @author embeddedt
* @reason On Forge, render types are not intended to be driven by a central registry like in vanilla; instead, they
* get queried from the block model during meshing. Only the default baked models defer to the vanilla registry;
* specifying a render type in the model JSON or using a custom model will return its own value. Thus, we need
* to redirect the access at a higher level.
*/
@Redirect(method = "execute(Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationToken;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/BakedModel;getRenderTypes(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/util/RandomSource;Lnet/minecraftforge/client/model/data/ModelData;)Lnet/minecraftforge/client/ChunkRenderTypeSet;"),
remap = false)
private ChunkRenderTypeSet oculus$overrideRenderTypes(BakedModel instance, BlockState blockState, RandomSource randomSource, ModelData modelData) {
Map<Holder.Reference<Block>, ChunkRenderTypeSet> idMap = BlockRenderingSettings.INSTANCE.getBlockTypeIds();
if (idMap != null) {
ChunkRenderTypeSet type = idMap.get(ForgeRegistries.BLOCKS.getDelegateOrThrow(blockState.getBlock()));
if (type != null) {
return type;
}
}

return instance.getRenderTypes(blockState, randomSource, modelData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"copyEntity.shadows.EntityRenderDispatcherMixin",
"font.MixinGlyphRenderer",
"pbr_animation.MixinSpriteContents",
"shader_overrides.MixinChunkBuilderMeshingTask",
"shader_overrides.MixinGlProgram",
"shader_overrides.MixinRegionChunkRenderer",
"shader_overrides.MixinShaderChunkRenderer",
Expand Down

0 comments on commit b613f2e

Please sign in to comment.