de.kitsunealex.projectx.client.render.RenderTruncatedIcosahedron.java Source code

Java tutorial

Introduction

Here is the source code for de.kitsunealex.projectx.client.render.RenderTruncatedIcosahedron.java

Source

/*
 * This file is part of ProjectX.
 * Copyright (c) 2015 - 2018, KitsuneAlex, All rights reserved.
 *
 * ProjectX is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ProjectX is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with ProjectX.  If not, see <http://www.gnu.org/licenses/lgpl>.
 */

package de.kitsunealex.projectx.client.render;

import codechicken.lib.colour.Colour;
import codechicken.lib.colour.ColourRGBA;
import codechicken.lib.math.MathHelper;
import codechicken.lib.vec.Vector3;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;

@SideOnly(Side.CLIENT)
public class RenderTruncatedIcosahedron {

    private static final ThreadLocal<RenderTruncatedIcosahedron> INSTANCES = ThreadLocal
            .withInitial(RenderTruncatedIcosahedron::new);
    private static Vector3[] VERTS = new Vector3[60];
    private static int LIST_INDEX;

    private RenderTruncatedIcosahedron() {
        generate();
    }

    public void render(double size, int colourPent, int colourHex, EnumHedronTexture type) {
        this.render(size, new ColourRGBA(colourPent), new ColourRGBA(colourHex), type);
    }

    public void render(double size, Colour colourPent, Colour colourHex, EnumHedronTexture type) {
        GlStateManager.pushMatrix();
        GlStateManager.pushAttrib();
        GL11.glDisable(GL11.GL_LIGHTING);
        GL11.glDisable(GL11.GL_LIGHT0);
        GL11.glDisable(GL11.GL_LIGHT1);
        Minecraft.getMinecraft().getTextureManager().bindTexture(type.getTexture());
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glScaled(size * 0.1D, size * 0.1D, size * 0.1D);
        colourPent.glColour();
        GL11.glCallList(LIST_INDEX);
        colourHex.glColour();
        GL11.glCallList(LIST_INDEX + 1);
        GL11.glScaled(1D / (size * 0.1D), 1D / (size * 0.1D), 1D / (size * 0.1D));
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glEnable(GL11.GL_LIGHT1);
        GL11.glEnable(GL11.GL_LIGHT0);
        GL11.glDisable(GL11.GL_BLEND);
        GL11.glColor4f(1F, 1F, 1F, 1F);
        GlStateManager.popAttrib();
        GlStateManager.popMatrix();
    }

    private void generate() {
        int[] s = { 1, -1 };

        for (int i = 0; i < 4; i++) {
            VERTS[i] = new Vector3(0D, s[(i / 2)], s[(i % 2)] * 3 * MathHelper.phi);
        }

        for (int i = 0; i < 8; i++) {
            VERTS[(i + 4)] = new Vector3(s[(i / 4)] * 2, s[(i / 2 % 2)] * 4.2360679999999995D,
                    s[(i % 2)] * MathHelper.phi);
            VERTS[(i + 12)] = new Vector3(s[(i / 4)], s[(i / 2 % 2)] * 3.6180339999999998D,
                    s[(i % 2)] * 2 * MathHelper.phi);
        }

        for (int i = 0; i < 20; i++) {
            VERTS[(i + 20)] = new Vector3(VERTS[i].y, VERTS[i].z, VERTS[i].x);
            VERTS[(i + 40)] = new Vector3(VERTS[i].z, VERTS[i].x, VERTS[i].y);
        }

        LIST_INDEX = GL11.glGenLists(2);
        GL11.glNewList(LIST_INDEX, GL11.GL_COMPILE);
        GL11.glBegin(GL11.GL_LINE_BIT);

        for (int rot = 0; rot < 3; rot++) {
            for (int i = 0; i < 4; i++) {
                pentagon(rot, i);
            }
        }

        GL11.glEnd();
        GL11.glEndList();
        GL11.glNewList(LIST_INDEX + 1, GL11.GL_COMPILE);
        GL11.glBegin(GL11.GL_LINE_BIT);

        for (int rot = 0; rot < 3; rot++) {
            for (int i = 0; i < 4; i++) {
                hexagon1(rot, i);
            }
        }

        for (int i = 0; i < 8; i++) {
            hexagon2(i);
        }

        GL11.glEnd();
        GL11.glEndList();
    }

    private void renderShape(Vector3[] verts, boolean reverse) {
        Vector3 center = new Vector3();
        for (int i = 0; i < verts.length; i++) {
            center.add(verts[i]);
        }

        center.multiply(1D / verts.length);

        Vector3 prev = verts[0];
        int start = reverse ? verts.length : 1;
        int end = reverse ? -1 : verts.length + 1;
        int step = reverse ? -1 : 1;

        for (int i = start; i != end; i += step) {
            GL11.glTexCoord2d(0.5D, 0.5D);
            GL11.glVertex3d(center.x, center.y, center.z);
            GL11.glTexCoord2d(0D, 0D);
            GL11.glVertex3d(prev.x, prev.y, prev.z);
            GL11.glTexCoord2d(1D, 0D);
            GL11.glVertex3d(verts[(i % verts.length)].x, verts[(i % verts.length)].y, verts[(i % verts.length)].z);
            prev = verts[(i % verts.length)];
        }
    }

    private void pentagon(int rot, int i) {
        Vector3[] pentagon = new Vector3[5];
        pentagon[0] = VERTS[(rot * 20 + i)];
        pentagon[1] = VERTS[((rot * 20 + 2 * i + 44) % 60)];
        pentagon[2] = VERTS[((rot * 20 + i + 12) % 60)];
        pentagon[3] = VERTS[((rot * 20 + i + 16) % 60)];
        pentagon[4] = VERTS[((rot * 20 + 2 * i + 45) % 60)];
        renderShape(pentagon, (i != 0) && (i != 3));
    }

    private void hexagon1(int rot, int i) {
        Vector3[] hexagon = new Vector3[6];
        hexagon[0] = VERTS[(rot * 20 + i / 2)];
        hexagon[1] = VERTS[((rot * 20 + i + 44) % 60)];
        hexagon[2] = VERTS[((rot * 20 + i + 52) % 60)];
        hexagon[3] = VERTS[((rot * 20 + i + 56) % 60)];
        hexagon[4] = VERTS[((rot * 20 + i + 48) % 60)];
        hexagon[5] = VERTS[(rot * 20 + i / 2 + 2)];
        renderShape(hexagon, (i == 0) || (i == 3));
    }

    private void hexagon2(int i) {
        Vector3[] hexagon = new Vector3[6];
        hexagon[0] = VERTS[(4 + i)];
        hexagon[1] = VERTS[(12 + i)];
        hexagon[2] = VERTS[(44 + i / 4 + i % 4 * 2)];
        hexagon[3] = VERTS[(52 + i / 4 + i % 4 * 2)];
        hexagon[4] = VERTS[(24 + i / 2 + i % 2 * 4)];
        hexagon[5] = VERTS[(32 + i / 2 + i % 2 * 4)];
        renderShape(hexagon, (i % 3 != 0) && (i != 5));
    }

    public static RenderTruncatedIcosahedron getInstance() {
        return INSTANCES.get();
    }

}