PhysicalConnectivity/src/main/kotlin/net/shadowfacts/cacao/util/RenderHelper.kt

130 lines
4.1 KiB
Kotlin

package net.shadowfacts.cacao.util
import com.mojang.blaze3d.platform.GlStateManager
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawableHelper
import net.minecraft.client.render.*
import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.sound.SoundEvent
import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.util.texture.Texture
import org.lwjgl.opengl.GL11
/**
* Helper methods for rendering using Minecraft's utilities from Cacao views.
* For unit testing, all drawing and OpenGL interaction can be disabled by setting the `cacao.drawing.disabled` JVM property to `true`.
*
* @author shadowfacts
*/
object RenderHelper {
val disabled = (System.getProperty("cacao.drawing.disabled") ?: "false").toBoolean()
// TODO: find a better place for this
fun playSound(event: SoundEvent) {
if (disabled) return
MinecraftClient.getInstance().soundManager.play(PositionedSoundInstance.master(event, 1f))
}
/**
* Draws a solid [rect] filled with the given [color].
*/
fun fill(matrixStack: MatrixStack, rect: Rect, color: Color) {
if (disabled) return
DrawableHelper.fill(matrixStack, rect.left.toInt(), rect.top.toInt(), rect.right.toInt(), rect.bottom.toInt(), color.argb)
}
/**
* Binds and draws the given [texture] filling the [rect].
*/
fun draw(rect: Rect, texture: Texture) {
if (disabled) return
color(1f, 1f, 1f, 1f)
MinecraftClient.getInstance().textureManager.bindTexture(texture.location)
draw(rect.left, rect.top, texture.u, texture.v, rect.width, rect.height, texture.width, texture.height)
}
fun drawLine(start: Point, end: Point, z: Double, width: Float, color: Color) {
if (disabled) return
GlStateManager.lineWidth(width)
val tessellator = Tessellator.getInstance()
val buffer = tessellator.buffer
buffer.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR)
buffer.vertex(start.x, start.y, z).color(color).next()
buffer.vertex(end.x, end.y, z).color(color).next()
tessellator.draw()
}
/**
* Draws the bound texture with the given screen and texture position and size.
*/
fun draw(x: Double, y: Double, u: Int, v: Int, width: Double, height: Double, textureWidth: Int, textureHeight: Int) {
if (disabled) return
val uStart = u.toFloat() / textureWidth
val uEnd = (u + width).toFloat() / textureWidth
val vStart = v.toFloat() / textureHeight
val vEnd = (v + height).toFloat() / textureHeight
drawTexturedQuad(x, x + width, y, y + height, 0.0, uStart, uEnd, vStart, vEnd)
}
// Copied from net.minecraft.client.gui.DrawableHelper
private fun drawTexturedQuad(xStart: Double, xEnd: Double, yStart: Double, yEnd: Double, z: Double, uStart: Float, uEnd: Float, vStart: Float, vEnd: Float) {
val tessellator = Tessellator.getInstance()
val buffer = tessellator.buffer
buffer.begin(GL11.GL_QUADS, VertexFormats.POSITION_TEXTURE)
buffer.vertex(xStart, yEnd, z).texture(uStart, vEnd).next()
buffer.vertex(xEnd, yEnd, z).texture(uEnd, vEnd).next()
buffer.vertex(xEnd, yStart, z).texture(uEnd, vStart).next()
buffer.vertex(xStart, yStart, z).texture(uStart, vStart).next()
tessellator.draw()
}
/**
* @see org.lwjgl.opengl.GL11.glPushMatrix
*/
fun pushMatrix() {
if (disabled) return
RenderSystem.pushMatrix()
}
/**
* @see org.lwjgl.opengl.GL11.glPopMatrix
*/
fun popMatrix() {
if (disabled) return
RenderSystem.popMatrix()
}
/**
* @see org.lwjgl.opengl.GL11.glTranslated
*/
fun translate(x: Double, y: Double, z: Double = 0.0) {
if (disabled) return
RenderSystem.translated(x, y, z)
}
/**
* @see org.lwjgl.opengl.GL11.glScaled
*/
fun scale(x: Double, y: Double, z: Double = 1.0) {
if (disabled) return
RenderSystem.scaled(x, y, z)
}
/**
* @see org.lwjgl.opengl.GL11.glColor4f
*/
fun color(r: Float, g: Float, b: Float, alpha: Float) {
if (disabled) return
RenderSystem.color4f(r, g, b, alpha)
}
private fun VertexConsumer.color(color: Color): VertexConsumer {
return color(color.red, color.green, color.blue, color.alpha)
}
}