vazkii.botania.client.render.world.SkyblockSkyRenderer.java Source code

Java tutorial

Introduction

Here is the source code for vazkii.botania.client.render.world.SkyblockSkyRenderer.java

Source

/**
 * This class was created by <Vazkii>. It's distributed as
 * part of the Botania Mod. Get the Source Code in github:
 * https://github.com/Vazkii/Botania
 *
 * Botania is Open Source and distributed under the
 * Botania License: http://botaniamod.net/license.php
 *
 * File Created @ [18/12/2015, 02:06:56 (GMT)]
 */
package vazkii.botania.client.render.world;

import java.util.Random;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.IRenderHandler;
import vazkii.botania.client.core.handler.ClientMethodHandles;
import vazkii.botania.client.core.handler.ClientTickHandler;
import vazkii.botania.client.lib.LibResources;

public class SkyblockSkyRenderer extends IRenderHandler {

    private static final ResourceLocation textureSkybox = new ResourceLocation(LibResources.MISC_SKYBOX);
    private static final ResourceLocation textureRainbow = new ResourceLocation(LibResources.MISC_RAINBOW);
    private static final ResourceLocation MOON_PHASES_TEXTURES = new ResourceLocation(
            "textures/environment/moon_phases.png");
    private static final ResourceLocation SUN_TEXTURES = new ResourceLocation("textures/environment/sun.png");
    private static final ResourceLocation[] planetTextures = new ResourceLocation[] {
            new ResourceLocation(LibResources.MISC_PLANET + "0.png"),
            new ResourceLocation(LibResources.MISC_PLANET + "1.png"),
            new ResourceLocation(LibResources.MISC_PLANET + "2.png"),
            new ResourceLocation(LibResources.MISC_PLANET + "3.png"),
            new ResourceLocation(LibResources.MISC_PLANET + "4.png"),
            new ResourceLocation(LibResources.MISC_PLANET + "5.png") };

    // Copy of overworld section of RenderGlobal.renderSky(), heavily modified
    @Override
    public void render(float partialTicks, WorldClient world, Minecraft mc) {
        // Environment setup
        int glSkyList;
        net.minecraft.client.renderer.vertex.VertexBuffer skyVBO;

        try {
            glSkyList = (int) ClientMethodHandles.glSkyList_getter.invokeExact(mc.renderGlobal);
            skyVBO = (net.minecraft.client.renderer.vertex.VertexBuffer) ClientMethodHandles.skyVBO_getter
                    .invokeExact(mc.renderGlobal);
        } catch (Throwable t) {
            return;
        }

        // Begin
        GlStateManager.disableTexture2D();
        Vec3d vec3d = world.getSkyColor(mc.getRenderViewEntity(), partialTicks);
        float f = (float) vec3d.xCoord;
        float f1 = (float) vec3d.yCoord;
        float f2 = (float) vec3d.zCoord;

        // Botania - darken when in void
        float insideVoid = 0;
        if (mc.thePlayer.posY <= -2)
            insideVoid = (float) Math.min(1F, -(mc.thePlayer.posY + 2) / 30F);

        f = Math.max(0F, f - insideVoid);
        f1 = Math.max(0F, f1 - insideVoid);
        f2 = Math.max(0F, f2 - insideVoid);

        /*if (pass != 2) Botania - no anaglyph stuff
        {
           float f3 = (f * 30.0F + f1 * 59.0F + f2 * 11.0F) / 100.0F;
           float f4 = (f * 30.0F + f1 * 70.0F) / 100.0F;
           float f5 = (f * 30.0F + f2 * 70.0F) / 100.0F;
           f = f3;
           f1 = f4;
           f2 = f5;
        }*/

        GlStateManager.color(f, f1, f2);
        Tessellator tessellator = Tessellator.getInstance();
        VertexBuffer vertexbuffer = tessellator.getBuffer();
        GlStateManager.depthMask(false);
        GlStateManager.enableFog();
        GlStateManager.color(f, f1, f2);

        if (OpenGlHelper.useVbo()) {
            skyVBO.bindBuffer();
            GlStateManager.glEnableClientState(32884);
            GlStateManager.glVertexPointer(3, 5126, 12, 0);
            skyVBO.drawArrays(7);
            skyVBO.unbindBuffer();
            GlStateManager.glDisableClientState(32884);
        } else {
            GlStateManager.callList(glSkyList);
        }

        GlStateManager.disableFog();
        GlStateManager.disableAlpha();
        GlStateManager.enableBlend();
        GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA,
                GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE,
                GlStateManager.DestFactor.ZERO);
        RenderHelper.disableStandardItemLighting();
        float[] afloat = world.provider.calcSunriseSunsetColors(world.getCelestialAngle(partialTicks),
                partialTicks);

        if (afloat != null) {
            GlStateManager.disableTexture2D();
            GlStateManager.shadeModel(7425);
            GlStateManager.pushMatrix();
            GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
            GlStateManager.rotate(
                    MathHelper.sin(world.getCelestialAngleRadians(partialTicks)) < 0.0F ? 180.0F : 0.0F, 0.0F, 0.0F,
                    1.0F);
            GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F);
            float f6 = afloat[0];
            float f7 = afloat[1];
            float f8 = afloat[2];

            /*if (pass != 2) Botania - no anaglyph stuff
            {
               float f9 = (f6 * 30.0F + f7 * 59.0F + f8 * 11.0F) / 100.0F;
               float f10 = (f6 * 30.0F + f7 * 70.0F) / 100.0F;
               float f11 = (f6 * 30.0F + f8 * 70.0F) / 100.0F;
               f6 = f9;
               f7 = f10;
               f8 = f11;
            }*/

            vertexbuffer.begin(6, DefaultVertexFormats.POSITION_COLOR);
            vertexbuffer.pos(0.0D, 100.0D, 0.0D).color(f6, f7, f8, afloat[3] * (1F - insideVoid)).endVertex(); // Botania - darken in void
            for (int l = 0; l <= 16; ++l) {
                float f21 = l * ((float) Math.PI * 2F) / 16.0F;
                float f12 = MathHelper.sin(f21);
                float f13 = MathHelper.cos(f21);
                vertexbuffer.pos(f12 * 120.0F, f13 * 120.0F, -f13 * 40.0F * afloat[3])
                        .color(afloat[0], afloat[1], afloat[2], 0.0F).endVertex();
            }

            tessellator.draw();
            GlStateManager.popMatrix();
            GlStateManager.shadeModel(7424);
        }

        GlStateManager.enableTexture2D();
        GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE,
                GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
        GlStateManager.pushMatrix();
        float f16 = 1.0F - world.getRainStrength(partialTicks);
        GlStateManager.color(1.0F, 1.0F, 1.0F, f16);
        GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F);

        float f17; // Botania - move declaration up from below "extra stuff"

        // Botania - Begin extra stuff
        float celAng = world.getCelestialAngle(partialTicks);
        float effCelAng = celAng;
        if (celAng > 0.5)
            effCelAng = 0.5F - (celAng - 0.5F);

        // === Planets
        f17 = 20F;
        float lowA = Math.max(0F, effCelAng - 0.3F) * f16;
        float a = Math.max(0.1F, lowA);

        GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
        GlStateManager.pushMatrix();
        GlStateManager.color(1F, 1F, 1F, a * 4 * (1F - insideVoid));
        GlStateManager.rotate(90F, 0.5F, 0.5F, 0.0F);
        for (int p = 0; p < planetTextures.length; p++) {
            mc.renderEngine.bindTexture(planetTextures[p]);
            tessellator.getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
            tessellator.getBuffer().pos(-f17, 100.0D, -f17).tex(0.0D, 0.0D).endVertex();
            tessellator.getBuffer().pos(f17, 100.0D, -f17).tex(1.0D, 0.0D).endVertex();
            tessellator.getBuffer().pos(f17, 100.0D, f17).tex(1.0D, 1.0D).endVertex();
            tessellator.getBuffer().pos(-f17, 100.0D, f17).tex(0.0D, 1.0D).endVertex();
            tessellator.draw();

            switch (p) {
            case 0:
                GlStateManager.rotate(70F, 1F, 0F, 0F);
                f17 = 12F;
                break;
            case 1:
                GlStateManager.rotate(120F, 0F, 0F, 1F);
                f17 = 15F;
                break;
            case 2:
                GlStateManager.rotate(80F, 1F, 0F, 1F);
                f17 = 25F;
                break;
            case 3:
                GlStateManager.rotate(100F, 0F, 0F, 1F);
                f17 = 10F;
                break;
            case 4:
                GlStateManager.rotate(-60F, 1F, 0F, 0.5F);
                f17 = 40F;
            }
        }
        GlStateManager.color(1F, 1F, 1F, 1F);
        GlStateManager.popMatrix();

        // === Rays
        mc.renderEngine.bindTexture(textureSkybox);

        f17 = 20F;
        a = lowA;
        GlStateManager.pushMatrix();
        GlStateManager.tryBlendFuncSeparate(770, 1, 1, 0);
        GlStateManager.translate(0F, -1F, 0F);
        GlStateManager.rotate(220F, 1F, 0F, 0F);
        GlStateManager.color(1F, 1F, 1F, a);
        int angles = 90;
        float y = 2F;
        float y0 = 0F;
        float uPer = 1F / 360F;
        float anglePer = 360F / angles;
        double fuzzPer = Math.PI * 10 / angles;
        float rotSpeed = 1F;
        float rotSpeedMod = 0.4F;

        for (int p = 0; p < 3; p++) {
            float baseAngle = rotSpeed * rotSpeedMod
                    * (ClientTickHandler.ticksInGame + ClientTickHandler.partialTicks);
            GlStateManager.rotate((ClientTickHandler.ticksInGame + ClientTickHandler.partialTicks) * 0.25F
                    * rotSpeed * rotSpeedMod, 0F, 1F, 0F);

            tessellator.getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
            for (int i = 0; i < angles; i++) {
                int j = i;
                if (i % 2 == 0)
                    j--;

                float ang = j * anglePer + baseAngle;
                double xp = Math.cos(ang * Math.PI / 180F) * f17;
                double zp = Math.sin(ang * Math.PI / 180F) * f17;
                double yo = Math.sin(fuzzPer * j) * 1;

                float ut = ang * uPer;
                if (i % 2 == 0) {
                    tessellator.getBuffer().pos(xp, yo + y0 + y, zp).tex(ut, 1F).endVertex();
                    tessellator.getBuffer().pos(xp, yo + y0, zp).tex(ut, 0).endVertex();
                } else {
                    tessellator.getBuffer().pos(xp, yo + y0, zp).tex(ut, 0).endVertex();
                    tessellator.getBuffer().pos(xp, yo + y0 + y, zp).tex(ut, 1F).endVertex();
                }

            }
            tessellator.draw();

            switch (p) {
            case 0:
                GlStateManager.rotate(20F, 1F, 0F, 0F);
                GlStateManager.color(1F, 0.4F, 0.4F, a);
                fuzzPer = Math.PI * 14 / angles;
                rotSpeed = 0.2F;
                break;
            case 1:
                GlStateManager.rotate(50F, 1F, 0F, 0F);
                GlStateManager.color(0.4F, 1F, 0.7F, a);
                fuzzPer = Math.PI * 6 / angles;
                rotSpeed = 2F;
                break;
            }
        }
        GlStateManager.popMatrix();

        // === Rainbow
        GlStateManager.pushMatrix();
        GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
        mc.renderEngine.bindTexture(textureRainbow);
        f17 = 10F;
        float effCelAng1 = celAng;
        if (effCelAng1 > 0.25F)
            effCelAng1 = 1F - effCelAng1;
        effCelAng1 = 0.25F - Math.min(0.25F, effCelAng1);

        long time = world.getWorldTime() + 1000;
        int day = (int) (time / 24000L);
        Random rand = new Random(day * 0xFF);
        float angle1 = rand.nextFloat() * 360F;
        float angle2 = rand.nextFloat() * 360F;
        GlStateManager.color(1F, 1F, 1F, effCelAng1 * (1F - insideVoid));
        GlStateManager.rotate(angle1, 0F, 1F, 0F);
        GlStateManager.rotate(angle2, 0F, 0F, 1F);

        tessellator.getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
        for (int i = 0; i < angles; i++) {
            int j = i;
            if (i % 2 == 0)
                j--;

            float ang = j * anglePer;
            double xp = Math.cos(ang * Math.PI / 180F) * f17;
            double zp = Math.sin(ang * Math.PI / 180F) * f17;
            double yo = 0;

            float ut = ang * uPer;
            if (i % 2 == 0) {
                tessellator.getBuffer().pos(xp, yo + y0 + y, zp).tex(ut, 1F).endVertex();
                tessellator.getBuffer().pos(xp, yo + y0, zp).tex(ut, 0).endVertex();
            } else {
                tessellator.getBuffer().pos(xp, yo + y0, zp).tex(ut, 0).endVertex();
                tessellator.getBuffer().pos(xp, yo + y0 + y, zp).tex(ut, 1F).endVertex();
            }

        }
        tessellator.draw();
        GlStateManager.popMatrix();
        GlStateManager.color(1F, 1F, 1F, 1F - insideVoid);
        GlStateManager.tryBlendFuncSeparate(770, 1, 1, 0);
        // Botania - End extra stuff

        GlStateManager.rotate(world.getCelestialAngle(partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F);
        /*float*/ f17 = 60.0F; // Botania - 30 -> 60 and move declaration above "extra stuff"
        mc.renderEngine.bindTexture(SUN_TEXTURES);
        vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX);
        vertexbuffer.pos(-f17, 100.0D, -f17).tex(0.0D, 0.0D).endVertex();
        vertexbuffer.pos(f17, 100.0D, -f17).tex(1.0D, 0.0D).endVertex();
        vertexbuffer.pos(f17, 100.0D, f17).tex(1.0D, 1.0D).endVertex();
        vertexbuffer.pos(-f17, 100.0D, f17).tex(0.0D, 1.0D).endVertex();
        tessellator.draw();
        f17 = 60.0F; // Botania - 20 -> 60
        mc.renderEngine.bindTexture(MOON_PHASES_TEXTURES);
        int i = world.getMoonPhase();
        int k = i % 4;
        int i1 = i / 4 % 2;
        float f22 = (k + 0) / 4.0F;
        float f23 = (i1 + 0) / 2.0F;
        float f24 = (k + 1) / 4.0F;
        float f14 = (i1 + 1) / 2.0F;
        vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX);
        vertexbuffer.pos(-f17, -100.0D, f17).tex(f24, f14).endVertex();
        vertexbuffer.pos(f17, -100.0D, f17).tex(f22, f14).endVertex();
        vertexbuffer.pos(f17, -100.0D, -f17).tex(f22, f23).endVertex();
        vertexbuffer.pos(-f17, -100.0D, -f17).tex(f24, f23).endVertex();
        tessellator.draw();
        GlStateManager.disableTexture2D();
        // Botania - Custom star rendering
        {
            f16 *= Math.max(0.1F, effCelAng * 2);
            renderStars(mc, f16, partialTicks);
        }
        /*float f15 = this.theWorld.getStarBrightness(partialTicks) * f16;
            
        if (f15 > 0.0F)
        {
           GlStateManager.color(f15, f15, f15, f15);
            
           if (this.vboEnabled)
           {
        this.starVBO.bindBuffer();
        GlStateManager.glEnableClientState(32884);
        GlStateManager.glVertexPointer(3, 5126, 12, 0);
        this.starVBO.drawArrays(7);
        this.starVBO.unbindBuffer();
        GlStateManager.glDisableClientState(32884);
           }
           else
           {
        GlStateManager.callList(this.starGLCallList);
           }
        }*/

        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        GlStateManager.disableBlend();
        GlStateManager.enableAlpha();
        GlStateManager.enableFog();
        GlStateManager.popMatrix();
        // Botania - no horizon rendering
        /* GlStateManager.disableTexture2D();
        GlStateManager.color(0.0F, 0.0F, 0.0F);
        double d0 = this.mc.thePlayer.getPositionEyes(partialTicks).yCoord - this.theWorld.getHorizon();
            
        if (d0 < 0.0D)
        {
           GlStateManager.pushMatrix();
           GlStateManager.translate(0.0F, 12.0F, 0.0F);
            
           if (this.vboEnabled)
           {
        this.sky2VBO.bindBuffer();
        GlStateManager.glEnableClientState(32884);
        GlStateManager.glVertexPointer(3, 5126, 12, 0);
        this.sky2VBO.drawArrays(7);
        this.sky2VBO.unbindBuffer();
        GlStateManager.glDisableClientState(32884);
           }
           else
           {
        GlStateManager.callList(this.glSkyList2);
           }
            
           GlStateManager.popMatrix();
           float f18 = 1.0F;
           float f19 = -((float)(d0 + 65.0D));
           float f20 = -1.0F;
           vertexbuffer.begin(7, DefaultVertexFormats.POSITION_COLOR);
           vertexbuffer.pos(-1.0D, (double)f19, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, (double)f19, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, (double)f19, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, (double)f19, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, (double)f19, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, (double)f19, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, (double)f19, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, (double)f19, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(-1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
           vertexbuffer.pos(1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex();
           tessellator.draw();
        }
            
        if (this.theWorld.provider.isSkyColored())
        {
           GlStateManager.color(f * 0.2F + 0.04F, f1 * 0.2F + 0.04F, f2 * 0.6F + 0.1F);
        }
        else
        {
           GlStateManager.color(f, f1, f2);
        }
            
        GlStateManager.pushMatrix();
        GlStateManager.translate(0.0F, -((float)(d0 - 16.0D)), 0.0F);
        GlStateManager.callList(this.glSkyList2);
        GlStateManager.popMatrix();*/
        GlStateManager.enableTexture2D();
        GlStateManager.depthMask(true);
    }

    private void renderStars(Minecraft mc, float alpha, float partialTicks) {
        int starGLCallList;
        net.minecraft.client.renderer.vertex.VertexBuffer starVBO;

        try {
            starGLCallList = (int) ClientMethodHandles.starGLCallList_getter.invokeExact(mc.renderGlobal);
            starVBO = (net.minecraft.client.renderer.vertex.VertexBuffer) ClientMethodHandles.starVBO_getter
                    .invokeExact(mc.renderGlobal);
        } catch (Throwable t) {
            return;
        }

        float t = (ClientTickHandler.ticksInGame + partialTicks + 2000) * 0.005F;
        GlStateManager.pushMatrix();

        GlStateManager.pushMatrix();
        GlStateManager.rotate(t * 3, 0F, 1F, 0F);
        GlStateManager.color(1F, 1F, 1F, alpha);
        drawVboOrList(starVBO, starGLCallList);
        GlStateManager.popMatrix();

        GlStateManager.pushMatrix();
        GlStateManager.rotate(t, 0F, 1F, 0F);
        GlStateManager.color(0.5F, 1F, 1F, alpha);
        drawVboOrList(starVBO, starGLCallList);
        GlStateManager.popMatrix();

        GlStateManager.pushMatrix();
        GlStateManager.rotate(t * 2, 0F, 1F, 0F);
        GlStateManager.color(1F, 0.75F, 0.75F, alpha);
        drawVboOrList(starVBO, starGLCallList);
        GlStateManager.popMatrix();

        GlStateManager.pushMatrix();
        GlStateManager.rotate(t * 3, 0F, 0F, 1F);
        GlStateManager.color(1F, 1F, 1F, 0.25F * alpha);
        drawVboOrList(starVBO, starGLCallList);
        GlStateManager.popMatrix();

        GlStateManager.pushMatrix();
        GlStateManager.rotate(t, 0F, 0F, 1F);
        GlStateManager.color(0.5F, 1F, 1F, 0.25F * alpha);
        drawVboOrList(starVBO, starGLCallList);
        GlStateManager.popMatrix();

        GlStateManager.pushMatrix();
        GlStateManager.rotate(t * 2, 0F, 0F, 1F);
        GlStateManager.color(1F, 0.75F, 0.75F, 0.25F * alpha);
        drawVboOrList(starVBO, starGLCallList);
        GlStateManager.popMatrix();

        GlStateManager.popMatrix();
    }

    // Excised from many occurences in RenderGlobal
    private void drawVboOrList(net.minecraft.client.renderer.vertex.VertexBuffer vbo, int displayList) {
        if (OpenGlHelper.useVbo()) {
            vbo.bindBuffer();
            GlStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
            GlStateManager.glVertexPointer(3, GL11.GL_FLOAT, 12, 0);
            vbo.drawArrays(GL11.GL_QUADS);
            vbo.unbindBuffer();
            GlStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
        } else {
            GlStateManager.callList(displayList);
        }
    }

}