Scissor stack fix
This commit is contained in:
parent
0dffe511fd
commit
71f13f70bf
@ -3,13 +3,11 @@ package ru.dbotthepony.mc.otm.client.render
|
||||
import com.mojang.blaze3d.platform.GlStateManager
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.*
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.renderer.GameRenderer
|
||||
import net.minecraft.client.renderer.RenderStateShard
|
||||
import net.minecraft.client.renderer.RenderStateShard.LineStateShard
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.ShaderInstance
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.packs.resources.ResourceProvider
|
||||
import org.apache.logging.log4j.LogManager
|
||||
@ -294,9 +292,15 @@ fun drawLine(
|
||||
tess.end()
|
||||
}
|
||||
|
||||
data class ScissorRect(val x: Int, val y: Int, val width: Int, val height: Int, val lock: Boolean = false) {
|
||||
data class ScissorRect(val xStart: Int, val yStart: Int, val xEnd: Int, val yEnd: Int, val lock: Boolean = false) {
|
||||
val width: Int
|
||||
get() = (xEnd - xStart).coerceAtLeast(0)
|
||||
|
||||
val height: Int
|
||||
get() = (yEnd - yStart).coerceAtLeast(0)
|
||||
|
||||
fun withinBounds(x: Int, y: Int): Boolean {
|
||||
return (x in this.x .. this.x + width) && (y in this.y .. this.y + height)
|
||||
return (x in this.xStart .. xEnd) && (y in this.yStart .. yEnd)
|
||||
}
|
||||
|
||||
fun cross(x: Int, y: Int, width: Int, height: Int): Boolean {
|
||||
@ -306,18 +310,18 @@ data class ScissorRect(val x: Int, val y: Int, val width: Int, val height: Int,
|
||||
}
|
||||
|
||||
// crossing at least one line
|
||||
if (y in this.y .. this.y + height) {
|
||||
if (x < this.x && x + width > this.x + this.width) {
|
||||
if (y in this.yStart .. this.yStart + height) {
|
||||
if (x < this.xStart && x + width > this.xEnd) {
|
||||
return true
|
||||
}
|
||||
} else if (x in this.x .. this.x + width) {
|
||||
if (y < this.y && y + height > this.y + this.height) {
|
||||
} else if (x in this.xStart .. this.xStart + width) {
|
||||
if (y < this.yStart && y + height > this.yEnd) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// final test: check if scissor rect is completely inside provided rect
|
||||
return this.x in x .. x + width && this.y in y .. y + height
|
||||
return this.xStart in x .. x + width && this.yStart in y .. y + height
|
||||
}
|
||||
|
||||
fun crossScaled(x: Float, y: Float, width: Float, height: Float): Boolean {
|
||||
@ -329,17 +333,20 @@ data class ScissorRect(val x: Int, val y: Int, val width: Int, val height: Int,
|
||||
val scale = minecraft.window.guiScale
|
||||
return cross((x * scale).roundToInt(), (y * scale).roundToInt(), (width * scale).roundToInt(), (height * scale).roundToInt())
|
||||
}
|
||||
|
||||
fun apply() {
|
||||
RenderSystem.enableScissor(xStart, minecraft.window.height - yStart - height, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
private val scissorStack = ArrayDeque<ScissorRect>()
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
@JvmOverloads
|
||||
fun pushScissorRect(x: Int, y: Int, width: Int, height: Int, lock: Boolean = false) {
|
||||
var x = x
|
||||
var y = y
|
||||
var width = width
|
||||
var height = height
|
||||
var xStart = x
|
||||
var yStart = y
|
||||
var xEnd = x + width
|
||||
var yEnd = y + height
|
||||
|
||||
val peek = scissorStack.lastOrNull()
|
||||
|
||||
@ -349,34 +356,31 @@ fun pushScissorRect(x: Int, y: Int, width: Int, height: Int, lock: Boolean = fal
|
||||
return
|
||||
}
|
||||
|
||||
x = x.coerceAtLeast(peek.x)
|
||||
y = y.coerceAtLeast(peek.y)
|
||||
width = width.coerceAtMost(peek.width)
|
||||
height = height.coerceAtMost(peek.height)
|
||||
xStart = xStart.coerceAtLeast(peek.xStart)
|
||||
yStart = yStart.coerceAtLeast(peek.yStart)
|
||||
xEnd = xEnd.coerceAtMost(peek.xEnd)
|
||||
yEnd = yEnd.coerceAtMost(peek.yEnd)
|
||||
|
||||
if (peek.x == x && peek.y == y && peek.width == width && peek.height == height) {
|
||||
if (peek.xStart == xStart && peek.yStart == yStart && peek.xEnd == xEnd && peek.yEnd == yEnd) {
|
||||
scissorStack.add(peek)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
scissorStack.add(ScissorRect(x, y, width, height, lock))
|
||||
y = minecraft.window.height - y - height
|
||||
RenderSystem.enableScissor(x, y, width, height)
|
||||
val new = ScissorRect(xStart, yStart, xEnd, yEnd, lock)
|
||||
scissorStack.add(new)
|
||||
new.apply()
|
||||
}
|
||||
|
||||
fun popScissorRect() {
|
||||
scissorStack.removeLast()
|
||||
|
||||
val peek = scissorStack.lastOrNull()
|
||||
|
||||
if (peek == null) {
|
||||
RenderSystem.disableScissor()
|
||||
return
|
||||
} else {
|
||||
peek.apply()
|
||||
}
|
||||
|
||||
val y = minecraft.window.height - peek.y - peek.height
|
||||
RenderSystem.enableScissor(peek.x, y, peek.width, peek.height)
|
||||
}
|
||||
|
||||
val currentScissorRect get() = scissorStack.lastOrNull()
|
||||
|
Loading…
Reference in New Issue
Block a user