ok, now light is still duct taped, but more optimized

This commit is contained in:
DBotThePony 2022-09-16 12:28:59 +07:00
parent 5c697c129e
commit 6483dae892
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 96 additions and 4 deletions

View File

@ -222,7 +222,7 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
for (y in this.y * SHADOW_GEOMETRY_SQUARE_SIZE until (this.y + 1) * SHADOW_GEOMETRY_SQUARE_SIZE) {
if (foreground[x, y].material?.renderParameters?.lightTransparent == false) {
if (x == 0 || foreground[x - 1, y].material?.renderParameters?.lightTransparent != true) {
line(builder, x.toFloat(), y.toFloat(), x.toFloat(), y + 1f)
line(builder, x.toFloat(), y + 1f, x.toFloat(), y.toFloat())
}
if (x == CHUNK_SIZE - 1 || foreground[x + 1, y].material?.renderParameters?.lightTransparent != true) {
@ -234,7 +234,7 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
}
if (y == CHUNK_SIZE - 1 || foreground[x, y + 1].material?.renderParameters?.lightTransparent != true) {
line(builder, x.toFloat(), y + 1f, x + 1f, y + 1f)
line(builder, x + 1f, y + 1f, x.toFloat(), y + 1f)
}
}
}

View File

@ -42,6 +42,7 @@ class ClientWorld(
*/
fun render(
size: AABB,
isScreenspaceRender: Boolean = true
) {
val parallax = parallax
@ -120,7 +121,17 @@ class ClientWorld(
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(0.1f)) to Color.GREEN,
(client.screenToWorld(client.mouseCoordinatesF) + Vector2f(-0.1f)) to Color.BLUE,
)) {
if (isScreenspaceRender) {
val (x, y) = client.worldToScreen(lightPosition.x - 20f, lightPosition.y - 20f)
val (x2, y2) = client.worldToScreen(lightPosition.x + 20f, lightPosition.y + 20f)
client.pushScissorRect(x, client.viewportHeight - y, x2 - x, y - y2)
}
client.lightRenderer.renderSoftLight(lightPosition, color, radius = 20f, innerRadius = 1f)
if (isScreenspaceRender) {
client.popScissorRect()
}
}
val old = client.gl.blendFunc

View File

@ -12,6 +12,7 @@ import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNITf
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.client.gl.BlendFunc
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
import ru.dbotthepony.kstarbound.client.gl.ScissorRect
import ru.dbotthepony.kstarbound.client.input.UserInput
import ru.dbotthepony.kstarbound.client.render.Camera
import ru.dbotthepony.kstarbound.client.render.LightRenderer
@ -25,7 +26,10 @@ import ru.dbotthepony.kvector.vector.nfloat.Vector2f
import ru.dbotthepony.kvector.vector.nfloat.Vector3f
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.*
import java.util.concurrent.locks.LockSupport
import kotlin.collections.ArrayList
import kotlin.math.roundToInt
class StarboundClient : AutoCloseable {
val window: Long
@ -289,6 +293,55 @@ class StarboundClient : AutoCloseable {
onPostDrawWorldOnce.add(lambda)
}
private val scissorStack = LinkedList<ScissorRect>()
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()

View File

@ -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

View File

@ -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,
)
}
}