package com.rwtema.funkylocomotion.rendering; import org.lwjgl.opengl.GL11; import com.rwtema.funkylocomotion.blocks.TileMovingClient; import com.rwtema.funkylocomotion.fakes.FakeWorldClient; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.init.Blocks; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.client.MinecraftForgeClient; public class TESRMoving extends TileEntitySpecialRenderer<TileMovingClient> { private BlockRendererDispatcher blockRenderer; public static final TESRMoving INSTANCE = new TESRMoving(); @Override public final void renderTileEntityAt(TileMovingClient te, double x, double y, double z, float partialTicks, int destroyStage) { Tessellator tessellator = Tessellator.getInstance(); VertexBuffer renderer = tessellator.getBuffer(); this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); RenderHelper.disableStandardItemLighting(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.enableBlend(); GlStateManager.enableCull(); if (Minecraft.isAmbientOcclusionEnabled()) { GlStateManager.shadeModel(GL11.GL_SMOOTH); } else { GlStateManager.shadeModel(GL11.GL_FLAT); } renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, renderer); renderer.setTranslation(0, 0, 0); RenderHelper.enableStandardItemLighting(); } @Override public void renderTileEntityFast(TileMovingClient te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer renderer) { if (blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); if (!te.init) return; if (te.maxTime == 0 || te.block == Blocks.AIR) return; Tessellator tessellator = Tessellator.getInstance(); double h = te.offset(true); int dir = te.dir; if (dir == -1) { return; } this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); boolean flag = false; int pass = MinecraftForgeClient.getRenderPass(); if (te.render && te.getState().getRenderType() != EnumBlockRenderType.INVISIBLE) { GlStateManager.pushMatrix(); renderer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); setupTranslations(x, y, z, te, h, dir, renderer); flag = renderStatic(te, pass, renderer); if (pass == 1) { BlockPos pos = te.getPos(); if (dir < 6) { EnumFacing dir1 = EnumFacing.values()[dir]; renderer.sortVertexData( -(float) (x - pos.getX() + dir1.getFrontOffsetX() * h), -(float) (y - pos.getY() + dir1.getFrontOffsetY() * h), -(float) (z - pos.getZ() + dir1.getFrontOffsetZ() * h)); } else { renderer.sortVertexData( -(float) (x - pos.getX()), -(float) (y - pos.getY()), -(float) (z - pos.getZ())); } } tessellator.draw(); GlStateManager.popMatrix(); GlStateManager.enableCull(); } flag = flag | renderDynamic(x, y, z, partialTicks, te, h, dir, pass, renderer); } protected boolean renderDynamic(double x, double y, double z, float f, TileMovingClient mover, double h, int dir, int pass, VertexBuffer renderer) { if (mover.tile == null || !mover.tile.shouldRenderInPass(pass)) return false; World world = mover.getWorld(); if (!FakeWorldClient.isValid(world)) { return false; } FakeWorldClient fakeWorldClient = FakeWorldClient.getFakeWorldWrapper(world); EnumFacing dir1 = mover.getDir(); if (dir1 != null) { fakeWorldClient.offset = mover.offset(true); fakeWorldClient.dir = dir1; } else { fakeWorldClient.offset = 0; fakeWorldClient.dir = null; } fakeWorldClient.dir_id = mover.dir; TileEntitySpecialRenderer<TileEntity> specialRenderer = TileEntityRendererDispatcher.instance.getSpecialRenderer(mover.tile); if (specialRenderer == null) return false; if (!mover.tile.shouldRenderInPass(pass)) return false; GlStateManager.pushMatrix(); setupTranslations(x, y, z, mover, h, dir, renderer); try { WorldClient prevWorld1 = Minecraft.getMinecraft().world; World prevWorld2 = Minecraft.getMinecraft().player.world; World prevWorld3 = rendererDispatcher.world; try { Minecraft.getMinecraft().world = fakeWorldClient; Minecraft.getMinecraft().player.world = fakeWorldClient; TileEntityRendererDispatcher.instance.world = fakeWorldClient; renderer.setTranslation(0, 0, 0); mover.tile.updateContainingBlockInfo(); RenderHelper.enableStandardItemLighting(); specialRenderer.renderTileEntityAt(mover.tile, mover.getPos().getX(), mover.getPos().getY(), mover.getPos().getZ(), f, -1); RenderHelper.disableStandardItemLighting(); renderer.setTranslation(0, 0, 0); } finally { Minecraft.getMinecraft().world = prevWorld1; Minecraft.getMinecraft().player.world = prevWorld2; TileEntityRendererDispatcher.instance.world = prevWorld3; } } catch (Exception e) { FLRenderHelper.clearTessellator(); (new RuntimeException( "Unable to render TSER " + mover.tile.getClass().getName() + " for " + Block.REGISTRY.getNameForObject(mover.block) + " with meta " + mover.meta + " at (" + mover.getPos() + "). Disabling Rendering." , e )).printStackTrace(); TileMovingClient.renderErrorList.add(mover.tile.getClass()); mover.error = true; mover.tile = null; mover.render = false; } GlStateManager.popMatrix(); return true; } private void setupTranslations(double x, double y, double z, TileMovingClient mover, double h, int dir, VertexBuffer renderer) { BlockPos pos = mover.getPos(); if (dir < 6) { EnumFacing dir1 = EnumFacing.values()[dir]; renderer.setTranslation(0, 0, 0); GlStateManager.translate((x - pos.getX() + dir1.getFrontOffsetX() * h), (y - pos.getY() + dir1.getFrontOffsetY() * h), (z - pos.getZ() + dir1.getFrontOffsetZ() * h)); // renderer.setTranslation( // x - pos.getX() + dir1.getFrontOffsetX() * h, // y - pos.getY() + dir1.getFrontOffsetY() * h, // z - pos.getZ() + dir1.getFrontOffsetZ() * h); } else { renderer.setTranslation(0, 0, 0); GlStateManager.translate(x, y, z); GlStateManager.translate(0.5, 0.5, 0.5); double dh = dir == 6 ? h + 1 : -h; GlStateManager.scale(dh, dh, dh); GlStateManager.translate(-0.5, -0.5, -0.5); GlStateManager.translate(-pos.getX(), -pos.getY(), -pos.getZ()); } } private boolean renderStatic(TileMovingClient tile, int pass, VertexBuffer vertexbuffer) { IBlockState state = tile.getState(); Block block = state.getBlock(); FakeWorldClient fakeWorldWrapper = FakeWorldClient.getFakeWorldWrapper(tile.getWorld()); EnumFacing dir1 = tile.getDir(); if (dir1 != null) { fakeWorldWrapper.offset = tile.offset(true); fakeWorldWrapper.dir = dir1; } else { fakeWorldWrapper.offset = 0; fakeWorldWrapper.dir = null; } fakeWorldWrapper.dir_id = tile.dir; boolean flag = false; for (BlockRenderLayer blockrenderlayer1 : PassHandler.getHandler(pass).layers) { if (!block.canRenderInLayer(state, blockrenderlayer1)) continue; net.minecraftforge.client.ForgeHooksClient.setRenderLayer(blockrenderlayer1); if (block.getDefaultState().getRenderType() != EnumBlockRenderType.INVISIBLE) { flag = flag | blockRenderer.renderBlock(state, tile.getPos(), fakeWorldWrapper, vertexbuffer); } } net.minecraftforge.client.ForgeHooksClient.setRenderLayer(null); return flag; } }