mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
abandoning the async idea: updating on the main thread is actually faster when it's called often enough -- maybe something to do with the optimisation on runtime?
This commit is contained in:
@@ -12,7 +12,6 @@ import com.badlogic.gdx.utils.GdxRuntimeException
|
|||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.App.measureDebugTime
|
import net.torvald.terrarum.App.measureDebugTime
|
||||||
import net.torvald.terrarum.App.printdbg
|
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
@@ -224,9 +223,8 @@ object IngameRenderer : Disposable {
|
|||||||
if (!gamePaused || newWorldLoadedLatch) {
|
if (!gamePaused || newWorldLoadedLatch) {
|
||||||
measureDebugTime("Renderer.LightRun*") {
|
measureDebugTime("Renderer.LightRun*") {
|
||||||
// recalculate for even frames, or if the sign of the cam-x changed
|
// recalculate for even frames, or if the sign of the cam-x changed
|
||||||
if (App.GLOBAL_RENDER_TIMER % 80 == 0 || Math.abs(WorldCamera.x - oldCamX) >= world.width * 0.85f * TILE_SIZEF || newWorldLoadedLatch) {
|
if (App.GLOBAL_RENDER_TIMER % 3 == 0 || Math.abs(WorldCamera.x - oldCamX) >= world.width * 0.85f * TILE_SIZEF || newWorldLoadedLatch) {
|
||||||
printdbg(this, "LightmapRenderer requestRecalculation")
|
LightmapRenderer.recalculate(actorsRenderBehind + actorsRenderFront + actorsRenderMidTop + actorsRenderMiddle + actorsRenderOverlay)
|
||||||
LightmapRenderer.requestRecalculation { actorsRenderBehind + actorsRenderFront + actorsRenderMidTop + actorsRenderMiddle + actorsRenderOverlay }
|
|
||||||
}
|
}
|
||||||
oldCamX = WorldCamera.x
|
oldCamX = WorldCamera.x
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ package net.torvald.terrarum.worlddrawer
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import net.torvald.UnsafeHelper
|
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.gdx.graphics.UnsafeCvecArray
|
import net.torvald.gdx.graphics.UnsafeCvecArray
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.App.measureDebugTime
|
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
@@ -21,8 +19,6 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer
|
|||||||
import net.torvald.terrarum.modulebasegame.ui.abs
|
import net.torvald.terrarum.modulebasegame.ui.abs
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
@@ -54,7 +50,6 @@ object LightmapRenderer {
|
|||||||
printdbg(this, "World change detected -- old world: ${this.world.hashCode()}, new world: ${world.hashCode()}")
|
printdbg(this, "World change detected -- old world: ${this.world.hashCode()}, new world: ${world.hashCode()}")
|
||||||
|
|
||||||
lightmap.zerofill()
|
lightmap.zerofill()
|
||||||
_lightmap.zerofill()
|
|
||||||
_mapLightLevelThis.zerofill()
|
_mapLightLevelThis.zerofill()
|
||||||
_mapThisTileOpacity.zerofill()
|
_mapThisTileOpacity.zerofill()
|
||||||
_mapThisTileOpacity2.zerofill()
|
_mapThisTileOpacity2.zerofill()
|
||||||
@@ -85,7 +80,6 @@ object LightmapRenderer {
|
|||||||
*/
|
*/
|
||||||
// it utilises alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light)
|
// it utilises alpha channel to determine brightness of "glow" sprites (so that alpha channel works like UV light)
|
||||||
private var lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
private var _lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
|
||||||
private var _mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var _mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var _mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
private var _mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
@@ -140,67 +134,14 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal var rendererStatus = AtomicInteger(2) // 0: processing queued, 1: processing, 2: done
|
|
||||||
private var lightmapPrepared = AtomicBoolean(false)
|
|
||||||
|
|
||||||
private val runnerLock = java.lang.Object()
|
|
||||||
private val runner = Runnable { while (!Thread.interrupted()) {
|
|
||||||
if (rendererStatus.get() == 0) {
|
|
||||||
measureDebugTime("Renderer.LightCalcThread") {
|
|
||||||
rendererStatus.incrementAndGet() // 0 -> 1
|
|
||||||
|
|
||||||
val unlock = lightmapPrepared.get()
|
|
||||||
|
|
||||||
if (unlock) {
|
|
||||||
try {
|
|
||||||
printdbg(this, "Recalculate!") // should recalculate once on request, not every f'ing frame
|
|
||||||
recalculate(actorsGetter(), _lightmap)
|
|
||||||
|
|
||||||
// dispatch _lightmap to lightmap
|
|
||||||
UnsafeHelper.memcpy(_lightmap.ptr, lightmap.ptr, lightmap.TOTAL_SIZE_IN_BYTES)
|
|
||||||
// visuals being "jittery" means you're not dispatching the lightmap correctly
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (e: NullPointerException) {
|
|
||||||
System.err.println("NPE; lightmapPrepared = $unlock")
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rendererStatus.incrementAndGet() // 1 -> 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Thread.sleep(1L)
|
|
||||||
synchronized(runnerLock) { runnerLock.wait() }
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
|
|
||||||
private val lightCalcThread = Thread(runner, "LightCalcThread")
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
LightmapHDRMap.invoke()
|
LightmapHDRMap.invoke()
|
||||||
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
||||||
lightCalcThread.start()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun recalculate(actorContainer: List<ActorWithBody>) = _recalculate(actorContainer, lightmap)
|
||||||
|
|
||||||
/**
|
private fun _recalculate(actorContainer: List<ActorWithBody>, lightmap: UnsafeCvecArray) {
|
||||||
* Request recalculation of the light. When it's not a tick to recalculate, or recalculation is ongoing,
|
|
||||||
* the request will be silently disregarded.
|
|
||||||
*/
|
|
||||||
fun requestRecalculation(actorContainers: () -> List<ActorWithBody>) {
|
|
||||||
if (rendererStatus.get() == 2) {
|
|
||||||
actorsGetter = actorContainers
|
|
||||||
rendererStatus.set(0)
|
|
||||||
synchronized(runnerLock) { runnerLock.notifyAll() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var actorsGetter: () -> List<ActorWithBody> = { listOf() }
|
|
||||||
|
|
||||||
private fun recalculate(actorContainers: List<ActorWithBody>, lightmap: UnsafeCvecArray) {
|
|
||||||
try {
|
try {
|
||||||
world.getTileFromTerrain(0, 0) // test inquiry
|
world.getTileFromTerrain(0, 0) // test inquiry
|
||||||
}
|
}
|
||||||
@@ -236,7 +177,7 @@ object LightmapRenderer {
|
|||||||
//println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y")
|
//println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y")
|
||||||
|
|
||||||
App.measureDebugTime("Renderer.Lanterns") {
|
App.measureDebugTime("Renderer.Lanterns") {
|
||||||
buildLanternmap(actorContainers)
|
buildLanternmap(actorContainer)
|
||||||
} // usually takes 3000 ns
|
} // usually takes 3000 ns
|
||||||
|
|
||||||
// set sunlight
|
// set sunlight
|
||||||
@@ -724,14 +665,10 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
lightCalcThread.interrupt()
|
|
||||||
|
|
||||||
LightmapHDRMap.dispose()
|
LightmapHDRMap.dispose()
|
||||||
_lightBufferAsTex.dispose()
|
_lightBufferAsTex.dispose()
|
||||||
lightBuffer.dispose()
|
lightBuffer.dispose()
|
||||||
|
|
||||||
lightmapPrepared.set(false)
|
|
||||||
|
|
||||||
lightmap.destroy()
|
lightmap.destroy()
|
||||||
_mapLightLevelThis.destroy()
|
_mapLightLevelThis.destroy()
|
||||||
_mapThisTileOpacity.destroy()
|
_mapThisTileOpacity.destroy()
|
||||||
@@ -802,8 +739,6 @@ object LightmapRenderer {
|
|||||||
private var _init = false
|
private var _init = false
|
||||||
|
|
||||||
fun resize(screenW: Int, screenH: Int) {
|
fun resize(screenW: Int, screenH: Int) {
|
||||||
lightmapPrepared.set(false)
|
|
||||||
/*
|
|
||||||
// make sure the BlocksDrawer is resized first!
|
// make sure the BlocksDrawer is resized first!
|
||||||
|
|
||||||
// copied from BlocksDrawer, duh!
|
// copied from BlocksDrawer, duh!
|
||||||
@@ -825,17 +760,13 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
|
|
||||||
lightmap.destroy()
|
lightmap.destroy()
|
||||||
_lightmap.destroy()
|
|
||||||
_mapLightLevelThis.destroy()
|
_mapLightLevelThis.destroy()
|
||||||
_mapThisTileOpacity.destroy()
|
_mapThisTileOpacity.destroy()
|
||||||
_mapThisTileOpacity2.destroy()
|
_mapThisTileOpacity2.destroy()
|
||||||
lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
_lightmap = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
|
||||||
_mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
_mapLightLevelThis = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
_mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
_mapThisTileOpacity = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
_mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)*/
|
_mapThisTileOpacity2 = UnsafeCvecArray(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT)
|
||||||
|
|
||||||
lightmapPrepared.set(true)
|
|
||||||
|
|
||||||
printdbg(this, "Resize event")
|
printdbg(this, "Resize event")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user