hellfirepvp.astralsorcery.client.render.tile.TESRTranslucentBlock.java Source code

Java tutorial

Introduction

Here is the source code for hellfirepvp.astralsorcery.client.render.tile.TESRTranslucentBlock.java

Source

/*******************************************************************************
 * HellFirePvP / Astral Sorcery 2017
 *
 * This project is licensed under GNU GENERAL PUBLIC LICENSE Version 3.
 * The source code is available on github: https://github.com/HellFirePvP/AstralSorcery
 * For further details, see the License file there.
 ******************************************************************************/

package hellfirepvp.astralsorcery.client.render.tile;

import hellfirepvp.astralsorcery.client.util.Blending;
import hellfirepvp.astralsorcery.client.util.RenderingUtils;
import hellfirepvp.astralsorcery.client.util.TextureHelper;
import hellfirepvp.astralsorcery.common.tile.TileTranslucent;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.lwjgl.opengl.GL11;

import java.util.LinkedList;
import java.util.List;

/**
 * This class is part of the Astral Sorcery Mod
 * The complete source code for this mod can be found on github.
 * Class: TESRTranslucentBlock
 * Created by HellFirePvP
 * Date: 17.01.2017 / 03:57
 */
public class TESRTranslucentBlock extends TileEntitySpecialRenderer<TileTranslucent> {

    protected static final List<TranslucentBlockState> blocks = new LinkedList<>();
    private static int hash = -1;
    private static int batchDList = -1;

    public static void renderTranslucentBlocks() {
        TextureHelper.refreshTextureBindState();
        TextureHelper.setActiveTextureToAtlasSprite();
        GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
        GL11.glPushMatrix();
        RenderingUtils.removeStandartTranslationFromTESRMatrix(Minecraft.getMinecraft().getRenderPartialTicks());
        GlStateManager.color(1F, 1F, 1F, 1F);

        if (batchDList == -1) {
            batchBlocks();
            hash = hashBlocks();
            blocks.clear();
        } else {
            int currentHash = hashBlocks();
            if (hash != currentHash) {
                GLAllocation.deleteDisplayLists(batchDList);
                batchBlocks();
                hash = currentHash;
                blocks.clear();
            }
        }
        GL11.glEnable(GL11.GL_BLEND);
        Blending.ADDITIVEDARK.apply();
        GL11.glCallList(batchDList);
        blocks.clear();
        Blending.DEFAULT.apply();
        GL11.glPopMatrix();
        GL11.glPopAttrib();
    }

    private static void batchBlocks() {
        World w = Minecraft.getMinecraft().world;
        batchDList = GLAllocation.generateDisplayLists(1);
        GL11.glEnable(GL11.GL_BLEND);
        Blending.ADDITIVEDARK.apply();
        GL11.glNewList(batchDList, GL11.GL_COMPILE);
        Tessellator tes = Tessellator.getInstance();
        VertexBuffer vb = tes.getBuffer();
        vb.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
        for (TranslucentBlockState tbs : blocks) {
            Minecraft.getMinecraft().getBlockRendererDispatcher().renderBlock(tbs.state, tbs.pos, w, vb);
        }
        tes.draw();
        GL11.glEndList();
        Blending.DEFAULT.apply();
    }

    private static int hashBlocks() {
        int hash = 80238287;
        for (TranslucentBlockState tbs : blocks) {
            hash = (hash << 4) ^ (hash >> 28) ^ (tbs.pos.getX() * 5449 % 130651);
            hash = (hash << 4) ^ (hash >> 28) ^ (tbs.pos.getY() * 5449 % 130651);
            hash = (hash << 4) ^ (hash >> 28) ^ (tbs.pos.getZ() * 5449 % 130651);
            hash = (hash << 4) ^ (hash >> 28) ^ (tbs.state.hashCode() * 5449 % 130651);
        }
        return hash % 75327403;
    }

    public static void cleanUp() {
        hash = -1;
        if (batchDList != -1) {
            GLAllocation.deleteDisplayLists(batchDList);
            batchDList = -1;
        }
    }

    @Override
    public void renderTileEntityAt(TileTranslucent te, double x, double y, double z, float partialTicks,
            int destroyStage) {
        if (te.getFakedState() == null)
            return;
        IBlockState renderState = te.getFakedState();
        TESRTranslucentBlock.blocks.add(new TESRTranslucentBlock.TranslucentBlockState(renderState, te.getPos()));
    }

    public static class TranslucentBlockState {

        public final IBlockState state;
        public final BlockPos pos;

        public TranslucentBlockState(IBlockState state, BlockPos pos) {
            this.state = state;
            this.pos = pos;
        }

    }

}