Last active
April 18, 2025 22:29
-
-
Save lowercasebtw/50884139e0def281d75db5f71a976082 to your computer and use it in GitHub Desktop.
MixinItemRenderer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.mojang.blaze3d.buffers.BufferType; | |
| import com.mojang.blaze3d.buffers.BufferUsage; | |
| import com.mojang.blaze3d.buffers.GpuBuffer; | |
| import com.mojang.blaze3d.pipeline.RenderPipeline; | |
| import com.mojang.blaze3d.pipeline.RenderTarget; | |
| import com.mojang.blaze3d.systems.RenderPass; | |
| import com.mojang.blaze3d.systems.RenderSystem; | |
| import com.mojang.blaze3d.textures.GpuTexture; | |
| import com.mojang.blaze3d.vertex.*; | |
| import net.minecraft.client.Minecraft; | |
| import net.minecraft.client.renderer.GameRenderer; | |
| import net.minecraft.client.renderer.MultiBufferSource; | |
| import net.minecraft.client.renderer.RenderPipelines; | |
| import net.minecraft.client.renderer.RenderType; | |
| import net.minecraft.client.renderer.block.model.BakedQuad; | |
| import net.minecraft.client.renderer.entity.ItemRenderer; | |
| import net.minecraft.client.renderer.item.ItemStackRenderState; | |
| import net.minecraft.client.renderer.texture.TextureAtlas; | |
| import net.minecraft.world.item.ItemDisplayContext; | |
| import org.spongepowered.asm.mixin.Mixin; | |
| import org.spongepowered.asm.mixin.Shadow; | |
| import org.spongepowered.asm.mixin.Unique; | |
| import org.spongepowered.asm.mixin.injection.At; | |
| import org.spongepowered.asm.mixin.injection.Inject; | |
| import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | |
| import java.util.List; | |
| import java.util.OptionalDouble; | |
| import java.util.OptionalInt; | |
| import java.util.function.Consumer; | |
| @Mixin(ItemRenderer.class) | |
| public abstract class MixinItemRenderer { | |
| @Shadow | |
| private static void renderQuadList( | |
| PoseStack poseStack, | |
| VertexConsumer vertexConsumer, | |
| List<BakedQuad> list, | |
| int[] tints, | |
| int light, | |
| int color | |
| ) { | |
| } | |
| @Inject(method = "renderItem", at = @At("HEAD"), cancellable = true) | |
| private static void usePipelines( | |
| ItemDisplayContext itemDisplayContext, | |
| PoseStack poseStack, | |
| MultiBufferSource multiBufferSource, | |
| int light, | |
| int color, | |
| int[] tints, | |
| List<BakedQuad> bakedQuads, | |
| RenderType renderType, | |
| ItemStackRenderState.FoilType foilType, | |
| CallbackInfo ci | |
| ) { | |
| if (TheItemRenderPipelineMod.ENABLED) { | |
| ci.cancel(); | |
| // Note: Looked into using VertexMultiConsumer but couldn't as I couldn't get MeshData from it | |
| // as it was not a BufferBuilder. Also, the vertex formats between ITEM_ENTITY_TRANSLUCENT_CULL and GLINT are different, | |
| // so it'd prob cause issues. | |
| Consumer<VertexConsumer> renderQuadConsumer = (vertexConsumer) -> renderQuadList(poseStack, vertexConsumer, bakedQuads, tints, light, color); | |
| RenderTarget renderTarget = renderType.getRenderTarget(); | |
| renderItemLayer(RenderPipelines.ITEM_ENTITY_TRANSLUCENT_CULL, renderTarget, false, renderQuadConsumer); | |
| if (foilType != ItemStackRenderState.FoilType.NONE) { | |
| RenderStateShardAccessor.setupGlintTexturingMatrix(8.0F); | |
| renderItemLayer(RenderPipelines.GLINT, renderTarget, true, renderQuadConsumer); | |
| RenderSystem.resetTextureMatrix(); | |
| } | |
| } | |
| } | |
| // Ideally, to be like the more recent code, we'd need to know how many vertex's there are | |
| // and create a ByteBufferBuilder with the default format mode times the vertex count | |
| // instead of using Tesselator which I assume will soon be removed/phased out. | |
| // I.E: Example from SkyRenderer#init | |
| @Unique | |
| private static void renderItemLayer(RenderPipeline renderPipeline, RenderTarget renderTarget, boolean glint, Consumer<VertexConsumer> vertexConsumerConsumer) { | |
| BufferBuilder builder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, renderPipeline.getVertexFormat()); | |
| vertexConsumerConsumer.accept(builder); | |
| GpuBuffer buffer; | |
| int indexCount; | |
| try (MeshData meshData = builder.buildOrThrow()) { | |
| indexCount = meshData.drawState().indexCount(); | |
| buffer = RenderSystem.getDevice().createBuffer(() -> "Item Rendering", BufferType.VERTICES, BufferUsage.DYNAMIC_WRITE, meshData.vertexBuffer()); | |
| } | |
| GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; | |
| GpuTexture texture = Minecraft.getInstance().getTextureManager().getTexture(glint ? ItemRenderer.ENCHANTED_GLINT_ITEM : TextureAtlas.LOCATION_BLOCKS).getTexture(); | |
| RenderSystem.AutoStorageIndexBuffer indexBuffer = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS); | |
| try (RenderPass renderPass = RenderSystem.getDevice() | |
| .createCommandEncoder() | |
| .createRenderPass(renderTarget.getColorTexture(), OptionalInt.empty(), renderTarget.getDepthTexture(), OptionalDouble.empty())) { | |
| renderPass.setPipeline(renderPipeline); | |
| renderPass.setVertexBuffer(0, buffer); | |
| renderPass.setIndexBuffer(indexBuffer.getBuffer(indexCount), indexBuffer.type()); | |
| renderPass.bindSampler("Sampler0", texture); | |
| if (!glint) { | |
| renderPass.bindSampler("Sampler1", ((OverlayTextureAccessor) gameRenderer.overlayTexture()).getDynamicTexture().getTexture()); | |
| renderPass.bindSampler("Sampler2", gameRenderer.lightTexture().getTarget()); | |
| } | |
| renderPass.drawIndexed(0, indexCount); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment