aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/anthonyhilyard/iceberg/renderer/CustomItemRenderer.java
blob: b77bb09ae19cc6c32032b7fe6b53f52980d06938 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.anthonyhilyard.iceberg.renderer;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.pipeline.MainTarget;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.Lighting;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL11;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.texture.TextureManager;

import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.math.Matrix4f;

import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.ItemStack;

/**
 * An extended ItemRenderer that allows items to be rendered to RenderTarget before drawing to screen.  
 * This allows alpha values to be supported properly by all item types, even semi-transparent items.
 */
public class CustomItemRenderer extends ItemRenderer
{
	@SuppressWarnings("unused")
	private static final Logger LOGGER = LogManager.getLogger();

	private static RenderTarget iconFrameBuffer = null;
	private Minecraft mc;
	
	public CustomItemRenderer(TextureManager textureManagerIn, ModelManager modelManagerIn, ItemColors itemColorsIn, BlockEntityWithoutLevelRenderer blockEntityRendererIn, Minecraft mcIn)
	{
		super(textureManagerIn, modelManagerIn, itemColorsIn, blockEntityRendererIn);
		mc = mcIn;

		// Initialize the icon framebuffer if needed.
		if (iconFrameBuffer == null)
		{
			// Use 96 x 96 pixels for the icon frame buffer so at 1.5 scale we get 4x resolution (for smooth icons on larger gui scales).
			iconFrameBuffer = new MainTarget(96, 96);
			iconFrameBuffer.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			iconFrameBuffer.clear(Minecraft.ON_OSX);
		}
	}

	public void renderItemModelIntoGUIWithAlpha(ItemStack stack, int x, int y, float alpha)
	{
		BakedModel bakedModel = mc.getItemRenderer().getModel(stack, null, null, 0);
		RenderTarget lastFrameBuffer = mc.getMainRenderTarget();

		// Bind the icon framebuffer so we can render to texture.
		iconFrameBuffer.clear(Minecraft.ON_OSX);
		iconFrameBuffer.bindWrite(true);

		RenderSystem.clear(GL11.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX);
		RenderSystem.backupProjectionMatrix();
		RenderSystem.setProjectionMatrix(Matrix4f.orthographic(0.0f, iconFrameBuffer.width, iconFrameBuffer.height, 0.0f, 1000.0f, 3000.0f));

		Lighting.setupFor3DItems();

		mc.getTextureManager().getTexture(InventoryMenu.BLOCK_ATLAS).setFilter(false, false);
		RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
		RenderSystem.enableBlend();
		RenderSystem.blendFuncSeparate(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
		RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);

		PoseStack modelViewStack = RenderSystem.getModelViewStack();
		modelViewStack.pushPose();
		modelViewStack.setIdentity();
		modelViewStack.translate(48.0f, 48.0f, -2000.0f);
		modelViewStack.scale(96.0F, 96.0F, 96.0F);
		RenderSystem.applyModelViewMatrix();
		PoseStack poseStack = new PoseStack();
		MultiBufferSource.BufferSource multibuffersource$buffersource = Minecraft.getInstance().renderBuffers().bufferSource();
		boolean flag = !bakedModel.usesBlockLight();
		if (flag) { Lighting.setupForFlatItems(); }

		render(stack, ItemTransforms.TransformType.GUI, false, poseStack, multibuffersource$buffersource, 0xF000F0, OverlayTexture.NO_OVERLAY, bakedModel);
		multibuffersource$buffersource.endBatch();
		RenderSystem.enableDepthTest();
		if (flag) { Lighting.setupFor3DItems(); }

		modelViewStack.popPose();
		RenderSystem.applyModelViewMatrix();
		RenderSystem.restoreProjectionMatrix();

		// Rebind the previous framebuffer, if there was one.
		if (lastFrameBuffer != null)
		{
			lastFrameBuffer.bindWrite(true);

			// Blit from the texture we just rendered to, respecting the alpha value given.
			RenderSystem.enableBlend();
			RenderSystem.defaultBlendFunc();
			RenderSystem.disableCull();
			RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha);
			modelViewStack.pushPose();
			modelViewStack.scale(1.0f, -1.0f, 1.0f);
			modelViewStack.translate(0.0f, 0.0f, 50.0f + this.blitOffset);
			RenderSystem.applyModelViewMatrix();

			RenderSystem.setShaderTexture(0, iconFrameBuffer.getColorTextureId());

			GuiComponent.blit(new PoseStack(), x, y - 18, 16, 16, 0, 0, iconFrameBuffer.width, iconFrameBuffer.height, iconFrameBuffer.width, iconFrameBuffer.height);
			modelViewStack.popPose();
			RenderSystem.applyModelViewMatrix();
			iconFrameBuffer.unbindRead();
		}
		else
		{
			iconFrameBuffer.unbindWrite();
		}
	 }
}