package speedytools.clientside.rendering; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.eventhandler.Event; import org.lwjgl.opengl.GL11; import speedytools.clientside.ClientSide; import java.util.ArrayList; import java.util.Collection; /** * User: The Grey Ghost * Date: 18/04/2014 * * This class is used to render the boundary field (translucent cuboid) * Usage: * (1) Call the constructor, providing a BoundaryFieldRenderInfoUpdateLink: * This interface is used to fill the supplied BoundaryFieldRenderInfo with the requested information for a render. * (2) When ready to render, call .render. */ public class RendererBoundaryField implements RendererElement { public RendererBoundaryField(BoundaryFieldRenderInfoUpdateLink i_infoProvider) { infoProvider = i_infoProvider; renderInfo = new BoundaryFieldRenderInfo(); } /** * Which events is this RendererElement interested in? * * @return a collection of events that the Renderer wants to receive. */ @Override public Collection<Class<? extends Event>> eventsToReceive() { ArrayList<Class<? extends Event>> retval = new ArrayList<Class<? extends Event>>(); retval.add(RenderWorldLastEvent.class); return retval; } @Override public void render(Event event, float partialTick) { RenderWorldLastEvent fullEvent = (RenderWorldLastEvent)event; RenderGlobal context = fullEvent.context; EntityPlayer player = (EntityPlayer)(Minecraft.getMinecraft().getRenderViewEntity()); renderWorld(player, ClientSide.getGlobalTickCount(), partialTick); } /** * render the boundary field if there is one selected * @param player * @param animationTickCount * @param partialTick */ public void renderWorld(EntityPlayer player, int animationTickCount, float partialTick) { Vec3 playerPositionEyes = player.getPositionEyes(partialTick); boolean shouldIRender = infoProvider.refreshRenderInfo(renderInfo, playerPositionEyes); if (!shouldIRender) return; try { GL11.glPushAttrib(GL11.GL_ENABLE_BIT); GL11.glPushMatrix(); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F); GL11.glLineWidth(2.0F); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glDepthMask(false); double EXPAND_BOX_DISTANCE = 0.002F; AxisAlignedBB boundingBox = renderInfo.boundaryFieldAABB; // Vec3 playerPositionFeet = playerPositionEyes.subtract(0, player.getEyeHeight(), 0); GlStateManager.translate(0.0F, player.getEyeHeight(), 0.0F); // put [0,0,0] at eye height boundingBox = boundingBox.expand(EXPAND_BOX_DISTANCE, EXPAND_BOX_DISTANCE, EXPAND_BOX_DISTANCE) .offset(-playerPositionEyes.xCoord, -playerPositionEyes.yCoord, -playerPositionEyes.zCoord); int faceToHighlight = -1; if (renderInfo.boundaryGrabActivated) { faceToHighlight = renderInfo.boundaryGrabSide; } else { faceToHighlight = renderInfo.boundaryCursorSide; } SelectionBoxRenderer.drawFilledCubeWithSelectedSide(boundingBox, faceToHighlight, renderInfo.boundaryGrabActivated); } finally { GL11.glPopMatrix(); GL11.glDepthMask(true); GL11.glPopAttrib(); } } /** The BoundaryFieldRenderInfoUpdateLink and BoundaryFieldRenderInfo are used to retrieve the necessary information for rendering from the current tool * If refreshRenderInfo returns false, no render is performed. */ public interface BoundaryFieldRenderInfoUpdateLink { public boolean refreshRenderInfo(BoundaryFieldRenderInfo infoToUpdate, Vec3 playerPosition); } public static class BoundaryFieldRenderInfo { public AxisAlignedBB boundaryFieldAABB; public boolean boundaryGrabActivated; public int boundaryGrabSide; public int boundaryCursorSide; } BoundaryFieldRenderInfoUpdateLink infoProvider; BoundaryFieldRenderInfo renderInfo; }