Major Update for Cable Rendering.

TESRs will are no longer used if the tile contains no dynamic renders.
Added alpha pass rendering for stained glass.
Enabled Stained Glass facades.
Cables / Facades have less geometry by hiding faces on connected boxes.
Added AlphaPass Option to disable AlphaPass Cables rendering ( fixes crash with Immbis Microblocks. )
This commit is contained in:
AlgorithmX2 2014-05-04 19:51:05 -05:00
parent 86c096c357
commit 3080510317
9 changed files with 269 additions and 14 deletions

View file

@ -289,7 +289,7 @@ public class AEBaseBlock extends BlockContainer implements IAEFeature
return null;
}
final public <T extends TileEntity> T getTileEntity(IBlockAccess w, int x, int y, int z)
public <T extends TileEntity> T getTileEntity(IBlockAccess w, int x, int y, int z)
{
if ( !hasBlockTileEntity() )
return null;

View file

@ -24,8 +24,10 @@ import appeng.api.parts.PartItemStack;
import appeng.api.parts.SelectedPart;
import appeng.block.AEBaseBlock;
import appeng.client.render.BaseBlockRender;
import appeng.client.render.BusRenderHelper;
import appeng.client.render.blocks.RendererCableBus;
import appeng.client.texture.ExtraTextures;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.core.CommonHelper;
@ -35,12 +37,28 @@ import appeng.parts.ICableBusContainer;
import appeng.parts.NullCableBusContainer;
import appeng.tile.AEBaseTile;
import appeng.tile.networking.TileCableBus;
import appeng.tile.networking.TileCableBusTESR;
import appeng.util.Platform;
public class BlockCableBus extends AEBaseBlock
{
static private ICableBusContainer nullCB = new NullCableBusContainer();
static public Class<? extends TileEntity> noTesrTile;
static public Class<? extends TileEntity> tesrTile;
public <T extends TileEntity> T getTileEntity(IBlockAccess w, int x, int y, int z)
{
TileEntity te = w.getTileEntity( x, y, z );
if ( noTesrTile.isInstance( te ) )
return (T) te;
if ( tesrTile.isInstance( te ) )
return (T) te;
return null;
}
public BlockCableBus() {
super( BlockCableBus.class, Material.glass );
@ -49,6 +67,25 @@ public class BlockCableBus extends AEBaseBlock
isFullSize = isOpaque = false;
}
@Override
public int getRenderBlockPass()
{
if ( AEConfig.instance.isFeatureEnabled( AEFeature.AlphaPass ) )
return 1;
return 0;
}
@Override
public boolean canRenderInPass(int pass)
{
BusRenderHelper.instance.setPass( pass );
if ( AEConfig.instance.isFeatureEnabled( AEFeature.AlphaPass ) )
return true;
return pass == 0;
}
@Override
public boolean isLadder(IBlockAccess world, int x, int y, int z, EntityLivingBase entity)
{
@ -229,9 +266,12 @@ public class BlockCableBus extends AEBaseBlock
public void setupTile()
{
setTileEntiy( Api.instance.partHelper.getCombinedInstance( TileCableBus.class.getName() ) );
setTileEntiy( noTesrTile = Api.instance.partHelper.getCombinedInstance( TileCableBus.class.getName() ) );
if ( Platform.isClient() )
CommonHelper.proxy.bindTileEntitySpecialRenderer( getTileEntityClass(), this );
{
tesrTile = Api.instance.partHelper.getCombinedInstance( TileCableBusTESR.class.getName() );
CommonHelper.proxy.bindTileEntitySpecialRenderer( tesrTile, this );
}
}
private ICableBusContainer cb(IBlockAccess w, int x, int y, int z)

View file

@ -13,6 +13,8 @@ import appeng.api.parts.IPartCollsionHelper;
import appeng.api.parts.IPartRenderHelper;
import appeng.api.parts.ISimplifiedBundle;
import appeng.block.AEBaseBlock;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ -103,6 +105,39 @@ public class BusRenderHelper implements IPartRenderHelper
BoundBoxCalculator bbc = new BoundBoxCalculator();
int renderingForPass = 0;
int currentPass = 0;
int itemsRendered = 0;
boolean noAlphaPass = AEConfig.instance.isFeatureEnabled( AEFeature.AlphaPass ) == false;
public int getItemsRendered()
{
return itemsRendered;
}
public void setPass(int pass)
{
renderingForPass = 0;
currentPass = pass;
itemsRendered = 0;
}
@Override
public void renderForPass(int pass)
{
renderingForPass = pass;
}
public boolean renderThis()
{
if ( renderingForPass == currentPass || noAlphaPass )
{
itemsRendered++;
return true;
}
return false;
}
@Override
public void normalRendering()
{
@ -255,6 +290,9 @@ public class BusRenderHelper implements IPartRenderHelper
@Override
public void renderBlock(int x, int y, int z, RenderBlocks renderer)
{
if ( !renderThis() )
return;
AEBaseBlock blk = (AEBaseBlock) AEApi.instance().blocks().blockMultiPart.block();
BlockRenderInfo info = blk.getRendererInstance();
ForgeDirection forward = BusRenderHelper.instance.az;
@ -285,14 +323,26 @@ public class BusRenderHelper implements IPartRenderHelper
bbr.renderBlockBounds( renderer, minX, minY, minZ, maxX, maxY, maxZ, ax, ay, az );
}
@Override
public void setFacesToRender(EnumSet<ForgeDirection> faces)
{
BusRenderer.instance.renderer.faces = faces;
}
public void renderBlockCurrentBounds(int x, int y, int z, RenderBlocks renderer)
{
if ( !renderThis() )
return;
renderer.renderStandardBlock( renderer.blockAccess.getBlock( x, y, z ), x, y, z );
}
@Override
public void renderFaceCutout(int x, int y, int z, IIcon ico, ForgeDirection face, float edgeThickness, RenderBlocks renderer)
{
if ( !renderThis() )
return;
switch (face)
{
case DOWN:
@ -325,6 +375,9 @@ public class BusRenderHelper implements IPartRenderHelper
@Override
public void renderFace(int x, int y, int z, IIcon ico, ForgeDirection face, RenderBlocks renderer)
{
if ( !renderThis() )
return;
prepareBounds( renderer );
switch (face)
{

View file

@ -7,6 +7,7 @@ import net.minecraft.world.IBlockAccess;
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
import appeng.block.AEBaseBlock;
import appeng.client.render.BaseBlockRender;
import appeng.client.render.BusRenderHelper;
import appeng.client.render.BusRenderer;
import appeng.tile.AEBaseTile;
import appeng.tile.networking.TileCableBus;
@ -38,7 +39,7 @@ public class RendererCableBus extends BaseBlockRender
BusRenderer.instance.renderer.renderAllFaces = false;
}
return true;
return BusRenderHelper.instance.getItemsRendered() > 0;
}
@Override

View file

@ -8,8 +8,10 @@ import net.minecraft.client.renderer.Tessellator;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;
@ -17,6 +19,7 @@ import org.lwjgl.opengl.GL11;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.IPartCollsionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartRenderHelper;
import appeng.client.render.BusRenderHelper;
import appeng.client.render.RenderBlocksWorkaround;
@ -89,11 +92,16 @@ public class FacadePart implements IFacadePart
{
ItemStack randomItem = getTexture();
if ( renderStilt && busBounds == null )
{
RenderBlocksWorkaround rbw = null;
if ( renderer instanceof RenderBlocksWorkaround )
{
RenderBlocksWorkaround rbw = (RenderBlocksWorkaround) renderer;
rbw = (RenderBlocksWorkaround) renderer;
}
if ( renderStilt && busBounds == null )
{
if ( rbw != null )
{
rbw.isFacade = false;
rbw.calculations = true;
}
@ -127,6 +135,11 @@ public class FacadePart implements IFacadePart
ItemBlock ib = (ItemBlock) randomItem.getItem();
Block blk = Block.getBlockFromItem( ib );
if ( blk.canRenderInPass( 1 ) )
{
instance.renderForPass( 1 );
}
try
{
int color = ib.getColorFromItemStack( randomItem, 0 );
@ -140,10 +153,8 @@ public class FacadePart implements IFacadePart
instance.setBounds( 0, 0, 16 - getFacadeThickness(), 16, 16, 16 );
instance.prepareBounds( renderer );
if ( renderer instanceof RenderBlocksWorkaround )
if ( rbw != null )
{
RenderBlocksWorkaround rbw = (RenderBlocksWorkaround) renderer;
rbw.isFacade = true;
rbw.calculations = true;
@ -152,7 +163,7 @@ public class FacadePart implements IFacadePart
rbw.renderStandardBlock( blk, x, y, z );
rbw.calculations = false;
rbw.faces = EnumSet.allOf( ForgeDirection.class );
rbw.faces = calculateFaceOpenFaces( rbw.blockAccess, fc, x, y, z, side );
((RenderBlocksWorkaround) renderer).setTexture(
blk.getIcon( ForgeDirection.DOWN.ordinal(), ib.getMetadata( randomItem.getItemDamage() ) ),
@ -248,6 +259,12 @@ public class FacadePart implements IFacadePart
}
}
if ( rbw != null )
{
rbw.faces = EnumSet.allOf( ForgeDirection.class );
}
instance.renderForPass( 0 );
instance.setTexture( null );
Tessellator.instance.setColorOpaque_F( 1, 1, 1 );
@ -265,6 +282,63 @@ public class FacadePart implements IFacadePart
}
}
private EnumSet<ForgeDirection> calculateFaceOpenFaces(IBlockAccess blockAccess, IFacadeContainer fc, int x, int y, int z, ForgeDirection side)
{
EnumSet<ForgeDirection> out = EnumSet.of( side, side.getOpposite() );
IFacadePart facade = fc.getFacade( side );
for (ForgeDirection it : ForgeDirection.VALID_DIRECTIONS)
{
if ( !out.contains( it ) && alphaDiff( blockAccess.getTileEntity( x + it.offsetX, y + it.offsetY, z + it.offsetZ ), side, facade ) )
{
out.add( it );
}
}
if ( out.contains( ForgeDirection.UP ) && (side.offsetX != 0 || side.offsetZ != 0) )
{
IFacadePart fp = fc.getFacade( ForgeDirection.UP );
if ( fp != null && (fp.isTransparent() == facade.isTransparent()) )
out.remove( ForgeDirection.UP );
}
if ( out.contains( ForgeDirection.DOWN ) && (side.offsetX != 0 || side.offsetZ != 0) )
{
IFacadePart fp = fc.getFacade( ForgeDirection.DOWN );
if ( fp != null && (fp.isTransparent() == facade.isTransparent()) )
out.remove( ForgeDirection.DOWN );
}
if ( out.contains( ForgeDirection.SOUTH ) && (side.offsetX != 0) )
{
IFacadePart fp = fc.getFacade( ForgeDirection.SOUTH );
if ( fp != null && (fp.isTransparent() == facade.isTransparent()) )
out.remove( ForgeDirection.SOUTH );
}
if ( out.contains( ForgeDirection.NORTH ) && (side.offsetX != 0) )
{
IFacadePart fp = fc.getFacade( ForgeDirection.NORTH );
if ( fp != null && (fp.isTransparent() == facade.isTransparent()) )
out.remove( ForgeDirection.NORTH );
}
return out;
}
private boolean alphaDiff(TileEntity tileEntity, ForgeDirection side, IFacadePart facade)
{
if ( tileEntity instanceof IPartHost )
{
IPartHost ph = (IPartHost) tileEntity;
IFacadePart fp = ph.getFacadeContainer().getFacade( side );
return fp == null || (fp.isTransparent() != facade.isTransparent());
}
return true;
}
@SideOnly(Side.CLIENT)
private void renderSegmentBlockCurrentBounds(BusRenderHelper instance, int x, int y, int z, RenderBlocks renderer, double minX, double minY, double minZ,
double maxX, double maxY, double maxZ)
@ -421,4 +495,15 @@ public class FacadePart implements IFacadePart
{
thickness = useThinFacades ? 1 : 2;
}
@Override
public boolean isTransparent()
{
ItemStack is = getTexture();
Block blk = Block.getBlockFromItem( is.getItem() );
if ( !blk.isOpaqueCube() )
return true;
return false;
}
}

View file

@ -34,7 +34,10 @@ import appeng.api.parts.SelectedPart;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.client.render.BusRenderHelper;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.helpers.AEMultiTile;
import appeng.parts.BusCollisionHelper;
import appeng.parts.CableBusContainer;
@ -259,8 +262,9 @@ public class CableBusPart extends JCuboidPart implements JNormalOcclusion, IReds
@Override
public void renderDynamic(Vector3 pos, float frame, int pass)
{
if ( pass == 0 )
if ( pass == 0 || (pass == 1 && AEConfig.instance.isFeatureEnabled( AEFeature.AlphaPass )) )
{
BusRenderHelper.instance.setPass( pass );
cb.renderDynamic( pos.x, pos.y, pos.z );
}
}
@ -268,10 +272,11 @@ public class CableBusPart extends JCuboidPart implements JNormalOcclusion, IReds
@Override
public boolean renderStatic(Vector3 pos, int pass)
{
if ( pass == 0 )
if ( pass == 0 || (pass == 1 && AEConfig.instance.isFeatureEnabled( AEFeature.AlphaPass )) )
{
BusRenderHelper.instance.setPass( pass );
cb.renderStatic( pos.x, pos.y, pos.z );
return true;
return BusRenderHelper.instance.getItemsRendered() > 0;
}
return false;
}
@ -475,7 +480,9 @@ public class CableBusPart extends JCuboidPart implements JNormalOcclusion, IReds
public void markForSave()
{
// mark the chunk for save...
this.getTile().getWorldObj().getChunkFromBlockCoords( x(), z() ).isModified = true;
TileEntity te = getTile();
if ( te != null && te.getWorldObj() != null )
te.getWorldObj().getChunkFromBlockCoords( x(), z() ).isModified = true;
}
@Override

View file

@ -406,6 +406,8 @@ public class PartCable extends AEBasePart implements IPartCable
default:
return;
}
rh.setFacesToRender( EnumSet.complementOf( EnumSet.of( of ) ) );
rh.renderBlock( x, y, z, renderer );
rh.setTexture( getTexture( getCableColor() ) );
@ -436,7 +438,10 @@ public class PartCable extends AEBasePart implements IPartCable
default:
return;
}
rh.setFacesToRender( EnumSet.complementOf( EnumSet.of( of, of.getOpposite() ) ) );
rh.renderBlock( x, y, z, renderer );
rh.setFacesToRender( EnumSet.allOf( ForgeDirection.class ) );
}
protected CableBusTextures getChannelTex(int i, boolean b)
@ -486,6 +491,7 @@ public class PartCable extends AEBasePart implements IPartCable
IGridHost ghh = te instanceof IGridHost ? (IGridHost) te : null;
boolean isSmart = false;
rh.setFacesToRender( EnumSet.complementOf( EnumSet.of( of, of.getOpposite() ) ) );
if ( ghh != null && ccph != null && ghh.getCableConnectionType( of.getOpposite() ) == AECableType.GLASS && ccph.getPart( of.getOpposite() ) == null
&& ccph.getColor() != AEColor.Transparent )
rh.setTexture( getGlassTexture( ccph.getColor() ) );
@ -515,6 +521,7 @@ public class PartCable extends AEBasePart implements IPartCable
default:
return;
}
rh.renderBlock( x, y, z, renderer );
rh.setTexture( getTexture( getCableColor() ) );
@ -579,6 +586,8 @@ public class PartCable extends AEBasePart implements IPartCable
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;
}
rh.setFacesToRender( EnumSet.allOf( ForgeDirection.class ) );
}
@SideOnly(Side.CLIENT)
@ -590,6 +599,8 @@ public class PartCable extends AEBasePart implements IPartCable
boolean isGlass = false;
AEColor myColor = getCableColor();
rh.setFacesToRender( EnumSet.complementOf( EnumSet.of( of, of.getOpposite() ) ) );
if ( ghh != null && ccph != null && ghh.getCableConnectionType( of.getOpposite() ) == AECableType.GLASS && ccph.getPart( of.getOpposite() ) == null
&& ccph.getColor() != AEColor.Transparent )
{
@ -702,6 +713,8 @@ public class PartCable extends AEBasePart implements IPartCable
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;
}
rh.setFacesToRender( EnumSet.allOf( ForgeDirection.class ) );
}
@SideOnly(Side.CLIENT)
@ -737,6 +750,7 @@ public class PartCable extends AEBasePart implements IPartCable
break;
}
}
@SideOnly(Side.CLIENT)

View file

@ -26,6 +26,7 @@ import appeng.api.parts.SelectedPart;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.block.networking.BlockCableBus;
import appeng.helpers.AEMultiTile;
import appeng.helpers.ICustomCollision;
import appeng.hooks.TickHandler;
@ -74,6 +75,7 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl
// worldObj.updateAllLightTypes( xCoord, yCoord, zCoord );
}
updateTileSetting();
return ret;
}
@ -85,6 +87,32 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl
};
protected void updateTileSetting()
{
if ( cb.requiresDynamicRender )
{
TileCableBus tcb;
try
{
tcb = (TileCableBus) BlockCableBus.tesrTile.newInstance();
tcb.copyFrom( this );
getWorldObj().setTileEntity( xCoord, yCoord, zCoord, tcb );
}
catch (Throwable t)
{
}
}
}
protected void copyFrom(TileCableBus oldTile)
{
CableBusContainer tmpCB = cb;
cb = oldTile.cb;
oldLV = oldTile.oldLV;
oldTile.cb = tmpCB;
}
@Override
public void onReady()
{

View file

@ -0,0 +1,27 @@
package appeng.tile.networking;
import appeng.block.networking.BlockCableBus;
public class TileCableBusTESR extends TileCableBus
{
@Override
protected void updateTileSetting()
{
if ( !cb.requiresDynamicRender )
{
TileCableBus tcb;
try
{
tcb = (TileCableBus) BlockCableBus.noTesrTile.newInstance();
tcb.copyFrom( this );
getWorldObj().setTileEntity( xCoord, yCoord, zCoord, tcb );
}
catch (Throwable t)
{
}
}
}
}