From 168e4f08b5403310b362b3d5f781a3cc83b7b7f0 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 14 Aug 2021 12:52:47 +0900 Subject: [PATCH] lightmap to update every other frame, and rendering needs fix minor jitter --- src/net/torvald/terrarum/AppLoader.java | 3 +- .../terrarum/gameworld/WorldSimulator.kt | 2 +- .../terrarum/modulebasegame/IngameRenderer.kt | 18 +++++++-- .../terrarum/modulebasegame/TerrarumIngame.kt | 5 ++- .../terrarum/ui/BasicDebugInfoWindow.kt | 3 ++ .../terrarum/worlddrawer/LightmapRenderer.kt | 9 ++++- src/net/torvald/util/DebugTimers.kt | 37 +++++++++++++++++++ 7 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/net/torvald/util/DebugTimers.kt diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index 77bfd63fd..fb500c82f 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -38,6 +38,7 @@ import net.torvald.terrarum.worlddrawer.CreateTileAtlas; import net.torvald.terrarumsansbitmap.gdx.GameFontBase; import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack; import net.torvald.util.ArrayListMap; +import net.torvald.util.DebugTimers; import org.lwjgl.opengl.GL11; import java.io.File; @@ -205,7 +206,7 @@ public class AppLoader implements ApplicationListener { public static int GLOBAL_RENDER_TIMER = new Random().nextInt(1020) + 1; - public static ArrayListMap debugTimers = new ArrayListMap(); + public static DebugTimers debugTimers = new DebugTimers(); public static final String FONT_DIR = "assets/graphics/fonts/terrarum-sans-bitmap"; diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 506f26598..8463dbfa2 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -500,7 +500,7 @@ object WorldSimulator { // this makes sure that only the emitters with wires installed will get traversed world.getWireGraphOf(point.x, point.y, wire)?.let { _ -> printdbg(this, wire) - + val points = Queue() // a queue, enqueued at the end var marked = HashSet() diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 7ae6c47b6..6e08a41ca 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -11,7 +11,9 @@ import com.badlogic.gdx.utils.Disposable import com.badlogic.gdx.utils.ScreenUtils import net.torvald.gdx.graphics.PixmapIO2 import net.torvald.terrarum.* +import net.torvald.terrarum.AppLoader.measureDebugTime import net.torvald.terrarum.AppLoader.printdbg +import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gamecontroller.KeyToggler @@ -170,6 +172,8 @@ object IngameRenderer : Disposable { } } + private var oldCamX = 0 + operator fun invoke( gamePaused: Boolean, actorsRenderBehind : List? = null, @@ -200,7 +204,13 @@ object IngameRenderer : Disposable { if (!gamePaused) { - LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay) + measureDebugTime("Renderer.ApparentLightRun") { + // recalculate for even frames, or if the sign of the cam-x changed + if (AppLoader.GLOBAL_RENDER_TIMER % 2 == 0 || WorldCamera.x * oldCamX < 0) + LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay) + + oldCamX = WorldCamera.x + } prepLightmapRGBA() BlocksDrawer.renderData() @@ -737,8 +747,10 @@ object IngameRenderer : Disposable { private fun worldCamToRenderPos(): Pair { // for some reason it does not like integer. No, really; it breaks (jitter when you move) when you try to "fix" that. - val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) - val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) + val xoff = (WorldCamera.x / TILE_SIZE) - LightmapRenderer.camX + val yoff = (WorldCamera.y / TILE_SIZE) - LightmapRenderer.camY + val xrem = -(WorldCamera.x.toFloat() fmod TILE_SIZEF) - (xoff * TILE_SIZEF) + val yrem = -(WorldCamera.y.toFloat() fmod TILE_SIZEF) - (yoff * TILE_SIZEF) return xrem to yrem } diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 6a9d49564..c4728aa08 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -38,6 +38,7 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.terrarum.worlddrawer.FeaturesDrawer +import net.torvald.terrarum.worlddrawer.LightmapRenderer import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.util.CircularArray import net.torvald.util.SortedArrayList @@ -630,7 +631,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { // TODO thread pool(?) CollisionSolver.process() - WorldCamera.update(gameworld, actorNowPlaying) + //WorldCamera.update(gameworld, actorNowPlaying) } @@ -665,6 +666,8 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { private fun renderGame() { Gdx.graphics.setTitle(getCanonicalTitle()) + WorldCamera.update(gameworld, actorNowPlaying) + measureDebugTime("Ingame.FilterVisibleActors") { filterVisibleActors() } diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index 7b35be4e0..3ad744323 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -235,6 +235,9 @@ class BasicDebugInfoWindow : UICanvas() { // FPS count AppLoader.fontSmallNumbers.draw(batch, "${ccY}FPS${ccG}${Gdx.graphics.framesPerSecond.toString().padStart(3, ' ')}", (AppLoader.screenSize.screenW - 3 - 15 * TinyAlphNum.W).toFloat(), line(2)) + // global render counter + AppLoader.fontSmallNumbers.draw(batch, "${ccO}${AppLoader.GLOBAL_RENDER_TIMER.toString().padStart(10, ' ')}", + (AppLoader.screenSize.screenW - 35 * TinyAlphNum.W - 2).toFloat(), line(1)) /** * Bottom left diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt index ac0a49ca3..82e692bb2 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRenderer.kt @@ -60,7 +60,7 @@ object LightmapRenderer { finally { this.world = world - // fireRecalculateEvent() + //fireRecalculateEvent() } } @@ -101,6 +101,8 @@ object LightmapRenderer { internal var for_draw_y_start = 0 internal var for_draw_x_end = 0 internal var for_draw_y_end = 0 + internal var camX = 0 + internal var camY = 0 /** * @param x world coord @@ -137,7 +139,7 @@ object LightmapRenderer { } } - internal fun fireRecalculateEvent(vararg actorContainers: List?) { + fun fireRecalculateEvent(vararg actorContainers: List?) { try { world.getTileFromTerrain(0, 0) // test inquiry } @@ -167,6 +169,9 @@ object LightmapRenderer { for_draw_x_end = for_draw_x_start + WorldCamera.width / TILE_SIZE + 3 for_draw_y_end = for_draw_y_start + WorldCamera.height / TILE_SIZE + 3 + camX = WorldCamera.x / TILE_SIZE + camY = WorldCamera.y / TILE_SIZE + //println("$for_x_start..$for_x_end, $for_x\t$for_y_start..$for_y_end, $for_y") AppLoader.measureDebugTime("Renderer.Lanterns") { diff --git a/src/net/torvald/util/DebugTimers.kt b/src/net/torvald/util/DebugTimers.kt new file mode 100644 index 000000000..ffffa661e --- /dev/null +++ b/src/net/torvald/util/DebugTimers.kt @@ -0,0 +1,37 @@ +package net.torvald.util + +/** + * Debugtimers will collect multiple measurements and will return stabilised time reading + * + * Created by minjaesong on 2021-08-14 + */ +class DebugTimers { + + private val BUFFER_SIZE = 16 + private val bufs = ArrayListMap>() + + fun put(key: String, value: Long) { + if (bufs[key] == null) bufs[key] = CircularArray(BUFFER_SIZE, true) + bufs[key]!!.appendHead(value) + } + + operator fun get(key: String): Long? { + if (bufs[key] == null) return null + else { + var s = 0L; var c = 0 + for (i in 0 until BUFFER_SIZE) { + bufs[key]!![i]?.let { + s += it + c += 1 + } + } + return if (c == 0) 0L else s / c + } + } + + fun forEach(action: (String, Long?) -> Unit) { + bufs.keys.forEach { key -> action(key, get(key)) } + } + + +} \ No newline at end of file