ok, now light is still duct taped, but more optimized
This commit is contained in:
parent
5c697c129e
commit
6483dae892
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user