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.platform.GlStateManager
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
import com.mojang.blaze3d.vertex.*
|
import com.mojang.blaze3d.vertex.*
|
||||||
import net.minecraft.client.gui.GuiGraphics
|
|
||||||
import net.minecraft.client.renderer.GameRenderer
|
import net.minecraft.client.renderer.GameRenderer
|
||||||
import net.minecraft.client.renderer.RenderStateShard
|
import net.minecraft.client.renderer.RenderStateShard
|
||||||
import net.minecraft.client.renderer.RenderStateShard.LineStateShard
|
import net.minecraft.client.renderer.RenderStateShard.LineStateShard
|
||||||
import net.minecraft.client.renderer.RenderType
|
import net.minecraft.client.renderer.RenderType
|
||||||
import net.minecraft.client.renderer.ShaderInstance
|
import net.minecraft.client.renderer.ShaderInstance
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.server.packs.resources.ResourceProvider
|
import net.minecraft.server.packs.resources.ResourceProvider
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
@ -294,9 +292,15 @@ fun drawLine(
|
|||||||
tess.end()
|
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 {
|
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 {
|
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
|
// crossing at least one line
|
||||||
if (y in this.y .. this.y + height) {
|
if (y in this.yStart .. this.yStart + height) {
|
||||||
if (x < this.x && x + width > this.x + this.width) {
|
if (x < this.xStart && x + width > this.xEnd) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else if (x in this.x .. this.x + width) {
|
} else if (x in this.xStart .. this.xStart + width) {
|
||||||
if (y < this.y && y + height > this.y + this.height) {
|
if (y < this.yStart && y + height > this.yEnd) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// final test: check if scissor rect is completely inside provided rect
|
// 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 {
|
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
|
val scale = minecraft.window.guiScale
|
||||||
return cross((x * scale).roundToInt(), (y * scale).roundToInt(), (width * scale).roundToInt(), (height * scale).roundToInt())
|
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>()
|
private val scissorStack = ArrayDeque<ScissorRect>()
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun pushScissorRect(x: Int, y: Int, width: Int, height: Int, lock: Boolean = false) {
|
fun pushScissorRect(x: Int, y: Int, width: Int, height: Int, lock: Boolean = false) {
|
||||||
var x = x
|
var xStart = x
|
||||||
var y = y
|
var yStart = y
|
||||||
var width = width
|
var xEnd = x + width
|
||||||
var height = height
|
var yEnd = y + height
|
||||||
|
|
||||||
val peek = scissorStack.lastOrNull()
|
val peek = scissorStack.lastOrNull()
|
||||||
|
|
||||||
@ -349,34 +356,31 @@ fun pushScissorRect(x: Int, y: Int, width: Int, height: Int, lock: Boolean = fal
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
x = x.coerceAtLeast(peek.x)
|
xStart = xStart.coerceAtLeast(peek.xStart)
|
||||||
y = y.coerceAtLeast(peek.y)
|
yStart = yStart.coerceAtLeast(peek.yStart)
|
||||||
width = width.coerceAtMost(peek.width)
|
xEnd = xEnd.coerceAtMost(peek.xEnd)
|
||||||
height = height.coerceAtMost(peek.height)
|
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)
|
scissorStack.add(peek)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scissorStack.add(ScissorRect(x, y, width, height, lock))
|
val new = ScissorRect(xStart, yStart, xEnd, yEnd, lock)
|
||||||
y = minecraft.window.height - y - height
|
scissorStack.add(new)
|
||||||
RenderSystem.enableScissor(x, y, width, height)
|
new.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun popScissorRect() {
|
fun popScissorRect() {
|
||||||
scissorStack.removeLast()
|
scissorStack.removeLast()
|
||||||
|
|
||||||
val peek = scissorStack.lastOrNull()
|
val peek = scissorStack.lastOrNull()
|
||||||
|
|
||||||
if (peek == null) {
|
if (peek == null) {
|
||||||
RenderSystem.disableScissor()
|
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()
|
val currentScissorRect get() = scissorStack.lastOrNull()
|
||||||
|
Loading…
Reference in New Issue
Block a user