package blusunrize.immersiveengineering.api.shader; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import java.util.Collection; /** * @author BluSunrize - 29.10.2015 * Completely rewritten 29.10.2016 * * To be extended for ShaderCases all items, entities and whatever else you use them for<br> * Pre-configured ones exist (ShaderCaseRevolver.class) but when a new, shader-ready thing is implemented, it'll need a shadercase. */ public abstract class ShaderCase { /**An array of layers that this shader is comprised of.*/ protected ShaderLayer[] layers; protected ShaderCase(ShaderLayer... layers) { this.layers = layers; } protected ShaderCase(Collection<ShaderLayer> layers) { this.layers = layers.toArray(new ShaderLayer[layers.size()]); } public ShaderLayer[] getLayers() { return this.layers; } public ShaderCase addLayers(ShaderLayer... addedLayers) { ShaderLayer[] newLayers = new ShaderLayer[layers.length+addedLayers.length]; int insert = getLayerInsertionIndex(); System.arraycopy(this.layers,0, newLayers,0, insert); System.arraycopy(addedLayers,0, newLayers,insert, addedLayers.length); System.arraycopy(this.layers,insert, newLayers,insert+addedLayers.length, this.layers.length-insert); this.layers = newLayers; return this; } public abstract int getLayerInsertionIndex(); /** * @return if the given part of the model renders on the pass */ public abstract boolean renderModelPartForPass(ItemStack shader, ItemStack item, String modelPart, int pass); /** * @return A string representing which item this shader case applies to. e.g.: "immersiveengineering:revolver" */ public abstract String getShaderType(); /** * @return if the ResourceLocations of the layers should be stitched into the main texturemap<br> * defaults to true, since item and block textures are generally handled by that map<br * Minecarts return false here */ public boolean stitchIntoSheet() { return true; } /** * @return which icon is to be used for the given pass and model part. These obviously need to be stitched on the given sheet (mind the revolvers!) */ public ResourceLocation getReplacementSprite(ItemStack shader, ItemStack item, String modelPart, int pass) { return getLayers()[pass].getTexture(); } /** * @return the ARGB values to be appleid to the given part in the given pass */ public int getARGBColourModifier(ItemStack shader, ItemStack item, String modelPart, int pass) { return getLayers()[pass].getColour(); } /** * @param pre indicates whether this is before or after the part was rendered * @return make specific changes to the render, like GL calls */ public abstract void modifyRender(ItemStack shader, ItemStack item, String modelPart, int pass, boolean pre, boolean inventory); public static class ShaderLayer { /**A resource location pointing to a texture on the sheet*/ private final ResourceLocation texture; /**An ARGB formatted colour*/ private final int colour; /**An optional double array (uMin, vMin, uMax, vMax; values of 0-1) to define which part of the original texture is overriden<br> * The model will then only render faces who's coords lie within that limited space.<br> * Useful for keeping additional decorations (see Sponsor Shader) in smaller textures*/ private double[] textureBounds; /**An optional double array (uMin, vMin, uMax, vMax; values of 0-1) for the parts of the texture to be used.<br> * Useful when putting multiple shader textures into one file*/ private double[] cutoutBounds; public ShaderLayer(ResourceLocation texture, int colour) { this.texture = texture; this.colour = colour; } public ShaderLayer setTextureBounds(double... bounds) { if(bounds==null) return this; assert(bounds.length==4); this.textureBounds = bounds; return this; } /**@return An optional double array (uMin, vMin, uMax, vMax; values of 0-1) to define which part of the original texture is overriden<br> * The model will then only render faces who's coords lie within that limited space.<br> * Useful for keeping additional decorations (see Sponsor Shader) in smaller textures*/ public double[] getTextureBounds() { return this.textureBounds; } public ShaderLayer setCutoutBounds(double... bounds) { if(bounds==null) return this; assert(bounds.length==4); this.cutoutBounds = bounds; return this; } /** @return An optional double array (uMin, vMin, uMax, vMax; values of 0-1) for the parts of the texture to be used.<br> * Useful when putting multiple shader textures into one file*/ public double[] getCutoutBounds() { return this.cutoutBounds; } public ResourceLocation getTexture() { return texture; } public int getColour() { return colour; } } }