drawing tilemap 'texture' is also done once every three frames

This commit is contained in:
minjaesong
2024-08-30 17:50:29 +09:00
parent d405302c9d
commit 56a1723e4f

View File

@@ -86,15 +86,6 @@ internal object BlocksDrawer {
private const val NEARBY_TILE_KEY_DOWN = 2 private const val NEARBY_TILE_KEY_DOWN = 2
private const val NEARBY_TILE_KEY_LEFT = 3 private const val NEARBY_TILE_KEY_LEFT = 3
private const val NEARBY_TILE_CODE_UP = 1
private const val NEARBY_TILE_CODE_RIGHT = 2
private const val NEARBY_TILE_CODE_DOWN = 4
private const val NEARBY_TILE_CODE_LEFT = 8
private const val GZIP_READBUF_SIZE = 8192
private lateinit var terrainTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled) private lateinit var terrainTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled)
private lateinit var wallTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled) private lateinit var wallTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled)
private lateinit var oreTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled) private lateinit var oreTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled)
@@ -103,9 +94,15 @@ internal object BlocksDrawer {
private lateinit var blurMapTerr: UnsafeLong2D // stores subtiles (dimension is doubled) private lateinit var blurMapTerr: UnsafeLong2D // stores subtiles (dimension is doubled)
private lateinit var blurMapWall: UnsafeLong2D // stores subtiles (dimension is doubled) private lateinit var blurMapWall: UnsafeLong2D // stores subtiles (dimension is doubled)
private lateinit var tempRenderTypeBuffer: UnsafeLong2D // this one is NOT dimension doubled; 0x tttt 00 ii where t=rawTileNum, i=nearbyTilesInfo private lateinit var tempRenderTypeBuffer: UnsafeLong2D // this one is NOT dimension doubled; 0x tttt 00 ii where t=rawTileNum, i=nearbyTilesInfo
private var tilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888) private var terrainDrawBuffer1: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var tilesBuffer2: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888) private var terrainDrawBuffer2: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var wallDrawBuffer1: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var wallDrawBuffer2: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var oresDrawBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var fluidDrawBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var occlusionDrawBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var blurTilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888) private var blurTilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private var nullBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
private lateinit var tilesQuad: Mesh private lateinit var tilesQuad: Mesh
private val shaderTiling = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling.frag") private val shaderTiling = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling.frag")
@@ -272,14 +269,16 @@ internal object BlocksDrawer {
camTransX += WorldCamera.deltaX camTransX += WorldCamera.deltaX
camTransY += WorldCamera.deltaY camTransY += WorldCamera.deltaY
} }
if (doTilemapUpdate) { if (doTilemapUpdate) {
// rendering tilemap only updates every three frame // rendering tilemap only updates every three frame
measureDebugTime("Renderer.Tiling*") { measureDebugTime("Renderer.Tiling*") {
drawTiles(WALL) fillInTileBuffer(WALL)
drawTiles(TERRAIN) // regular tiles fillInTileBuffer(TERRAIN) // regular tiles
drawTiles(ORES) fillInTileBuffer(ORES)
drawTiles(FLUID) fillInTileBuffer(FLUID)
drawTiles(OCCLUSION) fillInTileBuffer(OCCLUSION)
prepareDrawBuffers()
} }
} }
} }
@@ -438,7 +437,7 @@ internal object BlocksDrawer {
* @param drawModeTilesBlendMul If current drawing mode is MULTIPLY. Doesn't matter if mode is FLUID. * @param drawModeTilesBlendMul If current drawing mode is MULTIPLY. Doesn't matter if mode is FLUID.
* @param wire coduitTypes bit that is selected to be drawn. Must be the power of two. * @param wire coduitTypes bit that is selected to be drawn. Must be the power of two.
*/ */
private fun drawTiles(mode: Int) { private fun fillInTileBuffer(mode: Int) {
// TODO the real fluid rendering must use separate function, but its code should be similar to this. // TODO the real fluid rendering must use separate function, but its code should be similar to this.
// shader's tileAtlas will be fluid.tga, pixels written to the buffer is in accordance with the new // shader's tileAtlas will be fluid.tga, pixels written to the buffer is in accordance with the new
@@ -1184,6 +1183,57 @@ internal object BlocksDrawer {
private var camTransX = 0 private var camTransX = 0
private var camTransY = 0 private var camTransY = 0
private fun prepareDrawBuffers() {
listOf(TERRAIN, WALL, ORES, FLUID, OCCLUSION).forEach { mode ->
val sourceBuffer = when(mode) {
TERRAIN -> terrainTilesBuffer
WALL -> wallTilesBuffer
ORES -> oreTilesBuffer
FLUID -> fluidTilesBuffer
OCCLUSION -> occlusionBuffer
else -> throw IllegalArgumentException()
}
val drawBuffer1 = when(mode) {
TERRAIN -> terrainDrawBuffer1
WALL -> wallDrawBuffer1
ORES -> oresDrawBuffer
FLUID -> fluidDrawBuffer
OCCLUSION -> occlusionDrawBuffer
else -> throw IllegalArgumentException()
}
val drawBuffer2 = when(mode) {
TERRAIN -> terrainDrawBuffer2
WALL -> wallDrawBuffer2
else -> null
}
for (y in 0 until drawBuffer1.height) {
for (x in 0 until drawBuffer1.width) {
val colRaw = sourceBuffer[y, x]
val colMain = colRaw.toInt()
val colSub = colRaw.ushr(32).toInt()
drawBuffer1.setColor(colMain)
drawBuffer1.drawPixel(x, y)
drawBuffer2?.setColor(colSub)
drawBuffer2?.drawPixel(x, y)
// write blurmap to its own buffer for TERRAIN and WALL
if (mode == TERRAIN || mode == WALL) {
val colRaw = (if (mode == TERRAIN) blurMapTerr else blurMapWall)[y, x]
val colMain = colRaw.toInt()
blurTilesBuffer.setColor(colMain)
blurTilesBuffer.drawPixel(x, y)
}
}
}
}
}
private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean) { private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean) {
//Gdx.gl.glClearColor(.094f, .094f, .094f, 0f) //Gdx.gl.glClearColor(.094f, .094f, .094f, 0f)
//Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) //Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
@@ -1197,61 +1247,39 @@ internal object BlocksDrawer {
TERRAIN, ORES, WALL, OCCLUSION, FLUID, BLURMAP_TERR, BLURMAP_WALL -> tilesTerrain TERRAIN, ORES, WALL, OCCLUSION, FLUID, BLURMAP_TERR, BLURMAP_WALL -> tilesTerrain
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
} }
val sourceBuffer = when(mode) {
TERRAIN -> terrainTilesBuffer
WALL -> wallTilesBuffer
ORES -> oreTilesBuffer
FLUID -> fluidTilesBuffer
OCCLUSION -> occlusionBuffer
else -> throw IllegalArgumentException()
}
val vertexColour = when (mode) { val vertexColour = when (mode) {
WALL -> WALL_OVERLAY_COLOUR WALL -> WALL_OVERLAY_COLOUR
else -> Color.WHITE else -> Color.WHITE
} }
// write to colour buffer val drawBuffer1 = when(mode) {
// As the texture size is very small, multithreading it would be less effective TERRAIN -> terrainDrawBuffer1
// TODO making it run sporadically without graphical issue would improve the tiling performance WALL -> wallDrawBuffer1
// if (doTilemapUpdate) { ORES -> oresDrawBuffer
for (y in 0 until tilesBuffer.height) { FLUID -> fluidDrawBuffer
for (x in 0 until tilesBuffer.width) { OCCLUSION -> occlusionDrawBuffer
val colRaw = sourceBuffer[y, x] else -> throw IllegalArgumentException()
val colMain = colRaw.toInt() }
val colSub = colRaw.ushr(32).toInt()
tilesBuffer.setColor(colMain)
tilesBuffer.drawPixel(x, y)
tilesBuffer2.setColor(colSub)
tilesBuffer2.drawPixel(x, y)
// write blurmap to its own buffer for TERRAIN and WALL
if (mode == TERRAIN || mode == WALL) {
val colRaw = (if (mode == TERRAIN) blurMapTerr else blurMapWall)[y, x]
val colMain = colRaw.toInt()
blurTilesBuffer.setColor(colMain)
blurTilesBuffer.drawPixel(x, y)
}
}
}
// }
val drawBuffer2 = when(mode) {
TERRAIN -> terrainDrawBuffer2
WALL -> wallDrawBuffer2
else -> nullBuffer
}
_tilesBufferAsTex.dispose() _tilesBufferAsTex.dispose()
_tilesBufferAsTex = Texture(tilesBuffer) _tilesBufferAsTex = Texture(drawBuffer1)
_tilesBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) _tilesBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
_tilesBufferAsTex2.dispose() _tilesBufferAsTex2.dispose()
_tilesBufferAsTex2 = Texture(tilesBuffer2) _tilesBufferAsTex2 = Texture(drawBuffer2)
_tilesBufferAsTex2.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) _tilesBufferAsTex2.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
_blurTilesBuffer.dispose() _blurTilesBuffer.dispose()
_blurTilesBuffer = Texture(blurTilesBuffer) _blurTilesBuffer = Texture(blurTilesBuffer)
_blurTilesBuffer.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) _blurTilesBuffer.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
if (drawEmissive) { if (drawEmissive) {
nullTex.bind(4) nullTex.bind(4)
_tilesBufferAsTex2.bind(3) _tilesBufferAsTex2.bind(3)
@@ -1282,7 +1310,7 @@ internal object BlocksDrawer {
shaderTiling.setUniformi("tilemap", 2) shaderTiling.setUniformi("tilemap", 2)
shaderTiling.setUniformi("tilemap2", 3) shaderTiling.setUniformi("tilemap2", 3)
shaderTiling.setUniformi("deblockingMap", 4) shaderTiling.setUniformi("deblockingMap", 4)
shaderTiling.setUniformi("tilemapDimension", tilesBuffer.width, tilesBuffer.height) shaderTiling.setUniformi("tilemapDimension", drawBuffer1.width, drawBuffer1.height)
shaderTiling.setUniformf("tilesInAxes", tilesInHorizontal.toFloat(), tilesInVertical.toFloat()) shaderTiling.setUniformf("tilesInAxes", tilesInHorizontal.toFloat(), tilesInVertical.toFloat())
shaderTiling.setUniformi("cameraTranslation", camTransX, camTransY) // usage of 'fmod' and '%' were depend on the for_x_start, which I can't just do naive int div shaderTiling.setUniformi("cameraTranslation", camTransX, camTransY) // usage of 'fmod' and '%' were depend on the for_x_start, which I can't just do naive int div
shaderTiling.setUniformf("tilesInAtlas", tileAtlas.horizontalCount * 2f, tileAtlas.verticalCount * 2f) //depends on the tile atlas shaderTiling.setUniformf("tilesInAtlas", tileAtlas.horizontalCount * 2f, tileAtlas.verticalCount * 2f) //depends on the tile atlas
@@ -1335,10 +1363,20 @@ internal object BlocksDrawer {
blurMapWall = UnsafeLong2D(tilesInHorizontal, tilesInVertical) blurMapWall = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
tempRenderTypeBuffer = UnsafeLong2D(hTilesInHorizontal, hTilesInVertical) tempRenderTypeBuffer = UnsafeLong2D(hTilesInHorizontal, hTilesInVertical)
tilesBuffer.dispose() terrainDrawBuffer1.dispose()
tilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888) terrainDrawBuffer1 = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
tilesBuffer2.dispose() terrainDrawBuffer2.dispose()
tilesBuffer2 = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888) terrainDrawBuffer2 = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
wallDrawBuffer1.dispose()
wallDrawBuffer1 = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
wallDrawBuffer2.dispose()
wallDrawBuffer2 = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
oresDrawBuffer.dispose()
oresDrawBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
fluidDrawBuffer.dispose()
fluidDrawBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
occlusionDrawBuffer.dispose()
occlusionDrawBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
blurTilesBuffer.dispose() blurTilesBuffer.dispose()
blurTilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888) blurTilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
} }
@@ -1406,8 +1444,13 @@ internal object BlocksDrawer {
tileItemWall.dispose() tileItemWall.dispose()
tileItemWallGlow.dispose() tileItemWallGlow.dispose()
tileItemWallEmissive.dispose() tileItemWallEmissive.dispose()
tilesBuffer.dispose() terrainDrawBuffer1.dispose()
tilesBuffer2.dispose() terrainDrawBuffer2.dispose()
wallDrawBuffer1.dispose()
wallDrawBuffer2.dispose()
oresDrawBuffer.dispose()
fluidDrawBuffer.dispose()
occlusionDrawBuffer.dispose()
blurTilesBuffer.dispose() blurTilesBuffer.dispose()
_tilesBufferAsTex.dispose() _tilesBufferAsTex.dispose()
_tilesBufferAsTex2.dispose() _tilesBufferAsTex2.dispose()
@@ -1416,6 +1459,7 @@ internal object BlocksDrawer {
shaderTiling.dispose() shaderTiling.dispose()
shaderDeblock.dispose() shaderDeblock.dispose()
nullTex.dispose() nullTex.dispose()
nullBuffer.dispose()
if (::terrainTilesBuffer.isInitialized) terrainTilesBuffer.destroy() if (::terrainTilesBuffer.isInitialized) terrainTilesBuffer.destroy()
if (::wallTilesBuffer.isInitialized) wallTilesBuffer.destroy() if (::wallTilesBuffer.isInitialized) wallTilesBuffer.destroy()