blusunrize.immersiveengineering.client.render.ItemRendererIEOBJ.java Source code

Java tutorial

Introduction

Here is the source code for blusunrize.immersiveengineering.client.render.ItemRendererIEOBJ.java

Source

/*
 * BluSunrize
 * Copyright (c) 2017
 *
 * This code is licensed under "Blu's License of Common Sense"
 * Details can be found in the license file in the root folder of this project
 */

package blusunrize.immersiveengineering.client.render;

import blusunrize.immersiveengineering.api.shader.CapabilityShader;
import blusunrize.immersiveengineering.api.shader.IShaderItem;
import blusunrize.immersiveengineering.api.shader.ShaderCase;
import blusunrize.immersiveengineering.api.shader.ShaderCase.ShaderLayer;
import blusunrize.immersiveengineering.client.ClientUtils;
import blusunrize.immersiveengineering.client.models.IESmartObjModel;
import blusunrize.immersiveengineering.client.models.IOBJModelCallback;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.client.model.obj.OBJModel;
import net.minecraftforge.client.model.pipeline.VertexBufferConsumer;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;

import java.nio.FloatBuffer;
import java.util.*;
import java.util.stream.Collectors;

import static blusunrize.immersiveengineering.client.ClientUtils.mc;

public class ItemRendererIEOBJ extends TileEntityItemStackRenderer {
    public static final TileEntityItemStackRenderer INSTANCE = new ItemRendererIEOBJ();
    private static FloatBuffer transform = GLAllocation.createDirectFloatBuffer(16);
    private static final Matrix4 mat = new Matrix4();

    @Override
    public void renderByItem(ItemStack stack, float partialTicks) {
        GlStateManager.enableCull();
        partialTicks = mc().getRenderPartialTicks();
        if (stack.getItem() instanceof IOBJModelCallback) {
            IOBJModelCallback<ItemStack> callback = (IOBJModelCallback<ItemStack>) stack.getItem();
            World w = IESmartObjModel.tempEntityStatic != null ? IESmartObjModel.tempEntityStatic.world : null;
            IBakedModel model = mc().getRenderItem().getItemModelWithOverrides(stack, w,
                    IESmartObjModel.tempEntityStatic);
            if (model instanceof IESmartObjModel) {
                GlStateManager.disableCull();

                ItemStack shader = ItemStack.EMPTY;
                ShaderCase sCase = null;
                if (!stack.isEmpty() && stack.hasCapability(CapabilityShader.SHADER_CAPABILITY, null)) {
                    CapabilityShader.ShaderWrapper wrapper = stack.getCapability(CapabilityShader.SHADER_CAPABILITY,
                            null);
                    if (wrapper != null) {
                        shader = wrapper.getShaderItem();
                        if (!shader.isEmpty() && shader.getItem() instanceof IShaderItem)
                            sCase = ((IShaderItem) shader.getItem()).getShaderCase(shader, stack,
                                    wrapper.getShaderType());
                    }
                }
                IESmartObjModel obj = (IESmartObjModel) model;
                Map<String, Boolean> visible = new HashMap<>(
                        ((OBJModel.OBJState) obj.getState()).getVisibilityMap());
                Tessellator tes = Tessellator.getInstance();
                BufferBuilder bb = tes.getBuffer();
                ItemCameraTransforms.TransformType transformType = obj.lastCameraTransform;
                List<Pair<BakedQuad, ShaderLayer>> quads = new ArrayList<>();
                for (String[] groups : callback.getSpecialGroups(stack, transformType,
                        IESmartObjModel.tempEntityStatic)) {
                    GlStateManager.pushMatrix();
                    Matrix4 mat = callback.getTransformForGroups(stack, groups, transformType, mc().player,
                            ItemRendererIEOBJ.mat, partialTicks);
                    GlStateManager.multMatrix(mat.toFloatBuffer(transform));
                    boolean wasLightmapEnabled, wasLightingEnabled;
                    {
                        GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit);
                        wasLightmapEnabled = GL11.glIsEnabled(GL11.GL_TEXTURE_2D);
                        GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
                        wasLightingEnabled = GL11.glIsEnabled(GL11.GL_LIGHTING);
                    }
                    boolean bright = callback.areGroupsFullbright(stack, groups);
                    if (bright) {
                        GlStateManager.disableLighting();
                        ClientUtils.setLightmapDisabled(true);
                    }
                    renderQuadsForGroups(groups, callback, obj, quads, stack, sCase, shader, bb, tes, visible,
                            partialTicks);
                    if (bright) {
                        if (wasLightingEnabled)
                            GlStateManager.enableLighting();
                        if (wasLightmapEnabled)
                            ClientUtils.setLightmapDisabled(false);
                    }
                    GlStateManager.popMatrix();
                }
                renderQuadsForGroups(visible.keySet().toArray(new String[0]), callback, obj, quads, stack, sCase,
                        shader, bb, tes, visible, partialTicks);
                GlStateManager.enableCull();
            }
        }
    }

    private void renderQuadsForGroups(String[] groups, IOBJModelCallback<ItemStack> callback, IESmartObjModel model,
            List<Pair<BakedQuad, ShaderLayer>> quadsForGroup, ItemStack stack, ShaderCase sCase, ItemStack shader,
            BufferBuilder bb, Tessellator tes, Map<String, Boolean> visible, float partialTicks) {
        quadsForGroup.clear();
        for (String g : groups) {
            if (visible.getOrDefault(g, Boolean.FALSE) && callback.shouldRenderGroup(stack, g))
                quadsForGroup.addAll(model.addQuadsForGroup(callback, stack, g, sCase, shader).stream()
                        .filter(Objects::nonNull).collect(Collectors.toList()));
            visible.remove(g);
        }
        if (!callback.areGroupsFullbright(stack, groups))
            bb.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM);
        else
            bb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
        VertexBufferConsumer vbc = new VertexBufferConsumer(bb);
        ShaderLayer lastShaderLayer = null;
        for (Pair<BakedQuad, ShaderLayer> pair : quadsForGroup) {
            BakedQuad bq = pair.getKey();
            ShaderLayer layer = pair.getValue();
            //Switch to or between dynamic layers
            boolean switchDynamic = layer != lastShaderLayer;
            if (switchDynamic) {
                //interrupt batch
                tes.draw();

                if (lastShaderLayer != null)//finish dynamic call on last layer
                    lastShaderLayer.modifyRender(false, partialTicks);

                //set new layer
                lastShaderLayer = layer;

                if (lastShaderLayer != null)//start dynamic call on layer
                    lastShaderLayer.modifyRender(true, partialTicks);
                //start new batch
                if (!callback.areGroupsFullbright(stack, groups))
                    bb.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM);
                else
                    bb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);

            }
            bq.pipe(vbc);
        }
        tes.draw();
        if (lastShaderLayer != null)//finish dynamic call on final layer
            lastShaderLayer.modifyRender(false, partialTicks);

    }
}