Modernized Refinery Renderer

Also fixed tex bind issues, closes #792.

Additionally, I added a generic liquid display list renderer since there
really doesn't need to be one for each block.
This commit is contained in:
CovertJaguar 2013-04-27 16:51:53 -07:00
parent 019f40dfd3
commit 6596bb06fe
2 changed files with 222 additions and 141 deletions

View file

@ -0,0 +1,126 @@
/**
* Copyright (c) SpaceToad, 2011 http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public License
* 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.render;
import buildcraft.core.render.RenderEntityBlock.BlockInterface;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraftforge.liquids.LiquidStack;
import org.lwjgl.opengl.GL11;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.world.World;
/**
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
public class LiquidRenderer {
private static Map<LiquidStack, int[]> flowingRenderCache = new HashMap<LiquidStack, int[]>();
private static Map<LiquidStack, int[]> stillRenderCache = new HashMap<LiquidStack, int[]>();
public static final int DISPLAY_STAGES = 100;
private static final BlockInterface liquidBlock = new BlockInterface();
public static Icon getLiquidTexture(LiquidStack liquid) {
if (liquid == null || liquid.amount <= 0 || liquid.itemID <= 0) {
return null;
}
return liquid.canonical().getRenderingIcon();
}
public static String setupFlowingLiquidTexture(LiquidStack liquid, Icon[] texArray) {
if (liquid == null || liquid.amount <= 0 || liquid.itemID <= 0) {
return null;
}
ItemStack stack = liquid.asItemStack();
liquid = liquid.canonical();
String texSheet = liquid.getTextureSheet();
Icon top = liquid.getRenderingIcon();
Icon side = top;
if (stack.getItem() instanceof ItemBlock) {
top = Block.blocksList[stack.itemID].getIcon(0, 0);
side = Block.blocksList[stack.itemID].getIcon(2, 0);
texSheet = "/terrain.png";
}
texArray[0] = top;
texArray[1] = top;
texArray[2] = side;
texArray[3] = side;
texArray[4] = side;
texArray[5] = side;
return texSheet;
}
public static int[] getLiquidDisplayLists(LiquidStack liquid, World world, boolean flowing) {
if (liquid == null) {
return null;
}
liquid = liquid.canonical();
Map<LiquidStack, int[]> cache = flowing ? flowingRenderCache : stillRenderCache;
int[] diplayLists = cache.get(liquid);
if (diplayLists != null) {
return diplayLists;
}
diplayLists = new int[DISPLAY_STAGES];
if (liquid.itemID < Block.blocksList.length && Block.blocksList[liquid.itemID] != null) {
liquidBlock.baseBlock = Block.blocksList[liquid.itemID];
if (!flowing) {
liquidBlock.texture = liquid.getRenderingIcon();
}
} else if (Item.itemsList[liquid.itemID] != null) {
liquidBlock.baseBlock = Block.waterStill;
liquidBlock.texture = liquid.getRenderingIcon();
} else {
return null;
}
cache.put(liquid.canonical(), diplayLists);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_CULL_FACE);
ItemStack stack = liquid.asItemStack();
int color = stack.getItem().getColorFromItemStack(stack, 0);
float c1 = (float) (color >> 16 & 255) / 255.0F;
float c2 = (float) (color >> 8 & 255) / 255.0F;
float c3 = (float) (color & 255) / 255.0F;
GL11.glColor4f(c1, c2, c3, 1);
for (int s = 0; s < DISPLAY_STAGES; ++s) {
diplayLists[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(diplayLists[s], 4864 /*GL_COMPILE*/);
liquidBlock.minX = 0.01f;
liquidBlock.minY = 0;
liquidBlock.minZ = 0.01f;
liquidBlock.maxX = 0.99f;
liquidBlock.maxY = (float) s / (float) DISPLAY_STAGES;
liquidBlock.maxZ = 0.99f;
RenderEntityBlock.renderBlock(liquidBlock, world, 0, 0, 0, false, true);
GL11.glEndList();
}
GL11.glColor4f(1, 1, 1, 1);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_LIGHTING);
return diplayLists;
}
}

View file

@ -1,42 +1,31 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
* Copyright (c) SpaceToad, 2011 http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* BuildCraft is distributed under the terms of the Minecraft Mod Public License
* 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.factory.render;
import java.util.HashMap;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.Item;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import org.lwjgl.opengl.GL11;
import buildcraft.core.DefaultProps;
import buildcraft.core.IInventoryRenderer;
import buildcraft.core.render.RenderEntityBlock;
import buildcraft.core.render.RenderEntityBlock.BlockInterface;
import buildcraft.core.render.LiquidRenderer;
import buildcraft.factory.TileRefinery;
import net.minecraftforge.liquids.LiquidStack;
public class RenderRefinery extends TileEntitySpecialRenderer implements IInventoryRenderer {
static final float factor = (float) (1.0 / 16.0);
private static final float pixel = (float) (1.0 / 16.0);
private final ModelRenderer tank;
private final ModelRenderer magnet[] = new ModelRenderer[4];
private final ModelBase model = new ModelBase() {
};
@ -63,59 +52,6 @@ public class RenderRefinery extends TileEntitySpecialRenderer implements IInvent
setTileEntityRenderer(TileEntityRenderer.instance);
}
final static private int displayStages = 100;
private final HashMap<Integer, HashMap<Integer, int[]>> stage = new HashMap<Integer, HashMap<Integer, int[]>>();
private int[] getDisplayLists(int liquidId, int damage, World world) {
if (stage.containsKey(liquidId)) {
HashMap<Integer, int[]> x = stage.get(liquidId);
if (x.containsKey(damage))
return x.get(damage);
} else {
stage.put(liquidId, new HashMap<Integer, int[]>());
}
int[] d = new int[displayStages];
stage.get(liquidId).put(damage, d);
BlockInterface block = new BlockInterface();
String spriteSet = "/gui/items.png";
// Retrieve the texture depending on type of item.
if (liquidId < Block.blocksList.length && Block.blocksList[liquidId] != null) {
block.baseBlock = Block.blocksList[liquidId];
spriteSet = "/terrain.png";
} else if (Item.itemsList[liquidId] != null) {
block.baseBlock = Block.waterStill;
block.texture = Item.itemsList[liquidId].getIconFromDamage(damage);
} else
return null;
for (int s = 0; s < displayStages; ++s) {
d[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d[s], 4864 /* GL_COMPILE */);
Minecraft.getMinecraft().renderEngine.bindTexture(spriteSet);
block.minX = 0.5 - 4F * factor + 0.01;
block.minY = 0;
block.minZ = 0.5 - 4F * factor + 0.01;
block.maxX = 0.5 + 4F * factor - 0.01;
block.maxY = (float) s / (float) displayStages;
block.maxZ = 0.5 + 4F * factor - 0.01;
RenderEntityBlock.renderBlock(block, world, 0, 0, 0, false, true);
GL11.glEndList();
}
return d;
}
public RenderRefinery(String baseTexture) {
this();
}
@ -132,48 +68,40 @@ public class RenderRefinery extends TileEntitySpecialRenderer implements IInvent
}
private void render(TileRefinery tile, double x, double y, double z) {
LiquidStack liquid1 = null, liquid2 = null, liquidResult = null;
int liquid1 = 0, liquid2 = 0, liquid3 = 0;
int liquidMeta1 = 0, liquidMeta2 = 0, liquidMeta3 = 0;
int qty1 = 0, qty2 = 0, qty3 = 0;
float anim = 0;
int angle = 0;
ModelRenderer theMagnet = magnet[0];
if (tile != null) {
if (tile.ingredient1.getLiquid() != null) {
liquid1 = tile.ingredient1.getLiquid().itemID;
liquidMeta1 = tile.ingredient1.getLiquid().itemMeta;
qty1 = tile.ingredient1.getLiquid().amount;
liquid1 = tile.ingredient1.getLiquid();
}
if (tile.ingredient2.getLiquid() != null) {
liquid2 = tile.ingredient2.getLiquid().itemID;
liquidMeta2 = tile.ingredient2.getLiquid().itemMeta;
qty2 = tile.ingredient2.getLiquid().amount;
liquid2 = tile.ingredient2.getLiquid();
}
if (tile.result.getLiquid() != null) {
liquid3 = tile.result.getLiquid().itemID;
liquidMeta3 = tile.result.getLiquid().itemMeta;
qty3 = tile.result.getLiquid().amount;
liquidResult = tile.result.getLiquid();
}
anim = tile.getAnimationStage();
angle = 0;
switch (tile.worldObj.getBlockMetadata(tile.xCoord, tile.yCoord, tile.zCoord)) {
case 2:
angle = 90;
break;
case 3:
angle = 270;
break;
case 4:
angle = 180;
break;
case 5:
angle = 0;
break;
case 2:
angle = 90;
break;
case 3:
angle = 270;
break;
case 4:
angle = 180;
break;
case 5:
angle = 0;
break;
}
if (tile.animationSpeed <= 1) {
@ -185,83 +113,110 @@ public class RenderRefinery extends TileEntitySpecialRenderer implements IInvent
} else {
theMagnet = magnet[3];
}
}
GL11.glPushMatrix();
GL11.glDisable(2896 /* GL_LIGHTING */);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glTranslatef((float) x, (float) y, (float) z);
GL11.glTranslatef((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F);
GL11.glScalef(0.99F, 0.99F, 0.99F);
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
GL11.glRotatef(angle, 0, 1, 0);
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
bindTextureByName(DefaultProps.TEXTURE_PATH_BLOCKS + "/refinery.png");
GL11.glTranslatef(-4F * factor, 0, -4F * factor);
tank.render(factor);
GL11.glTranslatef(4F * factor, 0, 4F * factor);
GL11.glTranslatef(-4F * factor, 0, 4F * factor);
tank.render(factor);
GL11.glTranslatef(4F * factor, 0, -4F * factor);
GL11.glPushMatrix();
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
GL11.glTranslatef(-4F * pixel, 0, -4F * pixel);
tank.render(pixel);
GL11.glTranslatef(4F * pixel, 0, 4F * pixel);
GL11.glTranslatef(4F * factor, 0, 0);
tank.render(factor);
GL11.glTranslatef(-4F * factor, 0, 0);
GL11.glTranslatef(-4F * pixel, 0, 4F * pixel);
tank.render(pixel);
GL11.glTranslatef(4F * pixel, 0, -4F * pixel);
GL11.glTranslatef(4F * pixel, 0, 0);
tank.render(pixel);
GL11.glTranslatef(-4F * pixel, 0, 0);
GL11.glPopMatrix();
float trans1, trans2;
if (anim <= 100) {
trans1 = 12F * factor * anim / 100F;
trans1 = 12F * pixel * anim / 100F;
trans2 = 0;
} else if (anim <= 200) {
trans1 = 12F * factor - (12F * factor * (anim - 100F) / 100F);
trans2 = 12F * factor * (anim - 100F) / 100F;
trans1 = 12F * pixel - (12F * pixel * (anim - 100F) / 100F);
trans2 = 12F * pixel * (anim - 100F) / 100F;
} else {
trans1 = 12F * factor * (anim - 200F) / 100F;
trans2 = 12F * factor - (12F * factor * (anim - 200F) / 100F);
trans1 = 12F * pixel * (anim - 200F) / 100F;
trans2 = 12F * pixel - (12F * pixel * (anim - 200F) / 100F);
}
GL11.glTranslatef(0, trans1, 0);
theMagnet.render(factor);
GL11.glTranslatef(0, -trans1, 0);
GL11.glPushMatrix();
GL11.glScalef(0.99F, 0.99F, 0.99F);
GL11.glTranslatef(-0.51F, trans1 - 0.5F, -0.5F);
theMagnet.render(pixel);
GL11.glPopMatrix();
GL11.glTranslatef(0, trans2, 12F * factor);
theMagnet.render(factor);
GL11.glTranslatef(0, -trans2, -12F * factor);
GL11.glPushMatrix();
GL11.glScalef(0.99F, 0.99F, 0.99F);
GL11.glTranslatef(-0.51F, trans2 - 0.5F, 12F * pixel - 0.5F);
theMagnet.render(pixel);
GL11.glPopMatrix();
GL11.glTranslatef(-4F * factor, 0, -4F * factor);
if (qty1 > 0) {
int[] list1 = getDisplayLists(liquid1, liquidMeta1, tile.worldObj);
if (tile != null) {
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if (list1 != null) {
GL11.glCallList(list1[(int) ((float) qty1 / (float) TileRefinery.LIQUID_PER_SLOT * (displayStages - 1))]);
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
GL11.glScalef(0.5F, 1, 0.5F);
if (liquid1 != null && liquid1.amount > 0) {
int[] list1 = LiquidRenderer.getLiquidDisplayLists(liquid1, tile.worldObj, false);
if (list1 != null) {
GL11.glPushMatrix();
// GL11.glTranslatef(-0.5F, 0, -0.5F);
bindTextureByName(liquid1.canonical().getTextureSheet());
GL11.glCallList(list1[(int) ((float) liquid1.amount / (float) TileRefinery.LIQUID_PER_SLOT * (LiquidRenderer.DISPLAY_STAGES - 1))]);
GL11.glPopMatrix();
}
}
}
GL11.glTranslatef(4F * factor, 0, 4F * factor);
GL11.glTranslatef(-4F * factor, 0, 4F * factor);
if (qty2 > 0) {
int[] list2 = getDisplayLists(liquid2, liquidMeta2, tile.worldObj);
if (liquid2 != null && liquid2.amount > 0) {
int[] list2 = LiquidRenderer.getLiquidDisplayLists(liquid2, tile.worldObj, false);
if (list2 != null) {
GL11.glCallList(list2[(int) ((float) qty2 / (float) TileRefinery.LIQUID_PER_SLOT * (displayStages - 1))]);
if (list2 != null) {
GL11.glPushMatrix();
GL11.glTranslatef(0, 0, 1);
bindTextureByName(liquid2.canonical().getTextureSheet());
GL11.glCallList(list2[(int) ((float) liquid2.amount / (float) TileRefinery.LIQUID_PER_SLOT * (LiquidRenderer.DISPLAY_STAGES - 1))]);
GL11.glPopMatrix();
}
}
}
GL11.glTranslatef(4F * factor, 0, -4F * factor);
GL11.glTranslatef(4F * factor, 0, 0);
if (qty3 > 0) {
int[] list3 = getDisplayLists(liquid3, liquidMeta3, tile.worldObj);
if (list3 != null) {
GL11.glCallList(list3[(int) ((float) qty3 / (float) TileRefinery.LIQUID_PER_SLOT * (displayStages - 1))]);
if (liquidResult != null && liquidResult.amount > 0) {
int[] list3 = LiquidRenderer.getLiquidDisplayLists(liquidResult, tile.worldObj, false);
if (list3 != null) {
GL11.glPushMatrix();
GL11.glTranslatef(1, 0, 0.5F);
bindTextureByName(liquidResult.canonical().getTextureSheet());
GL11.glCallList(list3[(int) ((float) liquidResult.amount / (float) TileRefinery.LIQUID_PER_SLOT * (LiquidRenderer.DISPLAY_STAGES - 1))]);
GL11.glPopMatrix();
}
}
GL11.glPopAttrib();
}
GL11.glTranslatef(-4F * factor, 0, 0);
GL11.glEnable(2896 /* GL_LIGHTING */);
GL11.glPopAttrib();
GL11.glPopMatrix();
}
}