From 6483dae8923e936959111aeb4bb6150495b43a6e Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 16 Sep 2022 12:28:59 +0700 Subject: [PATCH] ok, now light is still duct taped, but more optimized --- .../kstarbound/client/ClientChunk.kt | 4 +- .../kstarbound/client/ClientWorld.kt | 11 ++++ .../kstarbound/client/StarboundClient.kt | 53 +++++++++++++++++++ .../kstarbound/client/gl/GLStateTracker.kt | 13 ++++- .../kstarbound/client/gl/ScissorRect.kt | 19 +++++++ 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/ScissorRect.kt diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientChunk.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientChunk.kt index 8c5bc9d4..1e996d20 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientChunk.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientChunk.kt @@ -222,7 +222,7 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk() + + fun pushScissorRect(x: Float, y: Float, width: Float, height: Float) { + return pushScissorRect(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt()) + } + + @Suppress("NAME_SHADOWING") + fun pushScissorRect(x: Int, y: Int, width: Int, height: Int) { + var x = x + var y = y + var width = width + var height = height + + val peek = scissorStack.lastOrNull() + + if (peek != null) { + x = x.coerceAtLeast(peek.x) + y = y.coerceAtLeast(peek.y) + width = width.coerceAtMost(peek.width) + height = height.coerceAtMost(peek.height) + + if (peek.x == x && peek.y == y && peek.width == width && peek.height == height) { + scissorStack.add(peek) + return + } + } + + val rect = ScissorRect(x, y, width, height) + scissorStack.add(rect) + gl.scissorRect = rect + gl.scissor = true + } + + fun popScissorRect() { + scissorStack.removeLast() + + val peek = scissorStack.lastOrNull() + + if (peek == null) { + gl.scissor = false + return + } + + val y = viewportHeight - peek.y - peek.height + gl.scissorRect = ScissorRect(peek.x, y, peek.width, peek.height) + } + + val currentScissorRect get() = scissorStack.lastOrNull() + fun renderFrame(): Boolean { ensureSameThread() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt index 575b6b73..91b8a2c7 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt @@ -28,9 +28,7 @@ import java.util.concurrent.ThreadFactory import kotlin.collections.ArrayList import kotlin.collections.HashMap import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty -import kotlin.reflect.KProperty0 private class GLStateSwitchTracker(private val enum: Int, private var value: Boolean = false) { operator fun getValue(glStateTracker: GLStateTracker, property: KProperty<*>): Boolean { @@ -249,6 +247,17 @@ class GLStateTracker { var blend by GLStateSwitchTracker(GL_BLEND) var scissor by GLStateSwitchTracker(GL_SCISSOR_TEST) + + var scissorRect by GLStateGenericTracker(ScissorRect(0, 0, 0, 0)) { + // require(it.x >= 0) { "Invalid X ${it.x}"} + // require(it.y >= 0) { "Invalid Y ${it.y}"} + + require(it.width >= 0) { "Invalid width ${it.width}"} + require(it.height >= 0) { "Invalid height ${it.height}"} + + glScissor(it.x, it.y, it.width, it.height) + } + var depthTest by GLStateSwitchTracker(GL_DEPTH_TEST) var VBO: VertexBufferObject? = null diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/ScissorRect.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/ScissorRect.kt new file mode 100644 index 00000000..4de4f86b --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/ScissorRect.kt @@ -0,0 +1,19 @@ +package ru.dbotthepony.kstarbound.client.gl + +import ru.dbotthepony.kvector.util2d.intersectRectangles + +data class ScissorRect(val x: Int, val y: Int, val width: Int, val height: Int) { + fun withinBounds(x: Int, y: Int): Boolean { + return (x in this.x .. this.x + width) && (y in this.y .. this.y + height) + } + + fun cross(x: Int, y: Int, width: Int, height: Int): Boolean { + return intersectRectangles( + x, y, + x + width, y + height, + + this.x, this.y, + this.x + this.width, this.y + this.height, + ) + } +} \ No newline at end of file