package at.hannibal2.skyhanni.utils import net.minecraft.client.Minecraft import net.minecraft.client.gui.Gui import net.minecraft.client.renderer.GlStateManager import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats import net.minecraft.inventory.Slot import net.minecraft.util.AxisAlignedBB import net.minecraft.util.MathHelper import net.minecraft.util.ResourceLocation import net.minecraft.util.Vec3 import net.minecraftforge.client.event.RenderWorldLastEvent import org.lwjgl.opengl.GL11 import java.awt.Color import kotlin.math.cos import kotlin.math.sin import kotlin.math.sqrt object RenderUtils { val beaconBeam = ResourceLocation("textures/entity/beacon_beam.png") infix fun Slot.highlight(color: LorenzColor) { Gui.drawRect( this.xDisplayPosition, this.yDisplayPosition, this.xDisplayPosition + 16, this.yDisplayPosition + 16, color.toColor().rgb ) } fun RenderWorldLastEvent.drawColor(location: LorenzVec, color: LorenzColor, beacon: Boolean = false) { val (viewerX, viewerY, viewerZ) = getViewerPos(partialTicks) val x = location.x - viewerX val y = location.y - viewerY val z = location.z - viewerZ val distSq = x * x + y * y + z * z GlStateManager.disableDepth() GlStateManager.disableCull() drawFilledBoundingBox( AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1).expandBlock(), color.toColor(), (0.1f + 0.005f * distSq.toFloat()).coerceAtLeast(0.2f) ) GlStateManager.disableTexture2D() if (distSq > 5 * 5 && beacon) renderBeaconBeam(x, y + 1, z, color.toColor().rgb, 1.0f, partialTicks) GlStateManager.disableLighting() GlStateManager.enableTexture2D() GlStateManager.enableDepth() GlStateManager.enableCull() } fun getViewerPos(partialTicks: Float): LorenzVec { val viewer = Minecraft.getMinecraft().renderViewEntity val viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * partialTicks val viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * partialTicks val viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * partialTicks return LorenzVec(viewerX, viewerY, viewerZ) } /** * Taken from NotEnoughUpdates under Creative Commons Attribution-NonCommercial 3.0 * https://github.com/Moulberry/NotEnoughUpdates/blob/master/LICENSE * @author Moulberry * @author Mojang */ private fun drawFilledBoundingBox(aabb: AxisAlignedBB, c: Color, alphaMultiplier: Float = 1f) { GlStateManager.enableBlend() GlStateManager.disableLighting() GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) GlStateManager.disableTexture2D() val tessellator = Tessellator.getInstance() val worldRenderer = tessellator.worldRenderer GlStateManager.color(c.red / 255f, c.green / 255f, c.blue / 255f, c.alpha / 255f * alphaMultiplier) //vertical worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() tessellator.draw() worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() tessellator.draw() GlStateManager.color( c.red / 255f * 0.8f, c.green / 255f * 0.8f, c.blue / 255f * 0.8f, c.alpha / 255f * alphaMultiplier ) //x worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() tessellator.draw() worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() tessellator.draw() GlStateManager.color( c.red / 255f * 0.9f, c.green / 255f * 0.9f, c.blue / 255f * 0.9f, c.alpha / 255f * alphaMultiplier ) //z worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() tessellator.draw() worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() tessellator.draw() GlStateManager.enableTexture2D() GlStateManager.disableBlend() } fun AxisAlignedBB.expandBlock() = expand(0.0020000000949949026, 0.0020000000949949026, 0.0020000000949949026) /** * Taken from NotEnoughUpdates under Creative Commons Attribution-NonCommercial 3.0 * https://github.com/Moulberry/NotEnoughUpdates/blob/master/LICENSE * @author Moulberry * @author Mojang */ fun renderBeaconBeam(x: Double, y: Double, z: Double, rgb: Int, alphaMultiplier: Float, partialTicks: Float) { val height = 300 val bottomOffset = 0 val topOffset = bottomOffset + height val tessellator = Tessellator.getInstance() val worldrenderer = tessellator.worldRenderer Minecraft.getMinecraft().textureManager.bindTexture(beaconBeam) GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, 10497.0f) GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, 10497.0f) GlStateManager.disableLighting() GlStateManager.enableCull() GlStateManager.enableTexture2D() GlStateManager.tryBlendFuncSeparate(770, 1, 1, 0) GlStateManager.enableBlend() GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) val time = Minecraft.getMinecraft().theWorld.totalWorldTime + partialTicks.toDouble() val d1 = MathHelper.func_181162_h( -time * 0.2 - MathHelper.floor_double(-time * 0.1) .toDouble() ) val r = (rgb shr 16 and 0xFF) / 255f val g = (rgb shr 8 and 0xFF) / 255f val b = (rgb and 0xFF) / 255f val d2 = time * 0.025 * -1.5 val d4 = 0.5 + cos(d2 + 2.356194490192345) * 0.2 val d5 = 0.5 + sin(d2 + 2.356194490192345) * 0.2 val d6 = 0.5 + cos(d2 + Math.PI / 4.0) * 0.2 val d7 = 0.5 + sin(d2 + Math.PI / 4.0) * 0.2 val d8 = 0.5 + cos(d2 + 3.9269908169872414) * 0.2 val d9 = 0.5 + sin(d2 + 3.9269908169872414) * 0.2 val d10 = 0.5 + cos(d2 + 5.497787143782138) * 0.2 val d11 = 0.5 + sin(d2 + 5.497787143782138) * 0.2 val d14 = -1.0 + d1 val d15 = height.toDouble() * 2.5 + d14 worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR) worldrenderer.pos(x + d4, y + topOffset, z + d5).tex(1.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d4, y + bottomOffset, z + d5).tex(1.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d6, y + bottomOffset, z + d7).tex(0.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d6, y + topOffset, z + d7).tex(0.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d10, y + topOffset, z + d11).tex(1.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d10, y + bottomOffset, z + d11).tex(1.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d8, y + bottomOffset, z + d9).tex(0.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d8, y + topOffset, z + d9).tex(0.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d6, y + topOffset, z + d7).tex(1.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d6, y + bottomOffset, z + d7).tex(1.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d10, y + bottomOffset, z + d11).tex(0.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d10, y + topOffset, z + d11).tex(0.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d8, y + topOffset, z + d9).tex(1.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() worldrenderer.pos(x + d8, y + bottomOffset, z + d9).tex(1.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d4, y + bottomOffset, z + d5).tex(0.0, d14).color(r, g, b, 1.0f).endVertex() worldrenderer.pos(x + d4, y + topOffset, z + d5).tex(0.0, d15).color(r, g, b, 1.0f * alphaMultiplier) .endVertex() tessellator.draw() GlStateManager.disableCull() val d12 = -1.0 + d1 val d13 = height + d12 worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR) worldrenderer.pos(x + 0.2, y + topOffset, z + 0.2).tex(1.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.2, y + bottomOffset, z + 0.2).tex(1.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.8, y + bottomOffset, z + 0.2).tex(0.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.8, y + topOffset, z + 0.2).tex(0.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.8, y + topOffset, z + 0.8).tex(1.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.8, y + bottomOffset, z + 0.8).tex(1.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.2, y + bottomOffset, z + 0.8).tex(0.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.2, y + topOffset, z + 0.8).tex(0.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.8, y + topOffset, z + 0.2).tex(1.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.8, y + bottomOffset, z + 0.2).tex(1.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.8, y + bottomOffset, z + 0.8).tex(0.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.8, y + topOffset, z + 0.8).tex(0.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.2, y + topOffset, z + 0.8).tex(1.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() worldrenderer.pos(x + 0.2, y + bottomOffset, z + 0.8).tex(1.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.2, y + bottomOffset, z + 0.2).tex(0.0, d12).color(r, g, b, 0.25f).endVertex() worldrenderer.pos(x + 0.2, y + topOffset, z + 0.2).tex(0.0, d13).color(r, g, b, 0.25f * alphaMultiplier) .endVertex() tessellator.draw() } fun RenderWorldLastEvent.drawString(location: LorenzVec, text: String, seeThroughBlocks: Boolean = false) { GlStateManager.alphaFunc(516, 0.1f) GlStateManager.pushMatrix() val viewer = Minecraft.getMinecraft().renderViewEntity val renderManager = Minecraft.getMinecraft().renderManager var x = location.x - renderManager.viewerPosX var y = location.y - renderManager.viewerPosY - viewer.eyeHeight var z = location.z - renderManager.viewerPosZ val distSq = x * x + y * y + z * z val dist = sqrt(distSq) if (distSq > 144) { x *= 12 / dist y *= 12 / dist z *= 12 / dist } if (seeThroughBlocks) { GlStateManager.disableDepth() GlStateManager.disableCull() } GlStateManager.translate(x, y, z) GlStateManager.translate(0f, viewer.eyeHeight, 0f) drawNametag(text) GlStateManager.rotate(-renderManager.playerViewY, 0.0f, 1.0f, 0.0f) GlStateManager.rotate(renderManager.playerViewX, 1.0f, 0.0f, 0.0f) GlStateManager.translate(0f, -0.25f, 0f) GlStateManager.rotate(-renderManager.playerViewX, 1.0f, 0.0f, 0.0f) GlStateManager.rotate(renderManager.playerViewY, 0.0f, 1.0f, 0.0f) // RenderUtil.drawNametag(EnumChatFormatting.YELLOW.toString() + dist.roundToInt() + "m") GlStateManager.popMatrix() GlStateManager.disableLighting() if (seeThroughBlocks) { GlStateManager.enableDepth() GlStateManager.enableCull() } } /** * @author Mojang */ fun drawNametag(str: String?) { val fontRenderer = Minecraft.getMinecraft().fontRendererObj val f1 = 0.02666667f GlStateManager.pushMatrix() GL11.glNormal3f(0.0f, 1.0f, 0.0f) GlStateManager.rotate(-Minecraft.getMinecraft().renderManager.playerViewY, 0.0f, 1.0f, 0.0f) GlStateManager.rotate( Minecraft.getMinecraft().renderManager.playerViewX, 1.0f, 0.0f, 0.0f ) GlStateManager.scale(-f1, -f1, f1) GlStateManager.disableLighting() GlStateManager.depthMask(false) GlStateManager.enableBlend() GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) val tessellator = Tessellator.getInstance() val worldrenderer = tessellator.worldRenderer val i = 0 val j = fontRenderer.getStringWidth(str) / 2 GlStateManager.disableTexture2D() worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR) worldrenderer.pos((-j - 1).toDouble(), (-1 + i).toDouble(), 0.0).color(0.0f, 0.0f, 0.0f, 0.25f).endVertex() worldrenderer.pos((-j - 1).toDouble(), (8 + i).toDouble(), 0.0).color(0.0f, 0.0f, 0.0f, 0.25f).endVertex() worldrenderer.pos((j + 1).toDouble(), (8 + i).toDouble(), 0.0).color(0.0f, 0.0f, 0.0f, 0.25f).endVertex() worldrenderer.pos((j + 1).toDouble(), (-1 + i).toDouble(), 0.0).color(0.0f, 0.0f, 0.0f, 0.25f).endVertex() tessellator.draw() GlStateManager.enableTexture2D() fontRenderer.drawString(str, -j, i, 553648127) GlStateManager.depthMask(true) fontRenderer.drawString(str, -j, i, -1) GlStateManager.enableBlend() GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f) GlStateManager.popMatrix() } /** * @author Mojang */ fun drawLabel( pos: Vec3, text: String, color: Color, partialTicks: Float, shadow: Boolean = false, scale: Float = 1f ) { var mc = Minecraft.getMinecraft() val player = mc.thePlayer val x = pos.xCoord - player.lastTickPosX + (pos.xCoord - player.posX - (pos.xCoord - player.lastTickPosX)) * partialTicks val y = pos.yCoord - player.lastTickPosY + (pos.yCoord - player.posY - (pos.yCoord - player.lastTickPosY)) * partialTicks val z = pos.zCoord - player.lastTickPosZ + (pos.zCoord - player.posZ - (pos.zCoord - player.lastTickPosZ)) * partialTicks val renderManager = mc.renderManager val f1 = 0.0266666688 val width = mc.fontRendererObj.getStringWidth(text) / 2 GlStateManager.pushMatrix() GlStateManager.translate(x, y, z) GL11.glNormal3f(0f, 1f, 0f) GlStateManager.rotate(-renderManager.playerViewY, 0f, 1f, 0f) GlStateManager.rotate(renderManager.playerViewX, 1f, 0f, 0f) GlStateManager.scale(-f1, -f1, -f1) GlStateManager.scale(scale, scale, scale) GlStateManager.enableBlend() GlStateManager.disableLighting() GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) GlStateManager.enableTexture2D() mc.fontRendererObj.drawString(text, (-width).toFloat(), 0f, color.rgb, shadow) GlStateManager.disableBlend() GlStateManager.popMatrix() } fun interpolate(currentValue: Double, lastValue: Double, multiplier: Float): Double { return lastValue + (currentValue - lastValue) * multiplier } }