package openblocks.client.renderer.block; import static openblocks.client.renderer.tileentity.tank.INeighbourMap.DIR_DOWN; import static openblocks.client.renderer.tileentity.tank.INeighbourMap.DIR_EAST; import static openblocks.client.renderer.tileentity.tank.INeighbourMap.DIR_NORTH; import static openblocks.client.renderer.tileentity.tank.INeighbourMap.DIR_SOUTH; import static openblocks.client.renderer.tileentity.tank.INeighbourMap.DIR_UP; import static openblocks.client.renderer.tileentity.tank.INeighbourMap.DIR_WEST; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import openblocks.client.renderer.tileentity.tank.INeighbourMap; import openblocks.common.block.BlockTank; import openblocks.common.tileentity.TileEntityTank; import openmods.renderer.DisplayListWrapper; import openmods.renderer.IBlockRenderer; import openmods.utils.render.RenderUtils; import org.lwjgl.opengl.GL11; public class BlockTankRenderer implements IBlockRenderer<BlockTank> { private static final double H = 0.01; public static final DisplayListWrapper EMPTY_FRAME = new DisplayListWrapper() { @Override public void compile() { GL11.glColor3f(1, 1, 1); GL11.glDisable(GL11.GL_TEXTURE_2D); final Tessellator tes = new Tessellator(); tes.startDrawingQuads(); tes.setColorOpaque(0, 0, 0); tes.setTextureUV(0, 0); BlockTankRenderer.render(tes, INeighbourMap.NO_NEIGHBOURS, 0, 0, 0); tes.draw(); GL11.glEnable(GL11.GL_TEXTURE_2D); } }; // Can I interest you in Karnaugh maps? -B // This whole logic stuff would be really hard to document here. Sorry. // Symmetry of equations is broken by special casing for blocks on diagonal // (to prevent edge from being drawn twice) private static boolean shouldRenderEdgeT(INeighbourMap connections, int d1, int d2) { final boolean n1 = connections.hasDirectNeighbour(d1); final boolean n2 = connections.hasDirectNeighbour(d2); final boolean n12 = connections.hasDiagonalNeighbour(d1, d2); return (n1 == n2) & !n12; } private static boolean shouldRenderEdgeB(INeighbourMap connections, int d1, int d2) { final boolean n1 = connections.hasDirectNeighbour(d1); final boolean n2 = connections.hasDirectNeighbour(d2); final boolean n12 = connections.hasDiagonalNeighbour(d1, d2); return (!n2 & !n1) | (n2 & !n12 & n1); } private static void render(Tessellator tes, INeighbourMap connections, double x, double y, double z) { if (shouldRenderEdgeT(connections, DIR_SOUTH, DIR_DOWN)) RenderUtils.renderCube(tes, x - H + 0, y - H + 0, z - H + 1, x + H + 1, y + H + 0, z + H + 1); if (shouldRenderEdgeT(connections, DIR_NORTH, DIR_DOWN)) RenderUtils.renderCube(tes, x - H + 0, y - H + 0, z - H + 0, x + H + 1, y + H + 0, z + H + 0); if (shouldRenderEdgeB(connections, DIR_SOUTH, DIR_UP)) RenderUtils.renderCube(tes, x - H + 0, y - H + 1, z - H + 1, x + H + 1, y + H + 1, z + H + 1); if (shouldRenderEdgeB(connections, DIR_NORTH, DIR_UP)) RenderUtils.renderCube(tes, x - H + 0, y - H + 1, z - H + 0, x + H + 1, y + H + 1, z + H + 0); if (shouldRenderEdgeT(connections, DIR_EAST, DIR_NORTH)) RenderUtils.renderCube(tes, x - H + 1, y - H + 0, z - H + 0, x + H + 1, y + H + 1, z + H + 0); if (shouldRenderEdgeT(connections, DIR_WEST, DIR_NORTH)) RenderUtils.renderCube(tes, x - H + 0, y - H + 0, z - H + 0, x + H + 0, y + H + 1, z + H + 0); if (shouldRenderEdgeB(connections, DIR_EAST, DIR_SOUTH)) RenderUtils.renderCube(tes, x - H + 1, y - H + 0, z - H + 1, x + H + 1, y + H + 1, z + H + 1); if (shouldRenderEdgeB(connections, DIR_WEST, DIR_SOUTH)) RenderUtils.renderCube(tes, x - H + 0, y - H + 0, z - H + 1, x + H + 0, y + H + 1, z + H + 1); if (shouldRenderEdgeT(connections, DIR_EAST, DIR_DOWN)) RenderUtils.renderCube(tes, x - H + 1, y - H + 0, z - H + 0, x + H + 1, y + H + 0, z + H + 1); if (shouldRenderEdgeT(connections, DIR_WEST, DIR_DOWN)) RenderUtils.renderCube(tes, x - H + 0, y - H + 0, z - H + 0, x + H + 0, y + H + 0, z + H + 1); if (shouldRenderEdgeB(connections, DIR_EAST, DIR_UP)) RenderUtils.renderCube(tes, x - H + 1, y - H + 1, z - H + 0, x + H + 1, y + H + 1, z + H + 1); if (shouldRenderEdgeB(connections, DIR_WEST, DIR_UP)) RenderUtils.renderCube(tes, x - H + 0, y - H + 1, z - H + 0, x + H + 0, y + H + 1, z + H + 1); } @Override public void renderInventoryBlock(BlockTank block, int metadata, int modelID, RenderBlocks renderer) { EMPTY_FRAME.render(); // not actually used, since there is custom item renderer } @Override public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, BlockTank block, int modelId, RenderBlocks renderer) { if (renderer.hasOverrideBlockTexture()) { // breaking animation handling renderer.setRenderBoundsFromBlock(block); renderer.renderStandardBlock(block, x, y, z); return true; } TileEntity te = world.getTileEntity(x, y, z); INeighbourMap connections = (te instanceof TileEntityTank)? ((TileEntityTank)te).getRenderNeigbourMap() : INeighbourMap.NO_NEIGHBOURS; final IIcon icon = block.getIcon(); Tessellator.instance.setTextureUV(icon.getMinU(), icon.getMinV()); Tessellator.instance.setColorOpaque(255, 255, 255); render(Tessellator.instance, connections, x, y, z); return true; } }