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

Java tutorial

Introduction

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

Source

/*
 * BluSunrize
 * Copyright (c) 2018
 *
 * 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.ShaderCase.ShaderLayer;
import blusunrize.immersiveengineering.common.util.IELogger;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.io.IOUtils;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.function.IntFunction;

@SideOnly(Side.CLIENT)
public class IEShaderLayerCompositeTexture extends AbstractTexture {
    /**
     * The location of the texture.
     */
    private final ResourceLocation canvasTexture;
    private final ShaderLayer[] layers;

    public IEShaderLayerCompositeTexture(ResourceLocation canvasTexture, ShaderLayer[] layers) {
        this.canvasTexture = canvasTexture;
        this.layers = layers;
    }

    @Override
    public void loadTexture(IResourceManager resourceManager) {
        this.deleteGlTexture();
        IResource iresource = null;
        BufferedImage bufferedimage;
        BufferedImage scaledImage;
        label255: {
            try {
                iresource = resourceManager.getResource(this.canvasTexture);
                BufferedImage canvasImage = TextureUtil.readBufferedImage(iresource.getInputStream());
                int imageType = canvasImage.getType();
                if (imageType == 0)
                    imageType = 6;
                int canvasWidth = canvasImage.getWidth();
                int canvasHeight = canvasImage.getHeight();

                bufferedimage = new BufferedImage(canvasWidth, canvasHeight, imageType);
                int layer = 0;

                while (true) {
                    if (layer >= 17 || layer >= this.layers.length)
                        break label255;

                    IResource iresource1 = null;

                    try {
                        String texPath = this.layers[layer].getTexture().getPath();

                        if (!texPath.startsWith("textures/"))
                            texPath = "textures/" + texPath;
                        if (!texPath.endsWith(".png"))
                            texPath += ".png";
                        String texture = this.layers[layer].getTexture().getNamespace() + ":" + texPath;
                        int colour = this.layers[layer].getColour();

                        iresource1 = resourceManager.getResource(new ResourceLocation(texture));
                        BufferedImage texureImage = TextureUtil.readBufferedImage(iresource1.getInputStream());

                        scaledImage = new BufferedImage(canvasWidth, canvasHeight, imageType);

                        float[] mod = { (colour >> 16 & 255) / 255f, (colour >> 8 & 255) / 255f,
                                (colour & 255) / 255f, (colour >> 24 & 255) / 255f };

                        IntFunction<Integer> uInterpolate = uIn -> uIn;
                        IntFunction<Integer> vInterpolate = vIn -> vIn;

                        int bufImg2Size = Math.min(texureImage.getWidth(), texureImage.getHeight());

                        int uMin = 0;
                        int vMin = 0;
                        int uMax = canvasWidth;
                        int vMax = canvasHeight;

                        final double[] texBounds = this.layers[layer].getTextureBounds();
                        if (texBounds != null) {
                            final double uOffset = texBounds[0] * canvasWidth;
                            final double vOffset = texBounds[1] * canvasHeight;
                            final double uScale = bufImg2Size / ((texBounds[2] - texBounds[0]) * canvasWidth);
                            final double vScale = bufImg2Size / ((texBounds[3] - texBounds[1]) * canvasHeight);
                            uInterpolate = uIn -> (int) Math.round((uIn - uOffset) * uScale);
                            vInterpolate = vIn -> (int) Math.round((vIn - vOffset) * vScale);
                            uMin = (int) uOffset;
                            vMin = (int) vOffset;
                            uMax = (int) (texBounds[2] * canvasWidth);
                            vMax = (int) (texBounds[3] * canvasHeight);
                        }

                        try {
                            for (int v = vMin; v < vMax; ++v)
                                for (int u = uMin; u < uMax; ++u) {
                                    int interU = uInterpolate.apply(u) % bufImg2Size;
                                    int interV = vInterpolate.apply(v) % bufImg2Size;

                                    int iRGB = texureImage.getRGB(interU, interV);

                                    float[] rgb = { (iRGB >> 16 & 255) / 255f, (iRGB >> 8 & 255) / 255f,
                                            (iRGB & 255) / 255f, (iRGB >> 24 & 255) / 255f };
                                    if ((iRGB & -16777216) != 0) {
                                        int iNoise = canvasImage.getRGB(u, v);
                                        float[] noise = { (iNoise >> 16 & 255) / 255f, (iNoise >> 8 & 255) / 255f,
                                                (iNoise & 255) / 255f, (iNoise >> 24 & 255) / 255f };

                                        for (int m = 0; m < 4; m++)
                                            rgb[m] = rgb[m] * mod[m] * noise[m];
                                        int[] irgb = { (int) (rgb[0] * 255), (int) (rgb[1] * 255),
                                                (int) (rgb[2] * 255), (int) (rgb[3] * 255) };

                                        int i2 = (irgb[0] << 16) + (irgb[1] << 8) + (irgb[2]) + (irgb[3] << 24);
                                        scaledImage.setRGB(u, v, i2);
                                    }
                                }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        bufferedimage.getGraphics().drawImage(scaledImage, 0, 0, null);
                    } finally {
                        IOUtils.closeQuietly(iresource1);
                    }

                    ++layer;
                }
            } catch (IOException ioexception) {
                IELogger.error("Couldn't load layered image", ioexception);
            } finally {
                IOUtils.closeQuietly(iresource);
            }

            return;
        }
        TextureUtil.uploadTextureImage(this.getGlTextureId(), bufferedimage);
    }
}