further tweaks to builders, refactor PipeRendererTESR to allow custom PipeTransport renderers

This commit is contained in:
Adrian 2015-08-09 14:38:22 +02:00
parent 75815174a9
commit bdb46f0bda
14 changed files with 676 additions and 535 deletions

View file

@ -41,7 +41,8 @@ public abstract class Schematic {
public enum BuildingStage {
/**
* Standalone blocks can be placed in the air, and they don't change
* once placed.
* once placed. This category also includes blocks which fall but can
* support other blocks.
*/
STANDALONE,
@ -159,6 +160,9 @@ public abstract class Schematic {
* Can the block be placed in the world at these coordinates now?
* This function is only used to *delay* block placement until other
* prerequisites are met.
*
* This should probably be used sparingly, in cases where the BuildStage
* distinction is not enough.
*/
public boolean canPlaceInWorld(IBuilderContext context, int x, int y, int z) {
return true;

View file

@ -93,12 +93,19 @@ public class SchematicBlock extends SchematicBlockBase {
}
@Override
public BuildingStage getBuildStage () {
public boolean canPlaceInWorld(IBuilderContext context, int x, int y, int z) {
if (block instanceof BlockFalling) {
return BuildingStage.SUPPORTED;
} else if (block instanceof BlockFluidBase || block instanceof BlockLiquid) {
return y > 0 && !context.world().isAirBlock(x, y - 1, z);
} else {
return true;
}
}
@Override
public BuildingStage getBuildStage () {
if (block instanceof BlockFluidBase || block instanceof BlockLiquid) {
return BuildingStage.EXPANDING;
} else if (block.isOpaqueCube()) {
} else if (block.isOpaqueCube() || block instanceof BlockFalling) {
return BuildingStage.STANDALONE;
} else {
return BuildingStage.SUPPORTED;

View file

@ -67,7 +67,7 @@ public class BuildingSlotMapIterator {
pair = impIterator.next();
if (isCreative || availablePairs.contains(pair)) {
current = slots.get(pair);
position = pair.position;
position = pair.position - 1;
return;
}
}

View file

@ -20,9 +20,10 @@ import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.transport.IPipeTile;
import buildcraft.core.lib.utils.BitSetUtils;
import buildcraft.transport.render.PipeTransportRenderer;
public abstract class PipeTransport {
public final PipeTransportRenderer renderer;
public TileGenericPipe container;
protected boolean[] inputsOpen = new boolean[ForgeDirection.VALID_DIRECTIONS.length];
@ -33,8 +34,12 @@ public abstract class PipeTransport {
inputsOpen[b] = true;
outputsOpen[b] = true;
}
renderer = createTransportRenderer();
}
public abstract PipeTransportRenderer createTransportRenderer();
public abstract IPipeTile.PipeType getPipeType();
public World getWorld() {

View file

@ -40,6 +40,8 @@ import buildcraft.transport.pipes.PipeFluidsStone;
import buildcraft.transport.pipes.PipeFluidsVoid;
import buildcraft.transport.pipes.PipeFluidsWood;
import buildcraft.transport.pipes.events.PipeEventFluid;
import buildcraft.transport.render.PipeTransportFluidsRenderer;
import buildcraft.transport.render.PipeTransportRenderer;
import buildcraft.transport.utils.FluidRenderData;
public class PipeTransportFluids extends PipeTransport implements IFluidHandler, IDebuggable {
@ -188,6 +190,11 @@ public class PipeTransportFluids extends PipeTransport implements IFluidHandler,
travelDelay = MathUtils.clamp(Math.round(16F / (flowRate / BuildCraftTransport.pipeFluidsBaseFlowRate)), 1, MAX_TRAVEL_DELAY);
}
@Override
public PipeTransportRenderer createTransportRenderer() {
return new PipeTransportFluidsRenderer();
}
@Override
public void initialize() {
super.initialize();

View file

@ -39,6 +39,8 @@ import buildcraft.core.lib.utils.MathUtils;
import buildcraft.transport.network.PacketPipeTransportItemStackRequest;
import buildcraft.transport.network.PacketPipeTransportTraveler;
import buildcraft.transport.pipes.events.PipeEventItem;
import buildcraft.transport.render.PipeTransportItemsRenderer;
import buildcraft.transport.render.PipeTransportRenderer;
import buildcraft.transport.utils.TransportUtils;
public class PipeTransportItems extends PipeTransport implements IDebuggable {
@ -53,6 +55,11 @@ public class PipeTransportItems extends PipeTransport implements IDebuggable {
return IPipeTile.PipeType.ITEM;
}
@Override
public PipeTransportRenderer createTransportRenderer() {
return new PipeTransportItemsRenderer();
}
public void readjustSpeed(TravelingItem item) {
PipeEventItem.AdjustSpeed event = new PipeEventItem.AdjustSpeed(container.pipe, item);
container.pipe.eventBus.handleEvent(PipeEventItem.AdjustSpeed.class, event);

View file

@ -43,6 +43,8 @@ import buildcraft.transport.pipes.PipePowerQuartz;
import buildcraft.transport.pipes.PipePowerSandstone;
import buildcraft.transport.pipes.PipePowerStone;
import buildcraft.transport.pipes.PipePowerWood;
import buildcraft.transport.render.PipeTransportPowerRenderer;
import buildcraft.transport.render.PipeTransportRenderer;
public class PipeTransportPower extends PipeTransport implements IDebuggable {
public static final Map<Class<? extends Pipe<?>>, Integer> powerCapacities = new HashMap<Class<? extends Pipe<?>>, Integer>();
@ -81,6 +83,11 @@ public class PipeTransportPower extends PipeTransport implements IDebuggable {
}
}
@Override
public PipeTransportRenderer createTransportRenderer() {
return new PipeTransportPowerRenderer();
}
@Override
public IPipeTile.PipeType getPipeType() {
return IPipeTile.PipeType.POWER;

View file

@ -12,8 +12,14 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.transport.IPipeTile;
import buildcraft.transport.render.PipeTransportRenderer;
import buildcraft.transport.render.PipeTransportStructureRenderer;
public class PipeTransportStructure extends PipeTransport {
@Override
public PipeTransportRenderer createTransportRenderer() {
return new PipeTransportStructureRenderer();
}
@Override
public IPipeTile.PipeType getPipeType() {

View file

@ -10,281 +10,42 @@ package buildcraft.transport.render;
import org.lwjgl.opengl.GL11;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.IntHashMap;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import buildcraft.BuildCraftCore;
import buildcraft.BuildCraftCore.RenderMode;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.EnumColor;
import buildcraft.api.core.Position;
import buildcraft.api.core.render.ITextureStates;
import buildcraft.api.gates.IGateExpansion;
import buildcraft.api.items.IItemCustomPipeRender;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.PipeWire;
import buildcraft.api.transport.pluggable.PipePluggable;
import buildcraft.core.CoreConstants;
import buildcraft.core.lib.render.RenderEntityBlock;
import buildcraft.core.lib.render.RenderEntityBlock.RenderInfo;
import buildcraft.core.lib.render.RenderUtils;
import buildcraft.core.lib.utils.MatrixTranformations;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeRenderState;
import buildcraft.transport.PipeTransportFluids;
import buildcraft.transport.PipeTransportItems;
import buildcraft.transport.PipeTransportPower;
import buildcraft.transport.TileGenericPipe;
import buildcraft.transport.TravelingItem;
import buildcraft.transport.gates.GatePluggable;
import buildcraft.transport.utils.FluidRenderData;
public class PipeRendererTESR extends TileEntitySpecialRenderer {
public static final PipeRendererTESR INSTANCE = new PipeRendererTESR();
public static final int POWER_STAGES = 256;
private static final float POWER_MAGIC = 0.7F; // Math.pow(displayPower, POWER_MAGIC)
private static final int LIQUID_STAGES = 40;
private static final int MAX_ITEMS_TO_RENDER = 10;
public int[] displayPowerList = new int[POWER_STAGES];
public int[] displayPowerListOverload = new int[POWER_STAGES];
private final IntHashMap displayFluidLists = new IntHashMap();
private final int[] angleY = {0, 0, 270, 90, 0, 180};
private final int[] angleZ = {90, 270, 0, 0, 0, 0};
private final EntityItem dummyEntityItem = new EntityItem(null);
private final RenderItem customRenderItem;
private boolean initialized = false;
private class DisplayFluidList {
public int[] sideHorizontal = new int[LIQUID_STAGES];
public int[] sideVertical = new int[LIQUID_STAGES];
public int[] centerHorizontal = new int[LIQUID_STAGES];
public int[] centerVertical = new int[LIQUID_STAGES];
}
protected PipeRendererTESR() {
customRenderItem = new RenderItem() {
@Override
public boolean shouldBob() {
return false;
}
@Override
public boolean shouldSpreadItems() {
return false;
}
};
customRenderItem.setRenderManager(RenderManager.instance);
}
public void onTextureReload() {
if (initialized) {
for (int i = 0; i < POWER_STAGES; i++) {
GL11.glDeleteLists(displayPowerList[i], 1);
GL11.glDeleteLists(displayPowerListOverload[i], 1);
}
}
displayFluidLists.clearMap();
initialized = false;
}
private DisplayFluidList getDisplayFluidLists(int liquidId, int skylight, int blocklight, int flags, World world) {
int finalBlockLight = Math.max(flags & 31, blocklight);
int listId = (liquidId & 0x3FFFF) << 13 | (flags & 0xE0 | finalBlockLight) << 5 | (skylight & 31);
if (displayFluidLists.containsItem(listId)) {
return (DisplayFluidList) displayFluidLists.lookup(listId);
}
Fluid fluid = FluidRegistry.getFluid(liquidId);
if (fluid == null) {
return null;
}
DisplayFluidList d = new DisplayFluidList();
displayFluidLists.addKey(listId, d);
RenderInfo block = new RenderInfo();
if (fluid.getBlock() != null) {
block.baseBlock = fluid.getBlock();
} else {
block.baseBlock = Blocks.water;
}
block.texture = fluid.getStillIcon();
block.brightness = skylight << 16 | finalBlockLight;
float size = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;
// render size
for (int s = 0; s < LIQUID_STAGES; ++s) {
float ratio = (float) s / (float) LIQUID_STAGES;
// SIDE HORIZONTAL
d.sideHorizontal[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.sideHorizontal[s], GL11.GL_COMPILE);
block.minX = 0.0F;
block.minZ = CoreConstants.PIPE_MIN_POS + 0.01F;
block.maxX = block.minX + size / 2F + 0.01F;
block.maxZ = block.minZ + size - 0.02F;
block.minY = CoreConstants.PIPE_MIN_POS + 0.01F;
block.maxY = block.minY + (size - 0.02F) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
// SIDE VERTICAL
d.sideVertical[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.sideVertical[s], GL11.GL_COMPILE);
block.minY = CoreConstants.PIPE_MAX_POS - 0.01;
block.maxY = 1;
block.minX = 0.5 - (size / 2 - 0.01) * ratio;
block.maxX = 0.5 + (size / 2 - 0.01) * ratio;
block.minZ = 0.5 - (size / 2 - 0.01) * ratio;
block.maxZ = 0.5 + (size / 2 - 0.01) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
// CENTER HORIZONTAL
d.centerHorizontal[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.centerHorizontal[s], GL11.GL_COMPILE);
block.minX = CoreConstants.PIPE_MIN_POS + 0.01;
block.minZ = CoreConstants.PIPE_MIN_POS + 0.01;
block.maxX = block.minX + size - 0.02;
block.maxZ = block.minZ + size - 0.02;
block.minY = CoreConstants.PIPE_MIN_POS + 0.01;
block.maxY = block.minY + (size - 0.02F) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
// CENTER VERTICAL
d.centerVertical[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.centerVertical[s], GL11.GL_COMPILE);
block.minY = CoreConstants.PIPE_MIN_POS + 0.01;
block.maxY = CoreConstants.PIPE_MAX_POS - 0.01;
block.minX = 0.5 - (size / 2 - 0.02) * ratio;
block.maxX = 0.5 + (size / 2 - 0.02) * ratio;
block.minZ = 0.5 - (size / 2 - 0.02) * ratio;
block.maxZ = 0.5 + (size / 2 - 0.02) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
}
return d;
}
private void initializeDisplayPowerList(World world) {
if (initialized) {
return;
}
initialized = true;
RenderInfo block = new RenderInfo();
block.texture = BuildCraftTransport.instance.pipeIconProvider.getIcon(PipeIconProvider.TYPE.Power_Normal.ordinal());
float size = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;
for (int s = 0; s < POWER_STAGES; ++s) {
displayPowerList[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(displayPowerList[s], GL11.GL_COMPILE);
float minSize = 0.005F;
float unit = (size - minSize) / 2F / POWER_STAGES;
block.minY = 0.5 - (minSize / 2F) - unit * s;
block.maxY = 0.5 + (minSize / 2F) + unit * s;
block.minZ = 0.5 - (minSize / 2F) - unit * s;
block.maxZ = 0.5 + (minSize / 2F) + unit * s;
block.minX = 0;
block.maxX = 0.5 + (minSize / 2F) + unit * s;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
}
block.texture = BuildCraftTransport.instance.pipeIconProvider.getIcon(PipeIconProvider.TYPE.Power_Overload.ordinal());
size = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;
for (int s = 0; s < POWER_STAGES; ++s) {
displayPowerListOverload[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(displayPowerListOverload[s], GL11.GL_COMPILE);
float minSize = 0.005F;
float unit = (size - minSize) / 2F / POWER_STAGES;
block.minY = 0.5 - (minSize / 2F) - unit * s;
block.maxY = 0.5 + (minSize / 2F) + unit * s;
block.minZ = 0.5 - (minSize / 2F) - unit * s;
block.maxZ = 0.5 + (minSize / 2F) + unit * s;
block.minX = 0;
block.maxX = 0.5 + (minSize / 2F) + unit * s;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
}
PipeTransportPowerRenderer.clear();
PipeTransportFluidsRenderer.clear();
}
@Override
@ -302,18 +63,8 @@ public class PipeRendererTESR extends TileEntitySpecialRenderer {
renderGatesWires(pipe, x, y, z);
renderPluggables(pipe, x, y, z);
IPipeTile.PipeType pipeType = pipe.getPipeType();
// do not use switch. we will be transitioning away from the enum
if (pipeType == IPipeTile.PipeType.ITEM) {
renderSolids(pipe.pipe, x, y, z, f);
} else if (pipeType == IPipeTile.PipeType.FLUID) {
renderFluids(((TileGenericPipe) CoreProxy.proxy.getServerTile(pipe)).pipe, x, y, z);
} else if (pipeType == IPipeTile.PipeType.POWER) {
renderPower(((TileGenericPipe) CoreProxy.proxy.getServerTile(pipe)).pipe, x, y, z);
} /* else if (pipeType == PipeType.STRUCTURE) {
// no object to render in a structure pipe;
} */
PipeTransportRenderer renderer = pipe.pipe.transport.renderer;
renderer.render(renderer.useServerTileIfPresent() ? (Pipe) (((IPipeTile) CoreProxy.proxy.getServerTile(pipe)).getPipe()) : pipe.pipe, x, y, z, f);
}
private void renderGatesWires(TileGenericPipe pipe, double x, double y, double z) {
@ -656,279 +407,4 @@ public class PipeRendererTESR extends TileEntitySpecialRenderer {
return targetOrientation.getOpposite() == direction;
}
private void renderPower(Pipe<PipeTransportPower> pipe, double x, double y, double z) {
initializeDisplayPowerList(pipe.container.getWorldObj());
PipeTransportPower pow = pipe.transport;
GL11.glPushMatrix();
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glTranslatef((float) x, (float) y, (float) z);
bindTexture(TextureMap.locationBlocksTexture);
int[] displayList = pow.overload > 0 ? displayPowerListOverload : displayPowerList;
for (int side = 0; side < 6; ++side) {
int stage = (int) Math.ceil(Math.pow(pow.displayPower[side], POWER_MAGIC));
if (stage >= 1) {
if (!pipe.container.isPipeConnected(ForgeDirection.getOrientation(side))) {
continue;
}
GL11.glPushMatrix();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
GL11.glRotatef(angleY[side], 0, 1, 0);
GL11.glRotatef(angleZ[side], 0, 0, 1);
float scale = 1.0F - side * 0.0001F;
GL11.glScalef(scale, scale, scale);
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
if (stage < displayList.length) {
GL11.glCallList(displayList[stage]);
} else {
GL11.glCallList(displayList[displayList.length - 1]);
}
GL11.glPopMatrix();
}
}
/*bindTexture(STRIPES_TEXTURE);
for (int side = 0; side < 6; side += 2) {
if (pipe.container.isPipeConnected(ForgeDirection.values()[side])) {
GL11.glPushMatrix();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
GL11.glRotatef(angleY[side], 0, 1, 0);
GL11.glRotatef(angleZ[side], 0, 0, 1);
float scale = 1.0F - side * 0.0001F;
GL11.glScalef(scale, scale, scale);
float movement = (0.50F) * pipe.transport.getPistonStage(side / 2);
GL11.glTranslatef(-0.25F - 1F / 16F - movement, -0.5F, -0.5F);
// float factor = (float) (1.0 / 256.0);
float factor = (float) (1.0 / 16.0);
box.render(factor);
GL11.glPopMatrix();
}
}*/
GL11.glPopAttrib();
GL11.glPopMatrix();
}
private void renderFluids(Pipe<PipeTransportFluids> pipe, double x, double y, double z) {
PipeTransportFluids trans = pipe.transport;
boolean needsRender = false;
FluidRenderData renderData;
if (!pipe.container.getWorldObj().isRemote) {
renderData = trans.createServerFluidRenderData();
} else {
renderData = trans.renderCache;
}
for (int i = 0; i < 7; ++i) {
if (renderData.amount[i] > 0) {
needsRender = true;
break;
}
}
if (!needsRender) {
return;
}
GL11.glPushMatrix();
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);
GL11.glTranslatef((float) x, (float) y, (float) z);
int skylight = pipe.container.getWorld().getSkyBlockTypeBrightness(EnumSkyBlock.Sky, pipe.container.x(), pipe.container.y(), pipe.container.z());
int blocklight = pipe.container.getWorld().getSkyBlockTypeBrightness(EnumSkyBlock.Block, pipe.container.x(), pipe.container.y(), pipe.container.z());
boolean sides = false, above = false;
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
int i = side.ordinal();
if (renderData.amount[i] <= 0) {
continue;
}
if (!pipe.container.isPipeConnected(side)) {
continue;
}
DisplayFluidList d = getDisplayFluidLists(renderData.fluidID, skylight, blocklight,
renderData.flags, pipe.container.getWorldObj());
if (d == null) {
continue;
}
int stage = (int) ((float) renderData.amount[i] / (float) (trans.getCapacity()) * (LIQUID_STAGES - 1));
GL11.glPushMatrix();
int list = 0;
switch (ForgeDirection.VALID_DIRECTIONS[i]) {
case UP:
above = true;
list = d.sideVertical[stage];
break;
case DOWN:
GL11.glTranslatef(0, -0.75F, 0);
list = d.sideVertical[stage];
break;
case EAST:
case WEST:
case SOUTH:
case NORTH:
sides = true;
// Yes, this is kind of ugly, but was easier than transform the coordinates above.
GL11.glTranslatef(0.5F, 0.0F, 0.5F);
GL11.glRotatef(angleY[i], 0, 1, 0);
GL11.glRotatef(angleZ[i], 0, 0, 1);
GL11.glTranslatef(-0.5F, 0.0F, -0.5F);
list = d.sideHorizontal[stage];
break;
default:
}
bindTexture(TextureMap.locationBlocksTexture);
RenderUtils.setGLColorFromInt(renderData.color);
GL11.glCallList(list);
GL11.glPopMatrix();
}
if (renderData.amount[6] > 0) {
DisplayFluidList d = getDisplayFluidLists(renderData.fluidID, skylight, blocklight,
renderData.flags, pipe.container.getWorldObj());
if (d != null) {
int stage = (int) ((float) renderData.amount[6] / (float) (trans.getCapacity()) * (LIQUID_STAGES - 1));
bindTexture(TextureMap.locationBlocksTexture);
RenderUtils.setGLColorFromInt(renderData.color);
if (above) {
GL11.glCallList(d.centerVertical[stage]);
}
if (!above || sides) {
GL11.glCallList(d.centerHorizontal[stage]);
}
}
}
GL11.glPopAttrib();
GL11.glPopMatrix();
}
private void renderSolids(Pipe<PipeTransportItems> pipe, double x, double y, double z, float f) {
GL11.glPushMatrix();
int count = 0;
for (TravelingItem item : pipe.transport.items) {
if (count >= MAX_ITEMS_TO_RENDER) {
break;
}
Position motion = new Position(0, 0, 0, item.toCenter ? item.input : item.output);
motion.moveForwards(item.getSpeed() * f);
doRenderItem(item, x + item.xCoord - pipe.container.xCoord + motion.x, y + item.yCoord - pipe.container.yCoord + motion.y, z + item.zCoord - pipe.container.zCoord + motion.z, 0.0F, item.color);
count++;
}
GL11.glPopMatrix();
}
private int getItemLightLevel(ItemStack stack) {
if (stack.getItem() instanceof ItemBlock) {
Block b = Block.getBlockFromItem(stack.getItem());
return b.getLightValue();
}
return 0;
}
public void doRenderItem(TravelingItem travellingItem, double x, double y, double z, float light, EnumColor color) {
if (travellingItem == null || travellingItem.getItemStack() == null) {
return;
}
float renderScale = 0.7f;
ItemStack itemstack = travellingItem.getItemStack();
GL11.glPushMatrix();
GL11.glTranslatef((float) x, (float) y + 0.25F, (float) z);
//OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, skylight << 4, Math.max(blocklight, getItemLightLevel(itemstack)) << 4);
if (travellingItem.hasDisplayList) {
GL11.glCallList(travellingItem.displayList);
} else {
travellingItem.displayList = GLAllocation.generateDisplayLists(1);
travellingItem.hasDisplayList = true;
GL11.glNewList(travellingItem.displayList, GL11.GL_COMPILE_AND_EXECUTE);
if (itemstack.getItem() instanceof IItemCustomPipeRender) {
IItemCustomPipeRender render = (IItemCustomPipeRender) itemstack.getItem();
float itemScale = render.getPipeRenderScale(itemstack);
GL11.glScalef(renderScale * itemScale, renderScale * itemScale, renderScale * itemScale);
itemScale = 1 / itemScale;
if (!render.renderItemInPipe(itemstack, x, y, z)) {
dummyEntityItem.setEntityItemStack(itemstack);
customRenderItem.doRender(dummyEntityItem, 0, 0, 0, 0, 0);
}
GL11.glScalef(itemScale, itemScale, itemScale);
} else {
GL11.glScalef(renderScale, renderScale, renderScale);
dummyEntityItem.setEntityItemStack(itemstack);
customRenderItem.doRender(dummyEntityItem, 0, 0, 0, 0, 0);
}
GL11.glEndList();
}
if (color != null) {
bindTexture(TextureMap.locationBlocksTexture);
RenderInfo block = new RenderInfo();
block.texture = BuildCraftTransport.instance.pipeIconProvider.getIcon(PipeIconProvider.TYPE.ItemBox.ordinal());
float pix = 0.0625F;
float min = -4 * pix;
float max = 4 * pix;
block.minY = min;
block.maxY = max;
block.minZ = min;
block.maxZ = max;
block.minX = min;
block.maxX = max;
RenderUtils.setGLColorFromInt(color.getLightHex());
RenderEntityBlock.INSTANCE.renderBlock(block);
}
GL11.glPopMatrix();
}
}

View file

@ -0,0 +1,280 @@
package buildcraft.transport.render;
import org.lwjgl.opengl.GL11;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.set.hash.TIntHashSet;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.init.Blocks;
import net.minecraft.util.IntHashMap;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import buildcraft.core.CoreConstants;
import buildcraft.core.lib.render.RenderEntityBlock;
import buildcraft.core.lib.render.RenderUtils;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeTransportFluids;
import buildcraft.transport.utils.FluidRenderData;
public class PipeTransportFluidsRenderer extends PipeTransportRenderer<PipeTransportFluids> {
private static final IntHashMap displayFluidLists = new IntHashMap();
private static final TIntHashSet displayFluidListsSet = new TIntHashSet();
private static final int LIQUID_STAGES = 40;
private static final int[] angleY = {0, 0, 270, 90, 0, 180};
private static final int[] angleZ = {90, 270, 0, 0, 0, 0};
private class DisplayFluidList {
public int[] sideHorizontal = new int[LIQUID_STAGES];
public int[] sideVertical = new int[LIQUID_STAGES];
public int[] centerHorizontal = new int[LIQUID_STAGES];
public int[] centerVertical = new int[LIQUID_STAGES];
}
protected static void clear() {
TIntIterator i = displayFluidListsSet.iterator();
while (i.hasNext()) {
GL11.glDeleteLists(i.next(), 1);
}
displayFluidListsSet.clear();
displayFluidLists.clearMap();
}
public boolean useServerTileIfPresent() {
return true;
}
private DisplayFluidList getDisplayFluidLists(int liquidId, int skylight, int blocklight, int flags, World world) {
int finalBlockLight = Math.max(flags & 31, blocklight);
int listId = (liquidId & 0x3FFFF) << 13 | (flags & 0xE0 | finalBlockLight) << 5 | (skylight & 31);
if (displayFluidLists.containsItem(listId)) {
return (DisplayFluidList) displayFluidLists.lookup(listId);
}
Fluid fluid = FluidRegistry.getFluid(liquidId);
if (fluid == null) {
return null;
}
DisplayFluidList d = new DisplayFluidList();
displayFluidLists.addKey(listId, d);
displayFluidListsSet.add(listId);
RenderEntityBlock.RenderInfo block = new RenderEntityBlock.RenderInfo();
if (fluid.getBlock() != null) {
block.baseBlock = fluid.getBlock();
} else {
block.baseBlock = Blocks.water;
}
block.texture = fluid.getStillIcon();
block.brightness = skylight << 16 | finalBlockLight;
float size = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;
// render size
for (int s = 0; s < LIQUID_STAGES; ++s) {
float ratio = (float) s / (float) LIQUID_STAGES;
// SIDE HORIZONTAL
d.sideHorizontal[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.sideHorizontal[s], GL11.GL_COMPILE);
block.minX = 0.0F;
block.minZ = CoreConstants.PIPE_MIN_POS + 0.01F;
block.maxX = block.minX + size / 2F + 0.01F;
block.maxZ = block.minZ + size - 0.02F;
block.minY = CoreConstants.PIPE_MIN_POS + 0.01F;
block.maxY = block.minY + (size - 0.02F) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
// SIDE VERTICAL
d.sideVertical[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.sideVertical[s], GL11.GL_COMPILE);
block.minY = CoreConstants.PIPE_MAX_POS - 0.01;
block.maxY = 1;
block.minX = 0.5 - (size / 2 - 0.01) * ratio;
block.maxX = 0.5 + (size / 2 - 0.01) * ratio;
block.minZ = 0.5 - (size / 2 - 0.01) * ratio;
block.maxZ = 0.5 + (size / 2 - 0.01) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
// CENTER HORIZONTAL
d.centerHorizontal[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.centerHorizontal[s], GL11.GL_COMPILE);
block.minX = CoreConstants.PIPE_MIN_POS + 0.01;
block.minZ = CoreConstants.PIPE_MIN_POS + 0.01;
block.maxX = block.minX + size - 0.02;
block.maxZ = block.minZ + size - 0.02;
block.minY = CoreConstants.PIPE_MIN_POS + 0.01;
block.maxY = block.minY + (size - 0.02F) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
// CENTER VERTICAL
d.centerVertical[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(d.centerVertical[s], GL11.GL_COMPILE);
block.minY = CoreConstants.PIPE_MIN_POS + 0.01;
block.maxY = CoreConstants.PIPE_MAX_POS - 0.01;
block.minX = 0.5 - (size / 2 - 0.02) * ratio;
block.maxX = 0.5 + (size / 2 - 0.02) * ratio;
block.minZ = 0.5 - (size / 2 - 0.02) * ratio;
block.maxZ = 0.5 + (size / 2 - 0.02) * ratio;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
}
return d;
}
@Override
public void render(Pipe<PipeTransportFluids> pipe, double x, double y, double z, float f) {
PipeTransportFluids trans = pipe.transport;
boolean needsRender = false;
FluidRenderData renderData;
if (!pipe.container.getWorldObj().isRemote) {
renderData = trans.createServerFluidRenderData();
} else {
renderData = trans.renderCache;
}
for (int i = 0; i < 7; ++i) {
if (renderData.amount[i] > 0) {
needsRender = true;
break;
}
}
if (!needsRender) {
return;
}
GL11.glPushMatrix();
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);
GL11.glTranslatef((float) x, (float) y, (float) z);
int skylight = pipe.container.getWorld().getSkyBlockTypeBrightness(EnumSkyBlock.Sky, pipe.container.x(), pipe.container.y(), pipe.container.z());
int blocklight = pipe.container.getWorld().getSkyBlockTypeBrightness(EnumSkyBlock.Block, pipe.container.x(), pipe.container.y(), pipe.container.z());
boolean sides = false, above = false;
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
int i = side.ordinal();
if (renderData.amount[i] <= 0) {
continue;
}
if (!pipe.container.isPipeConnected(side)) {
continue;
}
DisplayFluidList d = getDisplayFluidLists(renderData.fluidID, skylight, blocklight,
renderData.flags, pipe.container.getWorldObj());
if (d == null) {
continue;
}
int stage = (int) ((float) renderData.amount[i] / (float) (trans.getCapacity()) * (LIQUID_STAGES - 1));
GL11.glPushMatrix();
int list = 0;
switch (ForgeDirection.VALID_DIRECTIONS[i]) {
case UP:
above = true;
list = d.sideVertical[stage];
break;
case DOWN:
GL11.glTranslatef(0, -0.75F, 0);
list = d.sideVertical[stage];
break;
case EAST:
case WEST:
case SOUTH:
case NORTH:
sides = true;
// Yes, this is kind of ugly, but was easier than transform the coordinates above.
GL11.glTranslatef(0.5F, 0.0F, 0.5F);
GL11.glRotatef(angleY[i], 0, 1, 0);
GL11.glRotatef(angleZ[i], 0, 0, 1);
GL11.glTranslatef(-0.5F, 0.0F, -0.5F);
list = d.sideHorizontal[stage];
break;
default:
}
bindTexture(TextureMap.locationBlocksTexture);
RenderUtils.setGLColorFromInt(renderData.color);
GL11.glCallList(list);
GL11.glPopMatrix();
}
if (renderData.amount[6] > 0) {
DisplayFluidList d = getDisplayFluidLists(renderData.fluidID, skylight, blocklight,
renderData.flags, pipe.container.getWorldObj());
if (d != null) {
int stage = (int) ((float) renderData.amount[6] / (float) (trans.getCapacity()) * (LIQUID_STAGES - 1));
bindTexture(TextureMap.locationBlocksTexture);
RenderUtils.setGLColorFromInt(renderData.color);
if (above) {
GL11.glCallList(d.centerVertical[stage]);
}
if (!above || sides) {
GL11.glCallList(d.centerHorizontal[stage]);
}
}
}
GL11.glPopAttrib();
GL11.glPopMatrix();
}
}

View file

@ -0,0 +1,138 @@
package buildcraft.transport.render;
import org.lwjgl.opengl.GL11;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.EnumColor;
import buildcraft.api.core.Position;
import buildcraft.api.items.IItemCustomPipeRender;
import buildcraft.core.lib.render.RenderEntityBlock;
import buildcraft.core.lib.render.RenderUtils;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeTransportItems;
import buildcraft.transport.TravelingItem;
public class PipeTransportItemsRenderer extends PipeTransportRenderer<PipeTransportItems> {
private static final EntityItem dummyEntityItem = new EntityItem(null);
private static final RenderItem customRenderItem;
private static final int MAX_ITEMS_TO_RENDER = 10;
static {
customRenderItem = new RenderItem() {
@Override
public boolean shouldBob() {
return false;
}
@Override
public boolean shouldSpreadItems() {
return false;
}
};
customRenderItem.setRenderManager(RenderManager.instance);
}
private int getItemLightLevel(ItemStack stack) {
if (stack.getItem() instanceof ItemBlock) {
Block b = Block.getBlockFromItem(stack.getItem());
return b.getLightValue();
}
return 0;
}
public void doRenderItem(TravelingItem travellingItem, double x, double y, double z, float light, EnumColor color) {
if (travellingItem == null || travellingItem.getItemStack() == null) {
return;
}
float renderScale = 0.7f;
ItemStack itemstack = travellingItem.getItemStack();
GL11.glPushMatrix();
GL11.glTranslatef((float) x, (float) y + 0.25F, (float) z);
//OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, skylight << 4, Math.max(blocklight, getItemLightLevel(itemstack)) << 4);
if (travellingItem.hasDisplayList) {
GL11.glCallList(travellingItem.displayList);
} else {
travellingItem.displayList = GLAllocation.generateDisplayLists(1);
travellingItem.hasDisplayList = true;
GL11.glNewList(travellingItem.displayList, GL11.GL_COMPILE_AND_EXECUTE);
if (itemstack.getItem() instanceof IItemCustomPipeRender) {
IItemCustomPipeRender render = (IItemCustomPipeRender) itemstack.getItem();
float itemScale = render.getPipeRenderScale(itemstack);
GL11.glScalef(renderScale * itemScale, renderScale * itemScale, renderScale * itemScale);
itemScale = 1 / itemScale;
if (!render.renderItemInPipe(itemstack, x, y, z)) {
dummyEntityItem.setEntityItemStack(itemstack);
customRenderItem.doRender(dummyEntityItem, 0, 0, 0, 0, 0);
}
GL11.glScalef(itemScale, itemScale, itemScale);
} else {
GL11.glScalef(renderScale, renderScale, renderScale);
dummyEntityItem.setEntityItemStack(itemstack);
customRenderItem.doRender(dummyEntityItem, 0, 0, 0, 0, 0);
}
GL11.glEndList();
}
if (color != null) {
bindTexture(TextureMap.locationBlocksTexture);
RenderEntityBlock.RenderInfo block = new RenderEntityBlock.RenderInfo();
block.texture = BuildCraftTransport.instance.pipeIconProvider.getIcon(PipeIconProvider.TYPE.ItemBox.ordinal());
float pix = 0.0625F;
float min = -4 * pix;
float max = 4 * pix;
block.minY = min;
block.maxY = max;
block.minZ = min;
block.maxZ = max;
block.minX = min;
block.maxX = max;
RenderUtils.setGLColorFromInt(color.getLightHex());
RenderEntityBlock.INSTANCE.renderBlock(block);
}
GL11.glPopMatrix();
}
@Override
public void render(Pipe<PipeTransportItems> pipe, double x, double y, double z, float f) {
GL11.glPushMatrix();
int count = 0;
for (TravelingItem item : pipe.transport.items) {
if (count >= MAX_ITEMS_TO_RENDER) {
break;
}
Position motion = new Position(0, 0, 0, item.toCenter ? item.input : item.output);
motion.moveForwards(item.getSpeed() * f);
doRenderItem(item, x + item.xCoord - pipe.container.xCoord + motion.x, y + item.yCoord - pipe.container.yCoord + motion.y, z + item.zCoord - pipe.container.zCoord + motion.z, 0.0F, item.color);
count++;
}
GL11.glPopMatrix();
}
}

View file

@ -0,0 +1,172 @@
package buildcraft.transport.render;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport;
import buildcraft.core.CoreConstants;
import buildcraft.core.lib.render.RenderEntityBlock;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeTransportPower;
public class PipeTransportPowerRenderer extends PipeTransportRenderer<PipeTransportPower> {
public static final int POWER_STAGES = 256;
public static final int[] displayPowerList = new int[POWER_STAGES];
public static final int[] displayPowerListOverload = new int[POWER_STAGES];
private static final int[] angleY = {0, 0, 270, 90, 0, 180};
private static final int[] angleZ = {90, 270, 0, 0, 0, 0};
private static final float POWER_MAGIC = 0.7F; // Math.pow(displayPower, POWER_MAGIC)
private static boolean initialized = false;
protected static void clear() {
if (initialized) {
for (int i = 0; i < POWER_STAGES; i++) {
GL11.glDeleteLists(displayPowerList[i], 1);
GL11.glDeleteLists(displayPowerListOverload[i], 1);
}
}
initialized = false;
}
public boolean useServerTileIfPresent() {
return true;
}
private void initializeDisplayPowerList(World world) {
if (initialized) {
return;
}
initialized = true;
RenderEntityBlock.RenderInfo block = new RenderEntityBlock.RenderInfo();
block.texture = BuildCraftTransport.instance.pipeIconProvider.getIcon(PipeIconProvider.TYPE.Power_Normal.ordinal());
float size = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;
for (int s = 0; s < POWER_STAGES; ++s) {
displayPowerList[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(displayPowerList[s], GL11.GL_COMPILE);
float minSize = 0.005F;
float unit = (size - minSize) / 2F / POWER_STAGES;
block.minY = 0.5 - (minSize / 2F) - unit * s;
block.maxY = 0.5 + (minSize / 2F) + unit * s;
block.minZ = 0.5 - (minSize / 2F) - unit * s;
block.maxZ = 0.5 + (minSize / 2F) + unit * s;
block.minX = 0;
block.maxX = 0.5 + (minSize / 2F) + unit * s;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
}
block.texture = BuildCraftTransport.instance.pipeIconProvider.getIcon(PipeIconProvider.TYPE.Power_Overload.ordinal());
size = CoreConstants.PIPE_MAX_POS - CoreConstants.PIPE_MIN_POS;
for (int s = 0; s < POWER_STAGES; ++s) {
displayPowerListOverload[s] = GLAllocation.generateDisplayLists(1);
GL11.glNewList(displayPowerListOverload[s], GL11.GL_COMPILE);
float minSize = 0.005F;
float unit = (size - minSize) / 2F / POWER_STAGES;
block.minY = 0.5 - (minSize / 2F) - unit * s;
block.maxY = 0.5 + (minSize / 2F) + unit * s;
block.minZ = 0.5 - (minSize / 2F) - unit * s;
block.maxZ = 0.5 + (minSize / 2F) + unit * s;
block.minX = 0;
block.maxX = 0.5 + (minSize / 2F) + unit * s;
RenderEntityBlock.INSTANCE.renderBlock(block);
GL11.glEndList();
}
}
@Override
public void render(Pipe<PipeTransportPower> pipe, double x, double y, double z, float f) {
initializeDisplayPowerList(pipe.container.getWorldObj());
PipeTransportPower pow = pipe.transport;
GL11.glPushMatrix();
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glTranslatef((float) x, (float) y, (float) z);
bindTexture(TextureMap.locationBlocksTexture);
int[] displayList = pow.overload > 0 ? displayPowerListOverload : displayPowerList;
for (int side = 0; side < 6; ++side) {
int stage = (int) Math.ceil(Math.pow(pow.displayPower[side], POWER_MAGIC));
if (stage >= 1) {
if (!pipe.container.isPipeConnected(ForgeDirection.getOrientation(side))) {
continue;
}
GL11.glPushMatrix();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
GL11.glRotatef(angleY[side], 0, 1, 0);
GL11.glRotatef(angleZ[side], 0, 0, 1);
float scale = 1.0F - side * 0.0001F;
GL11.glScalef(scale, scale, scale);
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
if (stage < displayList.length) {
GL11.glCallList(displayList[stage]);
} else {
GL11.glCallList(displayList[displayList.length - 1]);
}
GL11.glPopMatrix();
}
}
/*bindTexture(STRIPES_TEXTURE);
for (int side = 0; side < 6; side += 2) {
if (pipe.container.isPipeConnected(ForgeDirection.values()[side])) {
GL11.glPushMatrix();
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
GL11.glRotatef(angleY[side], 0, 1, 0);
GL11.glRotatef(angleZ[side], 0, 0, 1);
float scale = 1.0F - side * 0.0001F;
GL11.glScalef(scale, scale, scale);
float movement = (0.50F) * pipe.transport.getPistonStage(side / 2);
GL11.glTranslatef(-0.25F - 1F / 16F - movement, -0.5F, -0.5F);
// float factor = (float) (1.0 / 256.0);
float factor = (float) (1.0 / 16.0);
box.render(factor);
GL11.glPopMatrix();
}
}*/
GL11.glPopAttrib();
GL11.glPopMatrix();
}
}

View file

@ -0,0 +1,22 @@
package buildcraft.transport.render;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeTransport;
public abstract class PipeTransportRenderer<T extends PipeTransport> {
public boolean useServerTileIfPresent() {
return false;
}
@SideOnly(Side.CLIENT)
public void bindTexture(ResourceLocation location) {
Minecraft.getMinecraft().renderEngine.bindTexture(location);
}
public abstract void render(Pipe<T> pipe, double x, double y, double z, float f);
}

View file

@ -0,0 +1,10 @@
package buildcraft.transport.render;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeTransportStructure;
public class PipeTransportStructureRenderer extends PipeTransportRenderer<PipeTransportStructure> {
@Override
public void render(Pipe<PipeTransportStructure> pipe, double x, double y, double z, float f) {
}
}