-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Describe the bug
My CardSection extends AbstractWidget, which means FancyMenu's mixin (MixinAbstractWidget) hooks into its render() method. The RenderWidgetEvent.Pre fired by FancyMenu seems to interfere with the rendering when the widget has a Y rotation of 180° applied to the PoseStack — likely a culling or render state issue caused by FancyMenu modifying the render pipeline before my renderWidget() is called.
To Reproduce
Create this class in a fabric mod and try to open the screen when using a specific item
package dev.lunark.cobblemontcg.screen;
import dev.lunark.cobblemontcg.net.SelectBoosterPackC2SPacket;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.architectury.networking.NetworkManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.sounds.SoundEvents;
import com.mojang.math.Axis;
import java.util.*;
public class BoosterPackScreen extends Screen {
private final Set<CardSection> sections;
private final Set<Integer> selected;
public BoosterPackScreen() {
super(Component.literal("Booster Pack"));
this.sections = new HashSet<>();
this.selected = new LinkedHashSet<>();
}
@Override
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
LocalPlayer player = Minecraft.getInstance().player;
if(player == null) return;
ItemStack stack = player.getItemInHand(player.getUsedItemHand());
ItemContainerContents container = stack.getOrDefault(DataComponents.CONTAINER, null);
if(container == null) return;
List<ItemStack> items = new ArrayList<>();
container.nonEmptyItems().forEach(items::add);
float width = 56.0F;
float spanX = width * items.size();
for(CardSection section : this.sections) {
this.removeWidget(section);
}
this.sections.clear();
int cardHeight = 64; // 16 * scale(4)
int cardY = (int)(this.height / 2.0F - cardHeight / 2.0F);
for(int i = 0; i < items.size(); i++) {
ItemStack outcome = items.get(i);
float x = this.width / 2.0F - spanX / 2.0F + i * width;
CardSection element = new CardSection(i, outcome, (int)x, cardY, (int)width, cardHeight);
this.addRenderableWidget(element);
this.sections.add(element);
}
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override
public void onClose() {
NetworkManager.sendToServer(new SelectBoosterPackC2SPacket(this.selected));
super.onClose();
}
public class CardSection extends AbstractWidget {
private final int index;
private final ItemStack stack;
public CardSection(int index, ItemStack stack, int x, int y, int width, int height) {
super(x, y, width, height, Component.empty());
this.index = index;
this.stack = stack;
}
@Override
public void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) {
if((this.isFocused() || this.isHovered()) && !BoosterPackScreen.this.selected.contains(this.index)) {
//context.fillGradient(this.getX(), this.getY(), this.getX() + this.getWidth(),
// this.getY() + this.getHeight(), -1000, 0x15CCCCCC, 0x15CCCCCC);
}
RenderSystem.disableDepthTest();
boolean selected = this.isHovered() || this.isFocused();
float scale = 4.0F;
context.pose().pushPose();
context.pose().translate(this.getX() + this.width / 2.0F, this.getY() + this.height / 2.0F, 0.0F);
if(!BoosterPackScreen.this.selected.contains(this.index)) {
context.pose().mulPose(Axis.YP.rotationDegrees(180.0F));
if(selected) {
context.pose().mulPose(Axis.ZP.rotationDegrees(-1.0F));
scale += 0.5F;
}
}
context.pose().scale(scale, scale, 1.0F);
context.pose().translate(-8.0F, -8.0F, 0.0F);
context.renderItem(this.stack, 0, 0);
context.pose().popPose();
RenderSystem.enableDepthTest();
if(this.isHovered() && BoosterPackScreen.this.selected.contains(this.index)) {
context.renderTooltip(Minecraft.getInstance().font, this.stack, mouseX, mouseY);
}
}
@Override
protected void updateWidgetNarration(NarrationElementOutput builder) {
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if(this.active && this.visible && !BoosterPackScreen.this.selected.contains(this.index)) {
if(this.isValidClickButton(button)) {
boolean bl = this.isMouseOver(mouseX, mouseY);
if(bl) {
Minecraft.getInstance().getSoundManager()
.play(SimpleSoundInstance.forUI(SoundEvents.AMETHYST_CLUSTER_HIT, 1.5F));
this.onClick(mouseX, mouseY);
return true;
}
}
return false;
} else {
return false;
}
}
@Override
public void onClick(double mouseX, double mouseY) {
BoosterPackScreen.this.selected.add(this.index);
}
}
}What I think is happening:
My CardSection extends AbstractWidget, which means FancyMenu's mixin (MixinAbstractWidget) hooks into its render() method. The RenderWidgetEvent.Pre fired by FancyMenu seems to interfere with the rendering when the widget has a Y rotation of 180° applied to the PoseStack — likely a culling or render state issue caused by FancyMenu modifying the render pipeline before my renderWidget() is called.
What I've already tried:
RenderSystem.disableCull()before renderingRenderSystem.setShaderColor(1, 1, 1, 1)to reset alpha- Forcing
bufferSource.endBatch()after rendering - Translating on the Z axis
None of these fixed the issue.
Is there a recommended way to either exclude a specific AbstractWidget subclass from FancyMenu's mixin, or a proper API to signal that a widget should not be touched by FancyMenu's render pipeline ?
I'm not sure how it works exactly or why this is happening but what I know is, when I remove FancyMenu, it all works fine
Expected behavior
My abstract widgets should render even when rotated 180° to see the back of the widget/item.
Game Log
11:29:01] [Server thread/INFO]:CaptainPrysm[local:E:e5e3f9ee] logged in with entity id 3 at (133.1950102830541, 76.0, 90.63101850077675)
[11:29:01] [Render thread/INFO]:[FANCYMENU] ScreenCustomizationLayer registered: receiving_level_screen
[11:29:01] [Server thread/INFO]:CaptainPrysm joined the game
[11:29:02] [Render thread/INFO]:Attaching attributes for 1 cobblemon_tcg:card_album to class_746['CaptainPrysm'/3, l='ClientLevel', x=133.20, y=76.00, z=90.63]
[11:29:02] [Render thread/INFO]:[FANCYMENU] Connected to a server with FancyMenu installed: local_lan_world
[11:29:02] [Server thread/INFO]:Attaching attributes for 1 cobblemon_tcg:card_album to class_3222['CaptainPrysm'/3, l='ServerLevel[New World]', x=133.20, y=76.00, z=90.63]
[11:29:02] [Server thread/INFO]:[TCG-Debug] Album trouvé: Card Album
[11:29:02] [Server thread/INFO]:[TCG-Debug] Taille du container: 12
[11:29:02] [Server thread/INFO]:[TCG-Debug] CARTE VALIDE slot 0 - Attachement au root...
[11:29:02] [Server thread/INFO]:[TCG-Debug] CARTE VALIDE slot 1 - Attachement au root...
[11:29:02] [Server thread/INFO]:[TCG-Debug] CARTE VALIDE slot 2 - Attachement au root...
[11:29:02] [Server thread/INFO]:[FANCYMENU] A client with FancyMenu installed joined the server: CaptainPrysm
[11:29:02] [Render thread/INFO]:Loaded 72 advancements
[11:29:02] [Render thread/INFO]:Attaching attributes for 1 cobblemon_tcg:card_album to class_746['CaptainPrysm'/3, l='ClientLevel', x=133.20, y=76.00, z=90.63]
[11:29:03] [Render thread/INFO]:[FANCYMENU] ScreenCustomizationLayer registered: pause_screen
[11:29:04] [Server thread/INFO]:Saving and pausing game...
[11:29:04] [Server thread/INFO]:Saving chunks for level 'ServerLevel[New World]'/minecraft:overworld
[11:29:04] [Server thread/INFO]:Saving chunks for level 'ServerLevel[New World]'/minecraft:the_nether
[11:29:04] [Server thread/INFO]:Saving chunks for level 'ServerLevel[New World]'/minecraft:the_end
[11:29:35] [Render thread/INFO]:[FANCYMENU] ScreenCustomizationLayer registered: dev.lunark.cobblemontcg.screen.BoosterPackScreen
Screenshots
Basic Information (please complete the following information):
- OS: Windows
- FancyMenu Version : 2.8.1
- Fabric Version 0.17.2
- Minecraft Version 1.21.1
- Active Mods : FancyMenu and its dependencies, Cobblemon, Architectury API, Trinkets + OWO Lib, Fabric API, Global Datapacks

