24
24
25
25
import net .minecraft .block .Block ;
26
26
import net .minecraft .block .BlockState ;
27
+ import net .minecraft .block .Blocks ;
27
28
import net .minecraft .client .MinecraftClient ;
28
29
import net .minecraft .client .render .model .BakedModel ;
29
30
import net .minecraft .client .render .model .BakedQuad ;
36
37
import net .minecraft .world .BlockRenderView ;
37
38
import net .minecraft .util .math .random .Random ;
38
39
40
+ import net .fabricmc .fabric .api .renderer .v1 .Renderer ;
41
+ import net .fabricmc .fabric .api .renderer .v1 .RendererAccess ;
42
+ import net .fabricmc .fabric .api .renderer .v1 .material .BlendMode ;
43
+ import net .fabricmc .fabric .api .renderer .v1 .material .RenderMaterial ;
39
44
import net .fabricmc .fabric .api .renderer .v1 .mesh .Mesh ;
40
- import net .fabricmc .fabric .api .renderer .v1 .mesh .MutableQuadView ;
41
- import net .fabricmc .fabric .api .renderer .v1 .mesh .QuadEmitter ;
42
45
import net .fabricmc .fabric .api .renderer .v1 .model .FabricBakedModel ;
46
+ import net .fabricmc .fabric .api .renderer .v1 .model .ModelHelper ;
43
47
import net .fabricmc .fabric .api .renderer .v1 .render .RenderContext ;
44
48
import net .fabricmc .fabric .api .rendering .data .v1 .RenderAttachedBlockView ;
45
49
46
50
final class FrameBakedModel implements BakedModel , FabricBakedModel {
47
51
private final Mesh frameMesh ;
48
52
private final Sprite frameSprite ;
53
+ private final RenderMaterial translucentMaterial ;
54
+ private final RenderMaterial translucentEmissiveMaterial ;
49
55
50
56
FrameBakedModel (Mesh frameMesh , Sprite frameSprite ) {
51
57
this .frameMesh = frameMesh ;
52
58
this .frameSprite = frameSprite ;
59
+
60
+ Renderer renderer = RendererAccess .INSTANCE .getRenderer ();
61
+ this .translucentMaterial = renderer .materialFinder ().blendMode (0 , BlendMode .TRANSLUCENT ).find ();
62
+ this .translucentEmissiveMaterial = renderer .materialFinder ().blendMode (0 , BlendMode .TRANSLUCENT ).emissive (0 , true ).find ();
53
63
}
54
64
55
65
@ Override
@@ -69,7 +79,7 @@ public boolean hasDepth() {
69
79
70
80
@ Override
71
81
public boolean isSideLit () {
72
- return false ;
82
+ return true ; // we want the block to be lit from the side when rendered as an item
73
83
}
74
84
75
85
@ Override
@@ -84,7 +94,7 @@ public Sprite getParticleSprite() {
84
94
85
95
@ Override
86
96
public ModelTransformation getTransformation () {
87
- return ModelTransformation . NONE ;
97
+ return ModelHelper . MODEL_TRANSFORM_BLOCK ;
88
98
}
89
99
90
100
@ Override
@@ -112,27 +122,71 @@ public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos
112
122
return ; // No inner block to render
113
123
}
114
124
115
- Sprite sprite = MinecraftClient .getInstance ().getBlockRenderManager ().getModels ().getModelManager ().getBlockModels ().getModelParticleSprite (data .getDefaultState ());
116
- QuadEmitter emitter = context .getEmitter ();
117
-
118
- // We can emit our quads outside of the mesh as the block being put in the frame is very much dynamic.
119
- // Emit the quads for each face of the block inside the frame
120
- for (Direction direction : Direction .values ()) {
121
- // Add a face, with an inset to give the appearance of the block being in a frame.
122
- emitter .square (direction , 0.1F , 0.1F , 0.9F , 0.9F , 0.1F )
123
- // Set the sprite of the fact, use whole texture via BAKE_LOCK_UV
124
- .spriteBake (0 , sprite , MutableQuadView .BAKE_LOCK_UV )
125
- // Allow textures
126
- // TODO: the magic values here are not documented at all and probably should be
127
- .spriteColor (0 , -1 , -1 , -1 , -1 )
128
- // Emit the quad
129
- .emit ();
130
- }
125
+ BlockState innerState = data .getDefaultState ();
126
+
127
+ // Now, we emit a transparent scaled-down version of the inner model
128
+ // Try both emissive and non-emissive versions of the translucent material
129
+ RenderMaterial material = pos .getX () % 2 == 0 ? translucentMaterial : translucentEmissiveMaterial ;
130
+
131
+ emitInnerQuads (context , material , () -> {
132
+ // Use emitBlockQuads to allow for Renderer API features
133
+ ((FabricBakedModel ) MinecraftClient .getInstance ().getBlockRenderManager ().getModel (innerState )).emitBlockQuads (blockView , innerState , pos , randomSupplier , context );
134
+ });
131
135
}
132
136
133
137
@ Override
134
138
public void emitItemQuads (ItemStack stack , Supplier <Random > randomSupplier , RenderContext context ) {
135
- // TODO: Implement an item test.
136
- // For now we will just leave this as I have not added a block item yet
139
+ // Emit our frame mesh
140
+ context .meshConsumer ().accept (this .frameMesh );
141
+
142
+ // Emit a scaled-down fence for testing, trying both materials again.
143
+ RenderMaterial material = stack .hasCustomName () ? translucentEmissiveMaterial : translucentMaterial ;
144
+
145
+ BlockState innerState = Blocks .OAK_FENCE .getDefaultState ();
146
+
147
+ emitInnerQuads (context , material , () -> {
148
+ // Need to use the fallback consumer directly:
149
+ // - we can't use emitBlockQuads because we don't have a blockView
150
+ // - we can't use emitItemQuads because multipart models don't have item quads
151
+ context .bakedModelConsumer ().accept (MinecraftClient .getInstance ().getBlockRenderManager ().getModel (innerState ), innerState );
152
+ });
153
+ }
154
+
155
+ /**
156
+ * Emit a scaled-down version of the inner model.
157
+ */
158
+ private void emitInnerQuads (RenderContext context , RenderMaterial material , Runnable innerModelEmitter ) {
159
+ // Let's push a transform to scale the model down and make it transparent
160
+ context .pushTransform (quad -> {
161
+ // Scale model down
162
+ for (int vertex = 0 ; vertex < 4 ; ++vertex ) {
163
+ float x = quad .x (vertex ) * 0.8f + 0.1f ;
164
+ float y = quad .y (vertex ) * 0.8f + 0.1f ;
165
+ float z = quad .z (vertex ) * 0.8f + 0.1f ;
166
+ quad .pos (vertex , x , y , z );
167
+ }
168
+
169
+ // Make the quad partially transparent
170
+ // Change material to translucent
171
+ quad .material (material );
172
+
173
+ // Change vertex colors to be partially transparent
174
+ for (int vertex = 0 ; vertex < 4 ; ++vertex ) {
175
+ int color = quad .spriteColor (vertex , 0 );
176
+ int alpha = (color >> 24 ) & 0xFF ;
177
+ alpha = alpha * 3 / 4 ;
178
+ color = (color & 0xFFFFFF ) | (alpha << 24 );
179
+ quad .spriteColor (vertex , 0 , color );
180
+ }
181
+
182
+ // Return true because we want the quad to be rendered
183
+ return true ;
184
+ });
185
+
186
+ // Emit the inner block model
187
+ innerModelEmitter .run ();
188
+
189
+ // Let's not forget to pop the transform!
190
+ context .popTransform ();
137
191
}
138
192
}
0 commit comments