Skip to content

Commit a468640

Browse files
dsnsgithubcodex
andcommitted
Restore fast item glint rendering and avoid animation-toggle reloads
Batch the previous GUI glint overlay, skip block glint while 1.7 Animations is enabled, and cache static sprite quads. Select already-baked trapdoor models without reloading resources. Add in-client regression checks and rendering benchmarks. Co-Authored-By: GPT-6 <codex@openai.com>
1 parent dd2ce3f commit a468640

15 files changed

Lines changed: 923 additions & 38 deletions

File tree

‎versions/1.8.9/src/main/java/io/github/axolotlclient/oldanimations/config/OldAnimationsConfig.java‎

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import io.github.axolotlclient.oldanimations.OldAnimations;
2727
import lombok.Getter;
2828
import net.fabricmc.loader.api.FabricLoader;
29-
import net.minecraft.client.Minecraft;
3029
import net.ornithemc.osl.lifecycle.api.client.MinecraftClientEvents;
3130

3231
public class OldAnimationsConfig {
@@ -99,8 +98,7 @@ public class OldAnimationsConfig {
9998
public final BooleanOption zombieVillagerHelmetOffset = new BooleanOption("zombieVillagerHelmetOffset", true);
10099
public final BooleanOption framedItemRotationOffset = new BooleanOption("framedItemRotationOffset", true);
101100

102-
/* toggling these two rebuilds cached game state, so their previous values are tracked */
103-
private boolean previousTrapDoorItemPosition = trapDoorItemPosition();
101+
/* Potion colors are cached; trapdoor models are selected at render time. */
104102
private boolean previousOldJumpBoostPotionColor = oldJumpBoostPotionColor();
105103

106104
/**
@@ -111,10 +109,6 @@ public static boolean isEnabled() {
111109
return instance.enabled.get();
112110
}
113111

114-
private boolean trapDoorItemPosition() {
115-
return enabled.get() && trapDoorItemPosition.get();
116-
}
117-
118112
private boolean oldJumpBoostPotionColor() {
119113
return enabled.get() && oldJumpBoostPotionColor.get();
120114
}
@@ -190,30 +184,23 @@ public void initConfig() {
190184
AxolotlClientConfig.getInstance().register(configManager);
191185
configManager.load();
192186

193-
/* attempt to prevent calling resourcereload during game init */
194-
previousTrapDoorItemPosition = trapDoorItemPosition();
187+
/* Seed the effective color setting after the configuration is loaded. */
195188
previousOldJumpBoostPotionColor = oldJumpBoostPotionColor();
196189

197-
/* reload the resources upon toggling certain options */
198-
reloadResources();
190+
trackPotionColors();
199191
}
200192

201193
/**
202-
* The trapdoor item model is baked at resource load, and potion colors are
203-
* cached separately, so both need a nudge when their option is toggled.
204-
* The master switch counts as toggling both of them.
194+
* Both trapdoor variants are always baked by ModelBakeryMixin and selected
195+
* by ItemModelShaperMixin. Toggling them (or the master switch) must not
196+
* reload every resource and rebuild the world. Only potion colors need
197+
* their cache invalidated when the effective option changes.
205198
*/
206-
private void reloadResources() {
199+
private void trackPotionColors() {
207200
MinecraftClientEvents.TICK_END.register(client -> {
208-
if (trapDoorItemPosition() != previousTrapDoorItemPosition) {
209-
previousTrapDoorItemPosition = trapDoorItemPosition();
210-
previousOldJumpBoostPotionColor = oldJumpBoostPotionColor();
211-
Minecraft.getInstance().reloadResources();
212-
reloadPotionColors = true;
213-
return;
214-
}
215-
if (oldJumpBoostPotionColor() != previousOldJumpBoostPotionColor) {
216-
previousOldJumpBoostPotionColor = oldJumpBoostPotionColor();
201+
boolean current = oldJumpBoostPotionColor();
202+
if (current != previousOldJumpBoostPotionColor) {
203+
previousOldJumpBoostPotionColor = current;
217204
reloadPotionColors = true;
218205
}
219206
});
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 3 of the License, or (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public License
13+
* along with this program; if not, write to the Free Software Foundation,
14+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15+
*
16+
* For more information, see the LICENSE file.
17+
*/
18+
19+
package io.github.axolotlclient.oldanimations.mixin;
20+
21+
import java.util.List;
22+
23+
import io.github.axolotlclient.oldanimations.util.SpriteQuadProvider;
24+
import net.minecraft.client.resource.model.BakedQuad;
25+
import net.minecraft.client.resource.model.BasicBakedModel;
26+
import org.spongepowered.asm.mixin.Mixin;
27+
import org.spongepowered.asm.mixin.Unique;
28+
29+
@Mixin(BasicBakedModel.class)
30+
public abstract class BasicBakedModelMixin implements SpriteQuadProvider {
31+
@Unique
32+
private List<BakedQuad> axolotlclient$spriteSourceQuads;
33+
34+
@Unique
35+
private List<BakedQuad> axolotlclient$spriteQuads;
36+
37+
@Override
38+
public List<BakedQuad> axolotlclient$getSpriteQuads(List<BakedQuad> quads) {
39+
// The cache belongs to the baked model, so resource reloads replace it
40+
// along with the geometry. Glint passes reuse it without scanning or
41+
// allocating another list on every item render.
42+
if (axolotlclient$spriteSourceQuads != quads) {
43+
axolotlclient$spriteQuads = SpriteQuadProvider.filter(quads);
44+
axolotlclient$spriteSourceQuads = quads;
45+
}
46+
return axolotlclient$spriteQuads;
47+
}
48+
}

‎versions/1.8.9/src/main/java/io/github/axolotlclient/oldanimations/mixin/ItemRendererMixin.java‎

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,41 @@
2525
import com.llamalad7.mixinextras.sugar.Local;
2626
import io.github.axolotlclient.oldanimations.config.OldAnimationsConfig;
2727
import io.github.axolotlclient.oldanimations.util.ItemUtil;
28+
import io.github.axolotlclient.oldanimations.util.GuiGlintRenderer;
29+
import io.github.axolotlclient.oldanimations.util.SpriteQuadProvider;
2830
import net.minecraft.client.render.entity.ItemRenderer;
31+
import net.minecraft.client.Minecraft;
2932
import net.minecraft.client.render.model.block.ModelTransformations;
3033
import net.minecraft.client.render.platform.GlStateManager;
3134
import net.minecraft.client.resource.model.BakedModel;
3235
import net.minecraft.client.resource.model.BakedQuad;
3336
import net.minecraft.item.ItemStack;
34-
import net.minecraft.util.math.Direction;
37+
import net.minecraft.client.render.texture.TextureManager;
38+
import net.minecraft.resource.Identifier;
39+
import org.spongepowered.asm.mixin.Final;
40+
import org.spongepowered.asm.mixin.Shadow;
3541
import org.spongepowered.asm.mixin.Mixin;
3642
import org.spongepowered.asm.mixin.Unique;
3743
import org.spongepowered.asm.mixin.injection.*;
3844
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
3945
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
4046

41-
import java.util.ArrayList;
4247
import java.util.List;
4348

4449
@Mixin(ItemRenderer.class /* C_6823239 */)
4550
public abstract class ItemRendererMixin {
4651

52+
@Shadow
53+
@Final
54+
private static Identifier ENCHANTMENT_GLINT_LOCATION;
55+
56+
@Shadow
57+
@Final
58+
private TextureManager textureManager;
59+
60+
@Shadow
61+
public abstract boolean isGui3d(ItemStack stack);
62+
4763
@Unique
4864
private BakedModel axolotlclient$model = null;
4965

@@ -92,30 +108,31 @@ public abstract class ItemRendererMixin {
92108
}
93109

94110
if (!model.isGui3d() && (axolotlclient$transform == ModelTransformations.Type.GUI || axolotlclient$shouldBeSpriteOrSwapNormal(false))) {
95-
/* this is the easiest way to have fast items with the 1.8 model system */
96-
/* even forge does this xD */
97-
List<BakedQuad> filtered = new ArrayList<>(quads.size());
98-
for (BakedQuad quad : quads) {
99-
if (quad.getFace() == Direction.SOUTH) {
100-
filtered.add(quad);
101-
}
102-
}
103-
return filtered;
111+
return SpriteQuadProvider.get(model, quads);
104112
}
105113
return quads;
106114
}
107115

108116
@Inject(method = "renderEnchantmentGlint", at = @At("HEAD"), cancellable = true)
109-
private void axolotlclient$disableDefaultGlint(CallbackInfo ci) {
117+
private void axolotlclient$disableDefaultGlint(BakedModel model, CallbackInfo ci) {
110118
if (!OldAnimationsConfig.isEnabled()) {
111119
return;
112120
}
113121

114-
if (axolotlclient$shouldBeSpriteOrSwapNormal(false)) {
122+
// Keep the pre-refactor fast paths: no two extra geometry passes on
123+
// blocks, and a flat overlay for GUI items. Master-off remains vanilla.
124+
if (model.isGui3d() || axolotlclient$transform == ModelTransformations.Type.GUI || axolotlclient$shouldBeSpriteOrSwapNormal(false)) {
115125
ci.cancel();
116126
}
117127
}
118128

129+
@Inject(method = "renderGuiItemModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/ItemRenderer;renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/resource/model/BakedModel;)V", shift = At.Shift.AFTER))
130+
private void axolotlclient$renderGuiGlint(ItemStack stack, int x, int y, CallbackInfo ci) {
131+
if (OldAnimationsConfig.isEnabled() && stack.hasEnchantmentGlint() && !isGui3d(stack)) {
132+
GuiGlintRenderer.render(textureManager, ENCHANTMENT_GLINT_LOCATION, Minecraft.getTime());
133+
}
134+
}
135+
119136
@Inject(method = "renderItemInHand(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/block/ModelTransformations$Type;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/ItemRenderer;renderItemInHand(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/resource/model/BakedModel;Lnet/minecraft/client/render/model/block/ModelTransformations$Type;)V"))
120137
private void axolotlclient$fastItemOffset(ItemStack stack, ModelTransformations.Type transformationType, CallbackInfo ci) {
121138
//todo: is this really needed? im not so sure anymore
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 3 of the License, or (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public License
13+
* along with this program; if not, write to the Free Software Foundation,
14+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15+
*
16+
* For more information, see the LICENSE file.
17+
*/
18+
19+
package io.github.axolotlclient.oldanimations.util;
20+
21+
import net.minecraft.client.render.platform.GlStateManager;
22+
import net.minecraft.client.render.texture.TextureAtlas;
23+
import net.minecraft.client.render.texture.TextureManager;
24+
import net.minecraft.client.render.vertex.BufferBuilder;
25+
import net.minecraft.client.render.vertex.DefaultVertexFormat;
26+
import net.minecraft.client.render.vertex.Tesselator;
27+
import net.minecraft.resource.Identifier;
28+
29+
/** The previous 1.7 GUI overlay, with both quads submitted in one draw. */
30+
public final class GuiGlintRenderer {
31+
private GuiGlintRenderer() {
32+
}
33+
34+
public static void render(TextureManager textures, Identifier glint, long time) {
35+
GlStateManager.depthMask(false);
36+
GlStateManager.depthFunc(518);
37+
GlStateManager.disableLighting();
38+
GlStateManager.blendFuncSeparate(772, 1, 0, 0);
39+
textures.bind(glint);
40+
GlStateManager.pushMatrix();
41+
try {
42+
GlStateManager.scalef(0.5F, 0.5F, 0.5F);
43+
GlStateManager.translatef(0.0F, -0.25F, 0.0F);
44+
Tesselator tesselator = Tesselator.getInstance();
45+
BufferBuilder buffer = tesselator.getBuffer();
46+
buffer.begin(7, DefaultVertexFormat.POSITION_TEX_COLOR);
47+
appendQuad(buffer, (float) (time % 3000L) / 3000.0F, 4.0F);
48+
appendQuad(buffer, (float) (time % 4873L) / 4873.0F, -1.0F);
49+
tesselator.end();
50+
} finally {
51+
GlStateManager.popMatrix();
52+
GlStateManager.blendFuncSeparate(770, 771, 1, 0);
53+
GlStateManager.enableLighting();
54+
GlStateManager.depthFunc(515);
55+
GlStateManager.depthMask(true);
56+
textures.bind(TextureAtlas.BLOCKS_LOCATION);
57+
}
58+
}
59+
60+
private static void appendQuad(BufferBuilder buffer, float speed, float skew) {
61+
// Same positions, UVs and color as the removed GlintQuadModel, without
62+
// allocating a model, vertex arrays or lists for each overlay pass.
63+
float dimension = 20.0F / 256.0F;
64+
vertex(buffer, -0.5F, -0.25F, speed + dimension * skew, dimension);
65+
vertex(buffer, 0.5F, -0.25F, speed + dimension + dimension * skew, dimension);
66+
vertex(buffer, 0.5F, 0.75F, speed + dimension, 0.0F);
67+
vertex(buffer, -0.5F, 0.75F, speed, 0.0F);
68+
}
69+
70+
private static void vertex(BufferBuilder buffer, float x, float y, float u, float v) {
71+
buffer.vertex(x, y, 0.0F).texture(u, v).color(128, 64, 204, 255).nextVertex();
72+
}
73+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 3 of the License, or (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public License
13+
* along with this program; if not, write to the Free Software Foundation,
14+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15+
*
16+
* For more information, see the LICENSE file.
17+
*/
18+
19+
package io.github.axolotlclient.oldanimations.util;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
24+
import net.minecraft.client.resource.model.BakedModel;
25+
import net.minecraft.client.resource.model.BakedQuad;
26+
import net.minecraft.client.resource.model.BasicBakedModel;
27+
import net.minecraft.util.math.Direction;
28+
29+
/** The south-facing quads used by the flat item renderer. */
30+
public interface SpriteQuadProvider {
31+
List<BakedQuad> axolotlclient$getSpriteQuads(List<BakedQuad> quads);
32+
33+
static List<BakedQuad> get(BakedModel model, List<BakedQuad> quads) {
34+
// Vanilla baked models keep the same quad list for their lifetime. Do not
35+
// cache custom models or subclasses: they may return dynamic geometry.
36+
if (model.getClass() == BasicBakedModel.class) {
37+
return ((SpriteQuadProvider) model).axolotlclient$getSpriteQuads(quads);
38+
}
39+
return filter(quads);
40+
}
41+
42+
static List<BakedQuad> filter(List<BakedQuad> quads) {
43+
List<BakedQuad> filtered = new ArrayList<>();
44+
for (BakedQuad quad : quads) {
45+
if (quad.getFace() == Direction.SOUTH) {
46+
filtered.add(quad);
47+
}
48+
}
49+
return List.copyOf(filtered);
50+
}
51+
}

‎versions/1.8.9/src/main/resources/assets/axolotlclient-oldanimations/lang/en_us.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
"thirdPersonPositions": "Third Person Item Positions",
9292
"thirdPersonPositions.tooltip": "Reverts third person item transformations to match 1.7. Currently, this feature will disable the ability for resource packs to alter item positions, however, this is subject to change in the future.",
9393
"trapDoorItemPosition": "Trapdoor Item Position",
94-
"trapDoorItemPosition.tooltip": "Reverts the trapdoor item model position when viewed in the inventory, while held, or dropped to match 1.7. Toggling this will reload the game resources!",
94+
"trapDoorItemPosition.tooltip": "Reverts the trapdoor item model position when viewed in the inventory, while held, or dropped to match 1.7.",
9595
"useAndMineSound": "Use and Mine Sound",
9696
"useAndMineSound.tooltip": "Plays block mining sounds while using and item and mining to imiate block breaking.",
9797
"framedItemRotationOffset": "Framed Item Rotation Offset",

‎versions/1.8.9/src/main/resources/oldanimations.mixins.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"minVersion": "0.5.0"
77
},
88
"client": [
9+
"BasicBakedModelMixin",
910
"ClientPlayNetworkHandlerMixin",
1011
"ClientPlayerInteractionManagerAccessor",
1112
"ClientPlayerInteractionManagerMixin",

0 commit comments

Comments
 (0)