Fixed Liquid renderer

This was at one point in time the BuildCraft fluid renderer. However, i
have rewrote most of it in order to fix it. BuiltCraft staff is welcome
to take anything from the render code they want.
This commit is contained in:
DarkGuardsman 2013-07-18 14:32:31 -04:00
parent e3300615a6
commit 3d82011b96
4 changed files with 397 additions and 0 deletions

View file

@ -0,0 +1,56 @@
package dark.core.render;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import universalelectricity.core.vector.Vector3;
/** Used to store info on a block mainly used for rendering */
public class BlockRenderInfo
{
/** Block lower corner size */
public Vector3 min = new Vector3(0, 0, 0);
/** Block higher corner size */
public Vector3 max = new Vector3(1, 1, 1);
/** Block to pull info from */
public Block baseBlock = Block.sand;
/** Override render texture */
public Icon texture = null;
/** meta data to use for block the block */
public int meta = 0;
/** Gets the block brightness at the given location */
public float getBlockBrightness(IBlockAccess iblockaccess, int i, int j, int k)
{
return baseBlock.getBlockBrightness(iblockaccess, i, j, k);
}
/** Gets the block texture from the given side */
public Icon getBlockTextureFromSide(int side)
{
return this.getBlockIconFromSideAndMetadata(side, meta);
}
/** Gets the block texture from side and meta */
public Icon getBlockIconFromSideAndMetadata(int side, int meta)
{
return this.getIconSafe(baseBlock.getIcon(side, meta));
}
/** Gets the icon and does some safty checks */
public Icon getIconSafe(Icon par1Icon)
{
Icon icon = par1Icon;
if (this.texture != null)
{
icon = texture;
}
if (par1Icon == null)
{
icon = ((TextureMap) Minecraft.getMinecraft().func_110434_K().func_110581_b(TextureMap.field_110575_b)).func_110572_b("missingno");
}
return icon;
}
}

View file

@ -0,0 +1,99 @@
package dark.core.render;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class EntityFakeBlock extends Entity
{
@SideOnly(Side.CLIENT)
public Icon texture;
public float shadowSize = 0;
public float rotationX = 0;
public float rotationY = 0;
public float rotationZ = 0;
public double iSize, jSize, kSize;
private int brightness = -1;
public EntityFakeBlock(World world)
{
super(world);
preventEntitySpawning = false;
noClip = true;
isImmuneToFire = true;
}
public EntityFakeBlock(World world, double xPos, double yPos, double zPos)
{
super(world);
setPositionAndRotation(xPos, yPos, zPos, 0, 0);
}
public EntityFakeBlock(World world, double i, double j, double k, double iSize, double jSize, double kSize)
{
this(world);
this.iSize = iSize;
this.jSize = jSize;
this.kSize = kSize;
setPositionAndRotation(i, j, k, 0, 0);
this.motionX = 0.0;
this.motionY = 0.0;
this.motionZ = 0.0;
}
@Override
public void setPosition(double d, double d1, double d2)
{
super.setPosition(d, d1, d2);
boundingBox.minX = posX;
boundingBox.minY = posY;
boundingBox.minZ = posZ;
boundingBox.maxX = posX + iSize;
boundingBox.maxY = posY + jSize;
boundingBox.maxZ = posZ + kSize;
}
@Override
public void moveEntity(double d, double d1, double d2)
{
setPosition(posX + d, posY + d1, posZ + d2);
}
public void setBrightness(int brightness)
{
this.brightness = brightness;
}
@Override
protected void entityInit()
{
// TODO Auto-generated method stub
}
@Override
protected void readEntityFromNBT(NBTTagCompound data)
{
iSize = data.getDouble("iSize");
jSize = data.getDouble("jSize");
kSize = data.getDouble("kSize");
}
@Override
protected void writeEntityToNBT(NBTTagCompound data)
{
data.setDouble("iSize", iSize);
data.setDouble("jSize", jSize);
data.setDouble("kSize", kSize);
}
@Override
public int getBrightnessForRender(float par1)
{
return brightness > 0 ? brightness : super.getBrightnessForRender(par1);
}
}

View file

@ -0,0 +1,119 @@
package dark.core.render;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.Icon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
import universalelectricity.core.vector.Vector3;
/** @author CovertJaguar <railcraft.wikispaces.com> from BuildCraft , modified by DarkGuardsman */
public class FluidBlockRenderer
{
private static Map<Fluid, int[]> flowingRenderCache = new HashMap<Fluid, int[]>();
private static Map<Fluid, int[]> stillRenderCache = new HashMap<Fluid, int[]>();
public static final int DISPLAY_STAGES = 100;
private static final BlockRenderInfo liquidBlock = new BlockRenderInfo();
/** Gets the icon for the given fluid */
public static Icon getFluidTexture(Fluid fluid)
{
if (fluid == null)
{
return null;
}
Icon icon = fluid.getStillIcon();
if (icon == null)
{
Block block = Block.blocksList[fluid.getBlockID()];
if (block != null)
{
if (block.blockID == Block.waterStill.blockID)
{
icon = Block.waterStill.getIcon(0, 0);
}
if (block.blockID == Block.lavaStill.blockID)
{
icon = Block.lavaStill.getIcon(0, 0);
}
}
if (icon == null)
{
icon = Block.waterStill.getIcon(0, 0);
}
}
return icon;
}
/** Get the texture sheet used to bind textures to the render */
public static ResourceLocation getFluidSheet(FluidStack liquid)
{
return TextureMap.field_110575_b;
}
/** Gets the GL11 display list used to render the fluidStack as a block */
public static int[] getFluidDisplayLists(FluidStack fluidStack, World world, boolean flowing)
{
if (fluidStack == null || fluidStack.getFluid() == null)
{
return null;
}
Fluid fluid = fluidStack.getFluid();
Map<Fluid, int[]> cache = flowing ? flowingRenderCache : stillRenderCache;
int[] diplayLists = cache.get(fluid);
if (diplayLists != null)
{
return diplayLists;
}
diplayLists = new int[DISPLAY_STAGES];
liquidBlock.baseBlock = fluid.getBlockID() > 0 ? Block.blocksList[fluid.getBlockID()] : Block.waterStill;
liquidBlock.texture = getFluidTexture(fluid);
cache.put(fluid, diplayLists);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_CULL_FACE);
int color = fluid.getColor(fluidStack);
if (color != 0xFFFFFF)
{
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.min = new Vector3(0.01f, 0, 0.01f);
liquidBlock.max = new Vector3(0.99f, (float) s / (float) DISPLAY_STAGES, 0.99f);
RenderFakeBlock.INSTANCE.renderBlock(liquidBlock, world, 0, 0, 0);
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

@ -0,0 +1,123 @@
/**
* 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 dark.core.render;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import org.lwjgl.opengl.GL11;
import universalelectricity.core.vector.Vector3;
public class RenderFakeBlock extends Render
{
/** Render instance */
public static RenderFakeBlock INSTANCE = new RenderFakeBlock();
@Override
public void doRender(Entity entity, double i, double j, double k, float f, float f1)
{
doRenderBlock((EntityFakeBlock) entity, i, j, k);
}
/** Renders a block as an Entity */
public void doRenderBlock(EntityFakeBlock entity, double i, double j, double k)
{
if (entity.isDead)
{
return;
}
shadowSize = entity.shadowSize;
World world = entity.worldObj;
BlockRenderInfo util = new BlockRenderInfo();
util.texture = entity.texture;
func_110776_a(TextureMap.field_110575_b);
for (int iBase = 0; iBase < entity.iSize; ++iBase)
{
for (int jBase = 0; jBase < entity.jSize; ++jBase)
{
for (int kBase = 0; kBase < entity.kSize; ++kBase)
{
util.min = new Vector3();
double remainX = entity.iSize - iBase;
double remainY = entity.jSize - jBase;
double remainZ = entity.kSize - kBase;
util.max = new Vector3((remainX > 1.0 ? 1.0 : remainX), (remainY > 1.0 ? 1.0 : remainY), (remainZ > 1.0 ? 1.0 : remainZ));
GL11.glPushMatrix();
GL11.glTranslatef((float) i, (float) j, (float) k);
GL11.glRotatef(entity.rotationX, 1, 0, 0);
GL11.glRotatef(entity.rotationY, 0, 1, 0);
GL11.glRotatef(entity.rotationZ, 0, 0, 1);
GL11.glTranslatef(iBase, jBase, kBase);
int lightX, lightY, lightZ;
lightX = (int) (Math.floor(entity.posX) + iBase);
lightY = (int) (Math.floor(entity.posY) + jBase);
lightZ = (int) (Math.floor(entity.posZ) + kBase);
GL11.glDisable(2896 /* GL_LIGHTING */);
renderBlock(util, world, lightX, lightY, lightZ);
GL11.glEnable(2896 /* GL_LIGHTING */);
GL11.glPopMatrix();
}
}
}
}
/** Renders a block at given location
*
* @param blockInterface - class used to store info for the render process
* @param world - world rendering in
* @param x - position on x axis
* @param y - position on y axis
* @param z - position on z axis */
public void renderBlock(BlockRenderInfo blockInterface, IBlockAccess world, int x, int y, int z)
{
renderBlocks.renderMaxX = blockInterface.max.x;
renderBlocks.renderMinX = blockInterface.min.x;
renderBlocks.renderMaxY = blockInterface.max.y;
renderBlocks.renderMinY = blockInterface.min.y;
renderBlocks.renderMaxZ = blockInterface.max.z;
renderBlocks.renderMinZ = blockInterface.min.z;
renderBlocks.enableAO = false;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
//TODO do a check for "should render side" to solve issue with transparent blocks. Mainly rendering water blocks next to each other
renderBlocks.renderFaceYNeg(blockInterface.baseBlock, 0, 0, 0, blockInterface.getBlockIconFromSideAndMetadata(0, blockInterface.meta));
renderBlocks.renderFaceYPos(blockInterface.baseBlock, 0, 0, 0, blockInterface.getBlockIconFromSideAndMetadata(1, blockInterface.meta));
renderBlocks.renderFaceZNeg(blockInterface.baseBlock, 0, 0, 0, blockInterface.getBlockIconFromSideAndMetadata(2, blockInterface.meta));
renderBlocks.renderFaceZPos(blockInterface.baseBlock, 0, 0, 0, blockInterface.getBlockIconFromSideAndMetadata(3, blockInterface.meta));
renderBlocks.renderFaceXNeg(blockInterface.baseBlock, 0, 0, 0, blockInterface.getBlockIconFromSideAndMetadata(4, blockInterface.meta));
renderBlocks.renderFaceXPos(blockInterface.baseBlock, 0, 0, 0, blockInterface.getBlockIconFromSideAndMetadata(5, blockInterface.meta));
tessellator.draw();
}
@Override
protected ResourceLocation func_110775_a(Entity entity)
{
throw new UnsupportedOperationException("Getting resoure location for this is not support as of yet");
}
}