even more raycasted lights tests
This commit is contained in:
parent
5947252dc7
commit
08c2b5a685
@ -1,8 +1,11 @@
|
|||||||
package ru.dbotthepony.kstarbound.client
|
package ru.dbotthepony.kstarbound.client
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
|
import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNIT
|
||||||
import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNITf
|
import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNITf
|
||||||
import ru.dbotthepony.kstarbound.client.gl.BlendFunc
|
import ru.dbotthepony.kstarbound.client.gl.BlendFunc
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.GLFrameBuffer
|
||||||
|
import ru.dbotthepony.kstarbound.client.gl.GLTexture2D
|
||||||
import ru.dbotthepony.kstarbound.client.gl.vertex.QuadTransformers
|
import ru.dbotthepony.kstarbound.client.gl.vertex.QuadTransformers
|
||||||
import ru.dbotthepony.kstarbound.client.gl.vertex.quad
|
import ru.dbotthepony.kstarbound.client.gl.vertex.quad
|
||||||
import ru.dbotthepony.kstarbound.client.gl.vertex.quadZ
|
import ru.dbotthepony.kstarbound.client.gl.vertex.quadZ
|
||||||
@ -18,6 +21,8 @@ import ru.dbotthepony.kvector.vector.Color
|
|||||||
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
||||||
import ru.dbotthepony.kvector.vector.nfloat.Vector2f
|
import ru.dbotthepony.kvector.vector.nfloat.Vector2f
|
||||||
import ru.dbotthepony.kvector.vector.nint.Vector2i
|
import ru.dbotthepony.kvector.vector.nint.Vector2i
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -192,17 +197,92 @@ class ClientWorld(
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
client.gl.quadWireframe {
|
val result = rayLightCircleNaive(pos, 48.0, falloffByTravel = 1.0, falloffByTile = 3.0)
|
||||||
for ((intensity, tpos) in rayLightCircleNaive(pos, 24.0, falloffByTravel = 1.5, falloffByTile = 4.0)) {
|
val result2 = rayLightCircleNaive(pos + Vector2d(-8.0), 24.0, falloffByTravel = 1.0, falloffByTile = 3.0)
|
||||||
it.quad(
|
val frame = GLFrameBuffer(client.gl)
|
||||||
tpos.x.toFloat(),
|
frame.attachTexture(client.viewportWidth, client.viewportHeight)
|
||||||
tpos.y.toFloat(),
|
|
||||||
tpos.x + 1f,
|
frame.bind()
|
||||||
tpos.y + 1f
|
|
||||||
)
|
client.gl.clearColor = Color.BLACK
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
client.gl.blendFunc = BlendFunc.ADDITIVE
|
||||||
|
|
||||||
|
/*client.gl.quadColor {
|
||||||
|
for (row in 0 until result.rows) {
|
||||||
|
for (column in 0 until result.columns) {
|
||||||
|
if (result[column, row] > 0.05) {
|
||||||
|
val color = result[column, row].toFloat() * 1.5f
|
||||||
|
|
||||||
|
it.quad(
|
||||||
|
pos.x.roundToInt() - result.rows.toFloat() / 2f + row.toFloat(),
|
||||||
|
pos.y.roundToInt() - result.columns.toFloat() / 2f + column.toFloat(),
|
||||||
|
pos.x.roundToInt() - result.rows.toFloat() / 2f + row + 1f,
|
||||||
|
pos.y.roundToInt() - result.columns.toFloat() / 2f + column + 1f
|
||||||
|
) { a, b -> a.pushVec4f(color, color, color, 1f) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.gl.quadColor {
|
||||||
|
for (row in 0 until result2.rows) {
|
||||||
|
for (column in 0 until result2.columns) {
|
||||||
|
if (result2[column, row] > 0.05) {
|
||||||
|
val color = result2[column, row].toFloat() * 1.5f
|
||||||
|
|
||||||
|
it.quad(
|
||||||
|
pos.x.roundToInt() - 8f - result2.rows.toFloat() / 2f + row.toFloat(),
|
||||||
|
pos.y.roundToInt() - result2.columns.toFloat() / 2f + column.toFloat(),
|
||||||
|
pos.x.roundToInt() - 8f - result2.rows.toFloat() / 2f + row + 1f,
|
||||||
|
pos.y.roundToInt() - result2.columns.toFloat() / 2f + column + 1f
|
||||||
|
) { a, b -> a.pushVec4f(color, 0f, 0f, 1f) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
val lightTextureWidth = (client.viewportWidth / PIXELS_IN_STARBOUND_UNIT).roundToInt()
|
||||||
|
val lightTextureHeight = (client.viewportHeight / PIXELS_IN_STARBOUND_UNIT).roundToInt()
|
||||||
|
|
||||||
|
val textureBuffer = ByteBuffer.allocateDirect(lightTextureWidth * lightTextureHeight * 3)
|
||||||
|
textureBuffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
|
||||||
|
for (x in 0 until result.columns.coerceAtMost(lightTextureWidth)) {
|
||||||
|
for (y in 0 until result.rows.coerceAtMost(lightTextureHeight)) {
|
||||||
|
textureBuffer.position(x * 3 + y * lightTextureWidth * 3)
|
||||||
|
|
||||||
|
if (result[x, y] > 0.05) {
|
||||||
|
val color = result[x, y].toFloat() * 1.5f
|
||||||
|
|
||||||
|
textureBuffer.put((color * 255).toInt().coerceAtMost(255).toByte())
|
||||||
|
textureBuffer.put((color * 255).toInt().coerceAtMost(255).toByte())
|
||||||
|
textureBuffer.put((color * 255).toInt().coerceAtMost(255).toByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.unbind()
|
||||||
|
|
||||||
|
val texture = GLTexture2D(client.gl)
|
||||||
|
|
||||||
|
textureBuffer.position(0)
|
||||||
|
texture.upload(GL_RGB, lightTextureWidth, lightTextureHeight, GL_RGB, GL_UNSIGNED_BYTE, textureBuffer)
|
||||||
|
|
||||||
|
texture.textureMinFilter = GL_LINEAR
|
||||||
|
texture.textureMagFilter = GL_LINEAR
|
||||||
|
|
||||||
|
client.gl.blendFunc = BlendFunc.MULTIPLY_BY_SRC
|
||||||
|
|
||||||
|
client.gl.activeTexture = 0
|
||||||
|
client.gl.texture2D = texture
|
||||||
|
client.gl.programs.viewTextureQuad.run()
|
||||||
|
|
||||||
|
client.gl.blendFunc = old
|
||||||
|
|
||||||
|
frame.close()
|
||||||
|
texture.close()
|
||||||
|
|
||||||
physics.debugDraw()
|
physics.debugDraw()
|
||||||
|
|
||||||
|
@ -362,6 +362,7 @@ class StarboundClient : AutoCloseable {
|
|||||||
if (frameRenderTime != 0.0 && Starbound.initialized)
|
if (frameRenderTime != 0.0 && Starbound.initialized)
|
||||||
world?.think(frameRenderTime)
|
world?.think(frameRenderTime)
|
||||||
|
|
||||||
|
gl.clearColor = Color.SLATE_GREY
|
||||||
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
|
||||||
gl.matrixStack.clear(viewportMatrixWorld.toMutableMatrix4f())
|
gl.matrixStack.clear(viewportMatrixWorld.toMutableMatrix4f())
|
||||||
|
|
||||||
|
@ -82,12 +82,11 @@ class GLFrameBuffer(val state: GLStateTracker) : AutoCloseable {
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
state.ensureSameThread()
|
|
||||||
|
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
return
|
return
|
||||||
|
|
||||||
cleanable.cleanManual()
|
cleanable.cleanManual()
|
||||||
|
texture?.close()
|
||||||
isValid = false
|
isValid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,10 +234,15 @@ class GLStateTracker {
|
|||||||
if (!cleanManual && LOGGER.isTraceEnabled)
|
if (!cleanManual && LOGGER.isTraceEnabled)
|
||||||
LOGGER.trace("{} with ID {} was GC'd by JVM, without manually calling close()", name, nativeRef)
|
LOGGER.trace("{} with ID {} was GC'd by JVM, without manually calling close()", name, nativeRef)
|
||||||
|
|
||||||
synchronized(cleanerHits) {
|
if (isSameThread()) {
|
||||||
cleanerHits.add {
|
fn(nativeRef)
|
||||||
fn(nativeRef)
|
checkForGLError()
|
||||||
checkForGLError()
|
} else {
|
||||||
|
synchronized(cleanerHits) {
|
||||||
|
cleanerHits.add {
|
||||||
|
fn(nativeRef)
|
||||||
|
checkForGLError()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -570,30 +575,12 @@ class GLStateTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val flat2DQuads = object : GLStreamBuilderList {
|
|
||||||
override val small by lazy {
|
|
||||||
return@lazy StreamVertexBuilder(this@GLStateTracker, GLAttributeList.VEC2F, GeometryType.QUADS, 1024)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val flat2DTexturedQuads = object : GLStreamBuilderList {
|
val flat2DTexturedQuads = object : GLStreamBuilderList {
|
||||||
override val small by lazy {
|
override val small by lazy {
|
||||||
return@lazy StreamVertexBuilder(this@GLStateTracker, GLAttributeList.VERTEX_TEXTURE, GeometryType.QUADS, 1024)
|
return@lazy StreamVertexBuilder(this@GLStateTracker, GLAttributeList.VERTEX_TEXTURE, GeometryType.QUADS, 1024)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val flat2DQuadLines = object : GLStreamBuilderList {
|
|
||||||
override val small by lazy {
|
|
||||||
return@lazy StreamVertexBuilder(this@GLStateTracker, GLAttributeList.VEC2F, GeometryType.QUADS_AS_LINES, 1024)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val flat2DQuadWireframe = object : GLStreamBuilderList {
|
|
||||||
override val small by lazy {
|
|
||||||
return@lazy StreamVertexBuilder(this@GLStateTracker, GLAttributeList.VEC2F, GeometryType.QUADS_AS_LINES_WIREFRAME, 1024)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val quadWireframe by lazy {
|
val quadWireframe by lazy {
|
||||||
StreamVertexBuilder(this, GLAttributeList.VEC2F, GeometryType.QUADS_AS_LINES_WIREFRAME, 16384)
|
StreamVertexBuilder(this, GLAttributeList.VEC2F, GeometryType.QUADS_AS_LINES_WIREFRAME, 16384)
|
||||||
}
|
}
|
||||||
@ -617,6 +604,19 @@ class GLStateTracker {
|
|||||||
builder.draw(GL_LINES)
|
builder.draw(GL_LINES)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun quadColor(lambda: (StreamVertexBuilder) -> Unit) {
|
||||||
|
val builder = programs.flatColor.builder
|
||||||
|
|
||||||
|
builder.begin()
|
||||||
|
lambda.invoke(builder)
|
||||||
|
builder.upload()
|
||||||
|
|
||||||
|
programs.flatColor.use()
|
||||||
|
programs.flatColor.transform.set(matrixStack.last)
|
||||||
|
|
||||||
|
builder.draw(GL_TRIANGLES)
|
||||||
|
}
|
||||||
|
|
||||||
inline fun quadWireframe(value: AABB, color: Color = Color.WHITE, chain: (StreamVertexBuilder) -> Unit = {}) {
|
inline fun quadWireframe(value: AABB, color: Color = Color.WHITE, chain: (StreamVertexBuilder) -> Unit = {}) {
|
||||||
quadWireframe(color) {
|
quadWireframe(color) {
|
||||||
it.quad(value.mins.x.toFloat(), value.mins.y.toFloat(), value.maxs.x.toFloat(), value.maxs.y.toFloat())
|
it.quad(value.mins.x.toFloat(), value.mins.y.toFloat(), value.maxs.x.toFloat(), value.maxs.y.toFloat())
|
||||||
|
@ -191,9 +191,37 @@ class GLTextureQuadProgram(state: GLStateTracker) : GLInternalProgram(state, "sc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GLTextureBlurredQuadProgram(state: GLStateTracker) : GLInternalProgram(state, "screen_quad_tex_blur") {
|
||||||
|
init {
|
||||||
|
link()
|
||||||
|
}
|
||||||
|
|
||||||
|
val texture = this["texture0"]!!
|
||||||
|
|
||||||
|
private val builder by lazy {
|
||||||
|
val builder = StreamVertexBuilder(state, FORMAT, GeometryType.QUADS, 1)
|
||||||
|
|
||||||
|
builder.begin()
|
||||||
|
builder.quad(-1f, -1f, 1f, 1f, QuadTransformers.uv())
|
||||||
|
builder.upload()
|
||||||
|
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
|
||||||
|
fun run(texture: Int = 0) {
|
||||||
|
use()
|
||||||
|
this.texture.set(texture)
|
||||||
|
builder.draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val FORMAT = GLAttributeList.Builder().push(GLType.VEC2F).push(GLType.VEC2F).build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class GLFlatProgram(state: GLStateTracker, vararg shaders: GLShader) : GLTransformableColorableProgram(state, *shaders) {
|
class GLFlatProgram(state: GLStateTracker, vararg shaders: GLShader) : GLTransformableColorableProgram(state, *shaders) {
|
||||||
val builder by lazy {
|
val builder by lazy {
|
||||||
StreamVertexBuilder(state, FORMAT, GeometryType.QUADS, 1024)
|
StreamVertexBuilder(state, FORMAT, GeometryType.QUADS, 2048)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -201,15 +229,33 @@ class GLFlatProgram(state: GLStateTracker, vararg shaders: GLShader) : GLTransfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GLFlatColorProgram(state: GLStateTracker) : GLInternalProgram(state, "flat_color") {
|
||||||
|
init {
|
||||||
|
link()
|
||||||
|
}
|
||||||
|
|
||||||
|
val transform = this["transform"]!!
|
||||||
|
|
||||||
|
val builder by lazy {
|
||||||
|
StreamVertexBuilder(state, FORMAT, GeometryType.QUADS, 16384)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val FORMAT = GLAttributeList.Builder().push(GLType.VEC2F).push(GLType.VEC4F).build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class GLPrograms(val state: GLStateTracker) {
|
class GLPrograms(val state: GLStateTracker) {
|
||||||
val tile by SimpleProgram("tile", ::GLTransformableColorableProgram)
|
val tile by SimpleProgram("tile", ::GLTransformableColorableProgram)
|
||||||
val font by SimpleProgram("font", ::GLTransformableColorableProgram)
|
val font by SimpleProgram("font", ::GLTransformableColorableProgram)
|
||||||
val flat by SimpleProgram("flat", ::GLFlatProgram)
|
val flat by SimpleProgram("flat", ::GLFlatProgram)
|
||||||
|
val flatColor by lazy { GLFlatColorProgram(state) }
|
||||||
val liquid by lazy { GLLiquidProgram(state) }
|
val liquid by lazy { GLLiquidProgram(state) }
|
||||||
val light by lazy { GLLightProgram(state) }
|
val light by lazy { GLLightProgram(state) }
|
||||||
val hardLightGeometry by lazy { GLHardLightGeometryProgram(state) }
|
val hardLightGeometry by lazy { GLHardLightGeometryProgram(state) }
|
||||||
val softLightGeometry by lazy { GLSoftLightGeometryProgram(state) }
|
val softLightGeometry by lazy { GLSoftLightGeometryProgram(state) }
|
||||||
|
|
||||||
val colorQuad by lazy { GLColorQuadProgram(state) }
|
val viewColorQuad by lazy { GLColorQuadProgram(state) }
|
||||||
val textureQuad by lazy { GLTextureQuadProgram(state) }
|
val viewTextureQuad by lazy { GLTextureQuadProgram(state) }
|
||||||
|
val viewTextureBlurQuad by lazy { GLTextureBlurredQuadProgram(state) }
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ class GPULightRenderer(val state: GLStateTracker) {
|
|||||||
state.activeTexture = 0
|
state.activeTexture = 0
|
||||||
state.texture2D = outputTexture
|
state.texture2D = outputTexture
|
||||||
state.blendFunc = BlendFunc.ADDITIVE
|
state.blendFunc = BlendFunc.ADDITIVE
|
||||||
state.programs.textureQuad.run(0)
|
state.programs.viewTextureQuad.run(0)
|
||||||
} finally {
|
} finally {
|
||||||
state.blendFunc = oldFunc
|
state.blendFunc = oldFunc
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ class GPULightRenderer(val state: GLStateTracker) {
|
|||||||
state.activeTexture = 0
|
state.activeTexture = 0
|
||||||
state.texture2D = outputTexture
|
state.texture2D = outputTexture
|
||||||
state.blendFunc = BlendFunc.MULTIPLY_WITH_ALPHA
|
state.blendFunc = BlendFunc.MULTIPLY_WITH_ALPHA
|
||||||
state.programs.textureQuad.run(0)
|
state.programs.viewTextureQuad.run(0)
|
||||||
} finally {
|
} finally {
|
||||||
state.blendFunc = oldFunc
|
state.blendFunc = oldFunc
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ class GPULightRenderer(val state: GLStateTracker) {
|
|||||||
state.blendFunc = BlendFunc.ADDITIVE
|
state.blendFunc = BlendFunc.ADDITIVE
|
||||||
state.activeTexture = 0
|
state.activeTexture = 0
|
||||||
state.texture2D = framebufferRender.texture
|
state.texture2D = framebufferRender.texture
|
||||||
state.programs.textureQuad.run(0)
|
state.programs.viewTextureQuad.run(0)
|
||||||
} finally {
|
} finally {
|
||||||
state.blendFunc = oldFunc
|
state.blendFunc = oldFunc
|
||||||
framebufferAccumulator.unbind()
|
framebufferAccumulator.unbind()
|
||||||
|
@ -17,11 +17,14 @@ import ru.dbotthepony.kstarbound.util.Timer
|
|||||||
import ru.dbotthepony.kstarbound.world.entities.CollisionResolution
|
import ru.dbotthepony.kstarbound.world.entities.CollisionResolution
|
||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
import ru.dbotthepony.kstarbound.world.entities.projectile.AbstractProjectileMovementController
|
import ru.dbotthepony.kstarbound.world.entities.projectile.AbstractProjectileMovementController
|
||||||
|
import ru.dbotthepony.kvector.narray.Double2Dimensional
|
||||||
import ru.dbotthepony.kvector.narray.Int2Dimensional
|
import ru.dbotthepony.kvector.narray.Int2Dimensional
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
import ru.dbotthepony.kvector.util2d.AABBi
|
import ru.dbotthepony.kvector.util2d.AABBi
|
||||||
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
||||||
import ru.dbotthepony.kvector.vector.nint.Vector2i
|
import ru.dbotthepony.kvector.vector.nint.Vector2i
|
||||||
|
import java.util.LinkedList
|
||||||
|
import java.util.function.DoubleBinaryOperator
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
@ -67,10 +70,10 @@ private val veryPreciseFan by lazy { makeDirFan(0.25) }
|
|||||||
private fun chooseLightRayFan(size: Double): List<Vector2d> {
|
private fun chooseLightRayFan(size: Double): List<Vector2d> {
|
||||||
return when (size) {
|
return when (size) {
|
||||||
in 0.0 .. 8.0 -> potatoDirFan
|
in 0.0 .. 8.0 -> potatoDirFan
|
||||||
in 8.0 .. 12.0 -> veryRoughDirFan
|
in 8.0 .. 16.0 -> veryRoughDirFan
|
||||||
in 12.0 .. 18.0 -> roughDirFan
|
in 16.0 .. 24.0 -> roughDirFan
|
||||||
in 18.0 .. 24.0 -> dirFan
|
in 24.0 .. 48.0 -> dirFan
|
||||||
in 24.0 .. 32.0 -> preciseFan
|
in 48.0 .. 96.0 -> preciseFan
|
||||||
// in 32.0 .. 48.0 -> veryPreciseFan
|
// in 32.0 .. 48.0 -> veryPreciseFan
|
||||||
else -> veryPreciseFan
|
else -> veryPreciseFan
|
||||||
}
|
}
|
||||||
@ -399,7 +402,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
val dir = rayEnd - rayStart
|
val dir = rayEnd - rayStart
|
||||||
val inc = 0.5 / dir.length
|
val inc = 0.5 / dir.length
|
||||||
|
|
||||||
val tiles = ArrayList<Pair<Vector2i, ITileState>>()
|
val tiles = LinkedList<Pair<Vector2i, ITileState>>()
|
||||||
var prev = Vector2i(Int.MIN_VALUE, Int.MAX_VALUE)
|
var prev = Vector2i(Int.MIN_VALUE, Int.MAX_VALUE)
|
||||||
var hitTile: Pair<Vector2i, ITileState>? = null
|
var hitTile: Pair<Vector2i, ITileState>? = null
|
||||||
|
|
||||||
@ -482,37 +485,33 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Трассирует лучи света вокруг себя с заданной позицией, интенсивностью,
|
||||||
|
* падением интенсивности за проход сквозь тайл [falloffByTile] и
|
||||||
|
* падением интенсивности за проход по пустому месту [falloffByTravel].
|
||||||
|
*/
|
||||||
fun rayLightCircleNaive(
|
fun rayLightCircleNaive(
|
||||||
position: Vector2d,
|
position: Vector2d,
|
||||||
intensity: Double,
|
intensity: Double,
|
||||||
falloffByTile: Double = 2.0,
|
falloffByTile: Double = 2.0,
|
||||||
falloffByTravel: Double = 2.0,
|
falloffByTravel: Double = 1.0,
|
||||||
): List<Pair<Double, Vector2i>> {
|
): Double2Dimensional {
|
||||||
val result = Object2DoubleAVLTreeMap<Vector2i> { a, b ->
|
val combinedResult = Double2Dimensional(intensity.roundToInt() * 2, intensity.roundToInt() * 2)
|
||||||
val cmp = a.x.compareTo(b.x)
|
val baselineX = position.x.roundToInt() - intensity.roundToInt()
|
||||||
|
val baselineY = position.y.roundToInt() - intensity.roundToInt()
|
||||||
|
|
||||||
if (cmp != 0) {
|
val dirs = chooseLightRayFan(intensity)
|
||||||
return@Object2DoubleAVLTreeMap cmp
|
val mul = 1.0 / dirs.size
|
||||||
}
|
|
||||||
|
|
||||||
return@Object2DoubleAVLTreeMap a.y.compareTo(b.y)
|
for (dir in dirs) {
|
||||||
}
|
|
||||||
|
|
||||||
result.defaultReturnValue(-1.0)
|
|
||||||
|
|
||||||
for (dir in chooseLightRayFan(intensity)) {
|
|
||||||
val result2 = rayLightNaive(position, dir, intensity, falloffByTile, falloffByTravel)
|
val result2 = rayLightNaive(position, dir, intensity, falloffByTile, falloffByTravel)
|
||||||
|
|
||||||
for (pair in result2) {
|
for (pair in result2) {
|
||||||
val existing = result.getDouble(pair.second)
|
combinedResult[pair.second.y - baselineY, pair.second.x - baselineX] += pair.first * mul
|
||||||
|
|
||||||
if (existing < pair.first) {
|
|
||||||
result.put(pair.second, pair.first)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.map { it.value to it.key }
|
return combinedResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +559,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
intensity: Double,
|
intensity: Double,
|
||||||
falloffByTile: Double = 2.0,
|
falloffByTile: Double = 2.0,
|
||||||
falloffByTravel: Double = 2.0,
|
falloffByTravel: Double = 2.0,
|
||||||
): List<Pair<Double, Vector2i>> {
|
): Double2Dimensional {
|
||||||
return CachedGetter().rayLightCircleNaive(position, intensity, falloffByTile, falloffByTravel)
|
return CachedGetter().rayLightCircleNaive(position, intensity, falloffByTile, falloffByTravel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/main/resources/shaders/flat_color.fsh
Normal file
10
src/main/resources/shaders/flat_color.fsh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#version 460
|
||||||
|
|
||||||
|
in vec4 finalVertexColor;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = finalVertexColor;
|
||||||
|
}
|
13
src/main/resources/shaders/flat_color.vsh
Normal file
13
src/main/resources/shaders/flat_color.vsh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
#version 460
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 vertexPos;
|
||||||
|
layout (location = 1) in vec4 vertexColor;
|
||||||
|
uniform mat4 transform;
|
||||||
|
|
||||||
|
out vec4 finalVertexColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = transform * vec4(vertexPos, 0.5, 1.0);
|
||||||
|
finalVertexColor = vertexColor;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user