Chunk render offsets
this thing is broken
This commit is contained in:
parent
07ba48c121
commit
1e1c5a83c1
src/main/kotlin/ru/dbotthepony/kstarbound
@ -148,7 +148,7 @@ fun main() {
|
|||||||
|
|
||||||
//ent.position += Vector2d(y = 14.0, x = -10.0)
|
//ent.position += Vector2d(y = 14.0, x = -10.0)
|
||||||
ent.position = Vector2d(600.0 + 16.0, 721.0 + 48.0)
|
ent.position = Vector2d(600.0 + 16.0, 721.0 + 48.0)
|
||||||
client.camera.pos = Vector2f(7f, 685f)
|
client.camera.pos = Vector2f(-2967f, 685f)
|
||||||
|
|
||||||
client.onDrawGUI {
|
client.onDrawGUI {
|
||||||
client.gl.font.render("${ent.position}", y = 100f, scale = 0.25f)
|
client.gl.font.render("${ent.position}", y = 100f, scale = 0.25f)
|
||||||
|
@ -15,6 +15,7 @@ import ru.dbotthepony.kstarbound.world.api.ITileAccess
|
|||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
import ru.dbotthepony.kvector.arrays.Matrix4fStack
|
import ru.dbotthepony.kvector.arrays.Matrix4fStack
|
||||||
import ru.dbotthepony.kvector.vector.Vector2d
|
import ru.dbotthepony.kvector.vector.Vector2d
|
||||||
|
import ru.dbotthepony.kvector.vector.Vector2f
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
|
|
||||||
@ -66,14 +67,6 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun render(stack: Matrix4fStack) {
|
|
||||||
val transform = stack.last()
|
|
||||||
|
|
||||||
for (mesh in bakedMeshes) {
|
|
||||||
mesh.first.render(transform)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun upload() {
|
fun upload() {
|
||||||
if (layers.isNotEmpty) {
|
if (layers.isNotEmpty) {
|
||||||
for (mesh in bakedMeshes) {
|
for (mesh in bakedMeshes) {
|
||||||
@ -164,11 +157,11 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
|||||||
return liquidTypes
|
return liquidTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class Renderer(val renderOrigin: ChunkPos = pos) {
|
inner class Renderer(val renderOrigin: Vector2f = pos.tile.toFloatVector()) {
|
||||||
fun addLayers(layers: LayeredRenderer) {
|
fun addLayers(layers: LayeredRenderer) {
|
||||||
for ((baked, zLevel) in backgroundRenderer.bakedMeshes) {
|
for ((baked, zLevel) in backgroundRenderer.bakedMeshes) {
|
||||||
layers.add(zLevel + Z_LEVEL_BACKGROUND) {
|
layers.add(zLevel + Z_LEVEL_BACKGROUND) {
|
||||||
it.push().last().translateWithMultiplication(renderOrigin.x * CHUNK_SIZEf, renderOrigin.y * CHUNK_SIZEf)
|
it.push().last().translateWithMultiplication(renderOrigin.x, renderOrigin.y)
|
||||||
baked.renderStacked(it)
|
baked.renderStacked(it)
|
||||||
it.pop()
|
it.pop()
|
||||||
}
|
}
|
||||||
@ -176,7 +169,7 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
|||||||
|
|
||||||
for ((baked, zLevel) in foregroundRenderer.bakedMeshes) {
|
for ((baked, zLevel) in foregroundRenderer.bakedMeshes) {
|
||||||
layers.add(zLevel) {
|
layers.add(zLevel) {
|
||||||
it.push().last().translateWithMultiplication(renderOrigin.x * CHUNK_SIZEf, renderOrigin.y * CHUNK_SIZEf)
|
it.push().last().translateWithMultiplication(renderOrigin.x, renderOrigin.y)
|
||||||
baked.renderStacked(it)
|
baked.renderStacked(it)
|
||||||
it.pop()
|
it.pop()
|
||||||
}
|
}
|
||||||
@ -185,7 +178,7 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
|||||||
for (renderer in entityRenderers.values) {
|
for (renderer in entityRenderers.values) {
|
||||||
layers.add(renderer.layer) {
|
layers.add(renderer.layer) {
|
||||||
val relative = renderer.renderPos - posVector2d
|
val relative = renderer.renderPos - posVector2d
|
||||||
it.push().last().translateWithMultiplication(renderOrigin.x * CHUNK_SIZEf + relative.x.toFloat(), renderOrigin.y * CHUNK_SIZEf + relative.y.toFloat())
|
it.push().last().translateWithMultiplication(renderOrigin.x + relative.x.toFloat(), renderOrigin.y + relative.y.toFloat())
|
||||||
renderer.render(it)
|
renderer.render(it)
|
||||||
it.pop()
|
it.pop()
|
||||||
}
|
}
|
||||||
@ -195,7 +188,7 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
|||||||
|
|
||||||
if (types.isNotEmpty()) {
|
if (types.isNotEmpty()) {
|
||||||
layers.add(Z_LEVEL_LIQUID) {
|
layers.add(Z_LEVEL_LIQUID) {
|
||||||
it.push().last().translateWithMultiplication(renderOrigin.x * CHUNK_SIZEf, renderOrigin.y * CHUNK_SIZEf)
|
it.push().last().translateWithMultiplication(renderOrigin.x, renderOrigin.y)
|
||||||
|
|
||||||
val program = state.programs.liquid
|
val program = state.programs.liquid
|
||||||
|
|
||||||
|
@ -3,9 +3,12 @@ package ru.dbotthepony.kstarbound.client
|
|||||||
import ru.dbotthepony.kstarbound.client.render.LayeredRenderer
|
import ru.dbotthepony.kstarbound.client.render.LayeredRenderer
|
||||||
import ru.dbotthepony.kstarbound.math.encasingChunkPosAABB
|
import ru.dbotthepony.kstarbound.math.encasingChunkPosAABB
|
||||||
import ru.dbotthepony.kstarbound.world.*
|
import ru.dbotthepony.kstarbound.world.*
|
||||||
|
import ru.dbotthepony.kstarbound.world.api.CHUNK_SIZEf
|
||||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||||
import ru.dbotthepony.kvector.util2d.AABB
|
import ru.dbotthepony.kvector.util2d.AABB
|
||||||
|
import ru.dbotthepony.kvector.vector.Vector2f
|
||||||
import ru.dbotthepony.kvector.vector.Vector2i
|
import ru.dbotthepony.kvector.vector.Vector2i
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class ClientWorld(
|
class ClientWorld(
|
||||||
val client: StarboundClient,
|
val client: StarboundClient,
|
||||||
@ -30,57 +33,35 @@ class ClientWorld(
|
|||||||
layers: LayeredRenderer
|
layers: LayeredRenderer
|
||||||
) {
|
) {
|
||||||
for (chunk in collectPositionAware(size.encasingChunkPosAABB())) {
|
for (chunk in collectPositionAware(size.encasingChunkPosAABB())) {
|
||||||
val renderer = chunk.second.Renderer(chunk.first)
|
val (x, y) = chunk.first
|
||||||
|
|
||||||
|
val renderer = chunk.second.Renderer(
|
||||||
|
Vector2f(x * CHUNK_SIZEf + chunkMap.x.cellOffset(x), y * CHUNK_SIZEf + chunkMap.y.cellOffset(y))
|
||||||
|
)
|
||||||
|
|
||||||
renderer.addLayers(layers)
|
renderer.addLayers(layers)
|
||||||
chunk.second.bake()
|
chunk.second.bake()
|
||||||
//client.lightRenderer.addShadowGeometry(renderer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
for ((lightPosition, color) in listOf(
|
|
||||||
(client.screenToWorld(client.mouseCoordinatesF)) to Color.RED,
|
|
||||||
(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 - 64f, lightPosition.y - 64f)
|
|
||||||
val (x2, y2) = client.worldToScreen(lightPosition.x + 64f, lightPosition.y + 64f)
|
|
||||||
client.pushScissorRect(x, client.viewportHeight - y, x2 - x, y - y2)
|
|
||||||
}
|
|
||||||
|
|
||||||
client.lightRenderer.renderSoftLight(lightPosition, color, radius = 64f, innerRadius = 2f)
|
|
||||||
|
|
||||||
if (isScreenspaceRender) {
|
|
||||||
client.popScissorRect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val old = client.gl.blendFunc
|
|
||||||
client.gl.blendFunc = BlendFunc.MULTIPLY_BY_SRC
|
|
||||||
|
|
||||||
client.gl.activeTexture = 0
|
|
||||||
client.gl.texture2D = client.lightRenderer.outputTexture
|
|
||||||
client.gl.programs.viewTextureQuad.run()
|
|
||||||
|
|
||||||
client.gl.blendFunc = old
|
|
||||||
*/
|
|
||||||
val pos = client.screenToWorld(client.mouseCoordinatesF)
|
val pos = client.screenToWorld(client.mouseCoordinatesF)
|
||||||
|
|
||||||
/*val lightsize = 16
|
layers.add(-999999) {
|
||||||
|
val lightsize = 16
|
||||||
|
|
||||||
val lightmap = floodLight(
|
val lightmap = floodLight(
|
||||||
Vector2i(pos.x.roundToInt(), pos.y.roundToInt()), lightsize
|
Vector2i(pos.x.roundToInt(), pos.y.roundToInt()), lightsize
|
||||||
)
|
)
|
||||||
|
|
||||||
client.gl.quadWireframe {
|
client.gl.quadWireframe {
|
||||||
for (column in 0 until lightmap.columns) {
|
for (column in 0 until lightmap.columns) {
|
||||||
for (row in 0 until lightmap.rows) {
|
for (row in 0 until lightmap.rows) {
|
||||||
if (lightmap[column, row] > 0) {
|
if (lightmap[column, row] > 0) {
|
||||||
it.quad(pos.x.roundToInt() + column.toFloat() - lightsize, pos.y.roundToInt() + row.toFloat() - lightsize, pos.x.roundToInt() + column + 1f - lightsize, pos.y.roundToInt() + row + 1f - lightsize)
|
it.quad(pos.x.roundToInt() + column.toFloat() - lightsize, pos.y.roundToInt() + row.toFloat() - lightsize, pos.x.roundToInt() + column + 1f - lightsize, pos.y.roundToInt() + row + 1f - lightsize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
val rayFan = ArrayList<Vector2d>()
|
val rayFan = ArrayList<Vector2d>()
|
||||||
|
@ -26,7 +26,7 @@ private fun circulate(value: Int, bounds: Int): Int {
|
|||||||
* * Вверх у нас положительный Y
|
* * Вверх у нас положительный Y
|
||||||
* * Вниз у нас отрицательный Y
|
* * Вниз у нас отрицательный Y
|
||||||
*/
|
*/
|
||||||
class ChunkPos(val x: Int, val y: Int) : Comparable<ChunkPos> {
|
data class ChunkPos(val x: Int, val y: Int) : IStruct2i, Comparable<ChunkPos> {
|
||||||
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
|
constructor(pos: IStruct2i) : this(pos.component1(), pos.component2())
|
||||||
|
|
||||||
// bottom left corner
|
// bottom left corner
|
||||||
|
@ -38,8 +38,9 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
abstract fun cell(value: Int): Int
|
abstract fun cell(value: Int): Int
|
||||||
abstract fun cell(value: Double): Double
|
abstract fun cell(value: Double): Double
|
||||||
abstract fun cell(value: Float): Float
|
abstract fun cell(value: Float): Float
|
||||||
|
|
||||||
abstract fun chunk(value: Int): Int
|
abstract fun chunk(value: Int): Int
|
||||||
abstract fun chunk(value: Double): Double
|
abstract fun cellOffset(chunk: Int): Int
|
||||||
|
|
||||||
abstract fun inBounds(value: Int): Boolean
|
abstract fun inBounds(value: Int): Boolean
|
||||||
abstract fun inBoundsChunk(value: Int): Boolean
|
abstract fun inBoundsChunk(value: Int): Boolean
|
||||||
@ -65,7 +66,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
override fun cell(value: Double): Double = value
|
override fun cell(value: Double): Double = value
|
||||||
override fun cell(value: Float): Float = value
|
override fun cell(value: Float): Float = value
|
||||||
override fun chunk(value: Int): Int = value
|
override fun chunk(value: Int): Int = value
|
||||||
override fun chunk(value: Double): Double = value
|
override fun cellOffset(chunk: Int): Int = 0
|
||||||
|
|
||||||
override fun inBounds(value: Int) = true
|
override fun inBounds(value: Int) = true
|
||||||
override fun inBoundsChunk(value: Int) = true
|
override fun inBoundsChunk(value: Int) = true
|
||||||
@ -80,6 +81,19 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
return value in 0 until chunk
|
return value in 0 until chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val misalignedTiles = cell and CHUNK_SIZE_MASK
|
||||||
|
private val misalignedTiles2 = misalignedTiles - CHUNK_SIZE
|
||||||
|
|
||||||
|
override fun cellOffset(chunk: Int): Int {
|
||||||
|
if (misalignedTiles == 0) {
|
||||||
|
return 0
|
||||||
|
} else if (chunk >= 0) {
|
||||||
|
return (chunk / this.chunk) * misalignedTiles2
|
||||||
|
} else {
|
||||||
|
return ((chunk + 1) / this.chunk - 1) * misalignedTiles2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun cell(value: Int): Int {
|
override fun cell(value: Int): Int {
|
||||||
return positiveModulo(value, cell)
|
return positiveModulo(value, cell)
|
||||||
}
|
}
|
||||||
@ -95,10 +109,6 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
override fun chunk(value: Int): Int {
|
override fun chunk(value: Int): Int {
|
||||||
return positiveModulo(value, chunk)
|
return positiveModulo(value, chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chunk(value: Double): Double {
|
|
||||||
return positiveModulo(value, chunk)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoordinatesClamper(private val cell: Int, private val chunk: Int) : AbstractCoordinatesWrapper() {
|
class CoordinatesClamper(private val cell: Int, private val chunk: Int) : AbstractCoordinatesWrapper() {
|
||||||
@ -106,6 +116,10 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
return value in 0 until cell
|
return value in 0 until cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun cellOffset(chunk: Int): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
override fun inBoundsChunk(value: Int): Boolean {
|
override fun inBoundsChunk(value: Int): Boolean {
|
||||||
return value in 0 until chunk
|
return value in 0 until chunk
|
||||||
}
|
}
|
||||||
@ -125,10 +139,6 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
override fun chunk(value: Int): Int {
|
override fun chunk(value: Int): Int {
|
||||||
return value.coerceIn(0, chunk - 1)
|
return value.coerceIn(0, chunk - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chunk(value: Double): Double {
|
|
||||||
return value.coerceIn(0.0, chunk - 1.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract inner class ChunkMap : ICellAccess {
|
abstract inner class ChunkMap : ICellAccess {
|
||||||
@ -189,6 +199,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// infinite chunk map is around 30% slower than rectangular one
|
||||||
inner class InfiniteChunkMap : ChunkMap() {
|
inner class InfiniteChunkMap : ChunkMap() {
|
||||||
private val map = Long2ObjectOpenHashMap<ChunkType>()
|
private val map = Long2ObjectOpenHashMap<ChunkType>()
|
||||||
|
|
||||||
@ -414,12 +425,19 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
fun collect(boundingBox: AABBi): List<ChunkType> {
|
fun collect(boundingBox: AABBi): List<ChunkType> {
|
||||||
val output = ArrayList<ChunkType>()
|
val output = ArrayList<ChunkType>()
|
||||||
|
|
||||||
for (pos in boundingBox.chunkPositions) {
|
if (
|
||||||
val chunk = chunkMap[pos]
|
chunkMap.x.cellOffset(boundingBox.mins.x) == chunkMap.x.cellOffset(boundingBox.maxs.x) &&
|
||||||
|
chunkMap.y.cellOffset(boundingBox.mins.y) == chunkMap.y.cellOffset(boundingBox.maxs.y)
|
||||||
|
) {
|
||||||
|
for (pos in boundingBox.chunkPositions) {
|
||||||
|
val chunk = chunkMap[pos]
|
||||||
|
|
||||||
if (chunk != null && (loopX || chunkMap.x.inBoundsChunk(pos.x)) && (loopY || chunkMap.y.inBoundsChunk(pos.y))) {
|
if (chunk != null && (loopX || chunkMap.x.inBoundsChunk(pos.x)) && (loopY || chunkMap.y.inBoundsChunk(pos.y))) {
|
||||||
output.add(chunk)
|
output.add(chunk)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
@ -492,7 +510,7 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
|
|
||||||
val tile = chunkMap.getCell(worldPosX, worldPosY)
|
val tile = chunkMap.getCell(worldPosX, worldPosY)
|
||||||
|
|
||||||
val newIntensity: Int
|
var newIntensity: Int
|
||||||
|
|
||||||
if (tile.foreground.material?.renderParameters?.lightTransparent == false) {
|
if (tile.foreground.material?.renderParameters?.lightTransparent == false) {
|
||||||
newIntensity = thisIntensity - lightBlockerStrength
|
newIntensity = thisIntensity - lightBlockerStrength
|
||||||
@ -500,6 +518,9 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
newIntensity = thisIntensity - 1
|
newIntensity = thisIntensity - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tile.foreground.material != null)
|
||||||
|
newIntensity = 0
|
||||||
|
|
||||||
lightmap[posX, posY] = newIntensity.coerceAtLeast(0)
|
lightmap[posX, posY] = newIntensity.coerceAtLeast(0)
|
||||||
|
|
||||||
if (newIntensity > 1) {
|
if (newIntensity > 1) {
|
||||||
|
Loading…
Reference in New Issue
Block a user