mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
working deblocking
This commit is contained in:
@@ -277,7 +277,7 @@ object IngameRenderer : Disposable {
|
||||
|
||||
if ((!gamePaused && !App.isScreenshotRequested()) || newWorldLoadedLatch) {
|
||||
measureDebugTime("Renderer.LightRun*") {
|
||||
// recalculate for even frames, or if the sign of the cam-x changed
|
||||
// recalculate for every three frame, or if the sign of the cam-x changed
|
||||
if (App.GLOBAL_RENDER_TIMER % 3 == 0L || Math.abs(WorldCamera.x - oldCamX) >= world.width * 0.85f * TILE_SIZEF || newWorldLoadedLatch) {
|
||||
LightmapRenderer.recalculate(actorsRenderFarBehind + actorsRenderBehind + actorsRenderFront + actorsRenderMidTop + actorsRenderMiddle + actorsRenderOverlay)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,9 @@ internal object BlocksDrawer {
|
||||
val ORES = GameWorld.ORES
|
||||
val FLUID = -2
|
||||
val OCCLUSION = 31337
|
||||
val BLURMAP = 31338
|
||||
val BLURMAP_BASE = 31338
|
||||
val BLURMAP_TERR = BLURMAP_BASE + TERRAIN
|
||||
val BLURMAP_WALL = BLURMAP_BASE + WALL
|
||||
|
||||
private const val OCCLUSION_TILE_NUM_BASE = 16
|
||||
|
||||
@@ -98,7 +100,8 @@ internal object BlocksDrawer {
|
||||
private lateinit var oreTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled)
|
||||
private lateinit var fluidTilesBuffer: UnsafeLong2D // stores subtiles (dimension is doubled)
|
||||
private lateinit var occlusionBuffer: UnsafeLong2D // stores subtiles (dimension is doubled)
|
||||
private lateinit var blurMap: 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 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 tilesBuffer2: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
||||
@@ -257,8 +260,9 @@ internal object BlocksDrawer {
|
||||
}
|
||||
catch (e: ClassCastException) { }
|
||||
|
||||
if (!world.layerTerrain.ptrDestroyed) {
|
||||
measureDebugTime("Renderer.Tiling") {
|
||||
if (doTilemapUpdate) {
|
||||
// rendering tilemap only updates every three frame
|
||||
measureDebugTime("Renderer.Tiling*") {
|
||||
drawTiles(WALL)
|
||||
drawTiles(TERRAIN) // regular tiles
|
||||
drawTiles(ORES)
|
||||
@@ -334,7 +338,7 @@ internal object BlocksDrawer {
|
||||
}
|
||||
|
||||
private val occlusionRenderTag = CreateTileAtlas.RenderTag(
|
||||
OCCLUSION_TILE_NUM_BASE, CreateTileAtlas.RenderTag.CONNECT_SELF, CreateTileAtlas.RenderTag.MASK_47, 0
|
||||
OCCLUSION_TILE_NUM_BASE, CreateTileAtlas.RenderTag.CONNECT_SELF, CreateTileAtlas.RenderTag.MASK_47, 0, 0
|
||||
)
|
||||
|
||||
private lateinit var renderOnF3Only: Array<Int>
|
||||
@@ -583,19 +587,21 @@ internal object BlocksDrawer {
|
||||
else 0
|
||||
|
||||
if (mode == TERRAIN || mode == WALL) {
|
||||
// TODO translate nearbyTilesInfo into proper subtile number
|
||||
// translate nearbyTilesInfo into proper subtile number
|
||||
val nearbyTilesInfo = getNearbyTilesInfoDeblocking(mode, x, y)
|
||||
val subtiles = if (nearbyTilesInfo == null)
|
||||
listOf(
|
||||
Point2i(130, 1), Point2i(130, 1), Point2i(130, 1), Point2i(130, 1)
|
||||
)
|
||||
else
|
||||
(0..3).map {
|
||||
Point2i(126, 0) + deblockerNearbyTilesToSubtile[it][nearbyTilesInfo]
|
||||
}
|
||||
|
||||
// TEST CODE
|
||||
val subtiles = arrayOf(
|
||||
Point2i(130, 0),
|
||||
Point2i(131, 0),
|
||||
Point2i(131, 1),
|
||||
Point2i(130, 1),
|
||||
)
|
||||
/*TL*/writeToBufferSubtile(BLURMAP, bufferBaseX * 2 + 0, bufferBaseY * 2 + 0, subtiles[0].x, subtiles[0].y, 0, 0)
|
||||
/*TR*/writeToBufferSubtile(BLURMAP, bufferBaseX * 2 + 1, bufferBaseY * 2 + 0, subtiles[1].x, subtiles[1].y, 0, 0)
|
||||
/*BR*/writeToBufferSubtile(BLURMAP, bufferBaseX * 2 + 1, bufferBaseY * 2 + 1, subtiles[2].x, subtiles[2].y, 0, 0)
|
||||
/*BL*/writeToBufferSubtile(BLURMAP, bufferBaseX * 2 + 0, bufferBaseY * 2 + 1, subtiles[3].x, subtiles[3].y, 0, 0)
|
||||
/*TL*/writeToBufferSubtile(BLURMAP_BASE + mode, bufferBaseX * 2 + 0, bufferBaseY * 2 + 0, subtiles[0].x, subtiles[0].y, 0, 0)
|
||||
/*TR*/writeToBufferSubtile(BLURMAP_BASE + mode, bufferBaseX * 2 + 1, bufferBaseY * 2 + 0, subtiles[1].x, subtiles[1].y, 0, 0)
|
||||
/*BR*/writeToBufferSubtile(BLURMAP_BASE + mode, bufferBaseX * 2 + 1, bufferBaseY * 2 + 1, subtiles[2].x, subtiles[2].y, 0, 0)
|
||||
/*BL*/writeToBufferSubtile(BLURMAP_BASE + mode, bufferBaseX * 2 + 0, bufferBaseY * 2 + 1, subtiles[3].x, subtiles[3].y, 0, 0)
|
||||
}
|
||||
|
||||
if (renderTag.maskType >= CreateTileAtlas.RenderTag.MASK_SUBTILE_GENERIC) {
|
||||
@@ -796,6 +802,48 @@ internal object BlocksDrawer {
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun getNearbyTilesInfoDeblocking(mode: Int, x: Int, y: Int): Int? {
|
||||
val tileThis = world.getTileFrom(mode, x, y)
|
||||
val nearbyTiles = getNearbyTilesPos4(x, y).map { world.getTileFrom(mode, it.x, it.y) }
|
||||
|
||||
val renderTagThis = App.tileMaker.getRenderTag(tileThis)
|
||||
|
||||
if (renderTagThis.postProcessing != CreateTileAtlas.RenderTag.POSTPROCESS_DEBLOCKING) return null
|
||||
|
||||
when (renderTagThis.connectionType) {
|
||||
CreateTileAtlas.RenderTag.CONNECT_SELF -> {
|
||||
var ret = 0
|
||||
for (i in nearbyTiles.indices) {
|
||||
if (nearbyTiles[i] == tileThis) {
|
||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
CreateTileAtlas.RenderTag.CONNECT_MUTUAL -> {
|
||||
// make sure to not connect to tiles with no deblocking
|
||||
var ret = 0
|
||||
for (i in nearbyTiles.indices) {
|
||||
if (BlockCodex[nearbyTiles[i]].isSolidForTileCnx && isConnectMutual(nearbyTiles[i]) &&
|
||||
App.tileMaker.getRenderTag(nearbyTiles[i]).postProcessing == CreateTileAtlas.RenderTag.POSTPROCESS_DEBLOCKING
|
||||
) {
|
||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
}
|
||||
|
||||
private val deblockerNearbyTilesToSubtile: Array<Array<Point2i>> = arrayOf(
|
||||
arrayOf(Point2i(0,0),Point2i(0,0),Point2i(0,0),Point2i(0,0),Point2i(3,0),Point2i(3,0),Point2i(3,0),Point2i(3,0),Point2i(2,0),Point2i(2,0),Point2i(2,0),Point2i(2,0),Point2i(4,0),Point2i(4,0),Point2i(4,0),Point2i(4,0)), /*TL*/
|
||||
arrayOf(Point2i(1,0),Point2i(3,0),Point2i(1,0),Point2i(3,0),Point2i(1,0),Point2i(3,0),Point2i(1,0),Point2i(3,0),Point2i(3,1),Point2i(4,0),Point2i(3,1),Point2i(4,0),Point2i(3,1),Point2i(4,0),Point2i(3,1),Point2i(4,0)), /*TR*/
|
||||
arrayOf(Point2i(1,1),Point2i(2,1),Point2i(3,1),Point2i(4,0),Point2i(1,1),Point2i(2,1),Point2i(3,1),Point2i(4,0),Point2i(1,1),Point2i(2,1),Point2i(3,1),Point2i(4,0),Point2i(1,1),Point2i(2,1),Point2i(3,1),Point2i(4,0)), /*BR*/
|
||||
arrayOf(Point2i(0,1),Point2i(0,1),Point2i(2,0),Point2i(2,0),Point2i(2,1),Point2i(2,1),Point2i(4,0),Point2i(4,0),Point2i(0,1),Point2i(0,1),Point2i(2,0),Point2i(2,0),Point2i(2,1),Point2i(2,1),Point2i(4,0),Point2i(4,0)), /*BL*/
|
||||
)
|
||||
|
||||
private fun getNearbyTilesInfoConMutual(x: Int, y: Int, mode: Int): Int {
|
||||
val nearbyTiles: List<ItemID> = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) }
|
||||
|
||||
@@ -1075,7 +1123,6 @@ internal object BlocksDrawer {
|
||||
ORES -> oreTilesBuffer
|
||||
FLUID -> fluidTilesBuffer
|
||||
OCCLUSION -> occlusionBuffer
|
||||
BLURMAP -> blurMap
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
@@ -1092,7 +1139,8 @@ internal object BlocksDrawer {
|
||||
ORES -> oreTilesBuffer
|
||||
FLUID -> fluidTilesBuffer
|
||||
OCCLUSION -> occlusionBuffer
|
||||
BLURMAP -> blurMap
|
||||
BLURMAP_TERR -> blurMapTerr
|
||||
BLURMAP_WALL -> blurMapWall
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
@@ -1107,6 +1155,9 @@ internal object BlocksDrawer {
|
||||
private var _blurTilesBuffer: Texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
||||
private val occlusionIntensity = 0.25f // too low value and dark-coloured walls won't darken enough
|
||||
|
||||
private val doTilemapUpdate: Boolean
|
||||
get() = (!world.layerTerrain.ptrDestroyed && App.GLOBAL_RENDER_TIMER % 3 == 0L)
|
||||
|
||||
private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean) {
|
||||
//Gdx.gl.glClearColor(.094f, .094f, .094f, 0f)
|
||||
//Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
|
||||
@@ -1117,7 +1168,7 @@ internal object BlocksDrawer {
|
||||
|
||||
|
||||
val tileAtlas = when (mode) {
|
||||
TERRAIN, ORES, WALL, OCCLUSION, FLUID, BLURMAP -> tilesTerrain
|
||||
TERRAIN, ORES, WALL, OCCLUSION, FLUID, BLURMAP_TERR, BLURMAP_WALL -> tilesTerrain
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
val sourceBuffer = when(mode) {
|
||||
@@ -1133,35 +1184,33 @@ internal object BlocksDrawer {
|
||||
else -> Color.WHITE
|
||||
}
|
||||
|
||||
|
||||
// write to colour buffer
|
||||
// As the texture size is very small, multithreading it would be less effective
|
||||
for (y in 0 until tilesBuffer.height) {
|
||||
for (x in 0 until tilesBuffer.width) {
|
||||
val colRaw = sourceBuffer[y, x]
|
||||
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) {
|
||||
// TODO making it run sporadically without graphical issue would improve the tiling performance
|
||||
// if (doTilemapUpdate) {
|
||||
for (y in 0 until tilesBuffer.height) {
|
||||
for (x in 0 until tilesBuffer.width) {
|
||||
val colRaw = blurMap[y, x]
|
||||
val colRaw = sourceBuffer[y, x]
|
||||
val colMain = colRaw.toInt()
|
||||
val colSub = colRaw.ushr(32).toInt()
|
||||
|
||||
blurTilesBuffer.setColor(colMain)
|
||||
blurTilesBuffer.drawPixel(x, y)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
_tilesBufferAsTex.dispose()
|
||||
@@ -1256,7 +1305,8 @@ internal object BlocksDrawer {
|
||||
oreTilesBuffer = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
|
||||
fluidTilesBuffer = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
|
||||
occlusionBuffer = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
|
||||
blurMap = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
|
||||
blurMapTerr = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
|
||||
blurMapWall = UnsafeLong2D(tilesInHorizontal, tilesInVertical)
|
||||
tempRenderTypeBuffer = UnsafeLong2D(hTilesInHorizontal, hTilesInVertical)
|
||||
|
||||
tilesBuffer.dispose()
|
||||
@@ -1346,7 +1396,8 @@ internal object BlocksDrawer {
|
||||
if (::oreTilesBuffer.isInitialized) oreTilesBuffer.destroy()
|
||||
if (::fluidTilesBuffer.isInitialized) fluidTilesBuffer.destroy()
|
||||
if (::occlusionBuffer.isInitialized) occlusionBuffer.destroy()
|
||||
if (::blurMap.isInitialized) blurMap.destroy()
|
||||
if (::blurMapTerr.isInitialized) blurMapTerr.destroy()
|
||||
if (::blurMapWall.isInitialized) blurMapWall.destroy()
|
||||
if (::tempRenderTypeBuffer.isInitialized) tempRenderTypeBuffer.destroy()
|
||||
|
||||
if (::batch.isInitialized) batch.tryDispose()
|
||||
|
||||
@@ -87,7 +87,7 @@ class CreateTileAtlas {
|
||||
lateinit var tagsByTileNum: HashArray<RenderTag>; private set
|
||||
lateinit var itemSheetNumbers: HashMap<ItemID, Int> // TileID, Int
|
||||
private set
|
||||
private val defaultRenderTag = RenderTag(3, RenderTag.CONNECT_SELF, RenderTag.MASK_NA, 0) // 'update' block
|
||||
private val defaultRenderTag = RenderTag(3, RenderTag.CONNECT_SELF, RenderTag.MASK_NA, 0, 0) // 'update' block
|
||||
var initialised = false
|
||||
private set
|
||||
|
||||
@@ -478,20 +478,23 @@ class CreateTileAtlas {
|
||||
val maskType = if (tilesPixmap.width >= 3*W_SUBTILE_GENERIC) MASK_SUBTILE_GRASS else MASK_SUBTILE_GENERIC
|
||||
var connectionType0 = 0
|
||||
var tilingMode = 0
|
||||
var postProcessing = 0
|
||||
for (x in 0 until 4) {
|
||||
// val pixelY0 = (tilesPixmap.getPixel(x, 0).and(255) >= 128).toInt(x)
|
||||
val pixelY1 = (tilesPixmap.getPixel(x, 1).and(255) >= 128).toInt(x)
|
||||
val pixelY2 = (tilesPixmap.getPixel(x, 2).and(255) >= 128).toInt(x)
|
||||
val pixelY3 = (tilesPixmap.getPixel(x, 3).and(255) >= 128).toInt(x)
|
||||
|
||||
tilingMode += pixelY1
|
||||
connectionType0 += pixelY2
|
||||
postProcessing += pixelY3
|
||||
}
|
||||
val connectionType = when (connectionType0) {
|
||||
1 -> CONNECT_MUTUAL
|
||||
2 -> CONNECT_SELF
|
||||
else -> throw IllegalArgumentException("$connectionType0")
|
||||
}
|
||||
addTag(blockID, connectionType, maskType, tilingMode)
|
||||
addTag(blockID, connectionType, maskType, tilingMode, postProcessing)
|
||||
// println("drawToAtlantes tile: $blockID with mode $tilingMode")
|
||||
drawToAtlantes(tilesPixmap, tilesGlowPixmap, tilesEmissivePixmap, maskType)
|
||||
}
|
||||
@@ -541,13 +544,13 @@ class CreateTileAtlas {
|
||||
* This function must precede the drawToAtlantes() function, as the marking requires the variable
|
||||
* 'atlasCursor' and the draw function modifies it!
|
||||
*/
|
||||
private fun addTag(id: ItemID, connectionType: Int, maskType: Int, tilingMode: Int = TILING_FULL) {
|
||||
private fun addTag(id: ItemID, connectionType: Int, maskType: Int, tilingMode: Int = TILING_FULL, postProcessing: Int = 0) {
|
||||
if (tags.containsKey(id)) {
|
||||
throw Error("Block $id already exists")
|
||||
}
|
||||
|
||||
tags[id] = RenderTag(atlasCursor, connectionType, maskType, tilingMode)
|
||||
tagsByTileNum[atlasCursor.toLong()] = RenderTag(atlasCursor, connectionType, maskType, tilingMode)
|
||||
tags[id] = RenderTag(atlasCursor, connectionType, maskType, tilingMode, postProcessing)
|
||||
tagsByTileNum[atlasCursor.toLong()] = RenderTag(atlasCursor, connectionType, maskType, tilingMode, postProcessing)
|
||||
|
||||
printdbg(this, "tileName ${id} ->> tileNumber ${atlasCursor}")
|
||||
}
|
||||
@@ -714,7 +717,7 @@ class CreateTileAtlas {
|
||||
/**
|
||||
* @param tileNumber ordinal number of a tile in the texture atlas
|
||||
*/
|
||||
data class RenderTag(val tileNumber: Int, val connectionType: Int, val maskType: Int, val tilingMode: Int) {
|
||||
data class RenderTag(val tileNumber: Int, val connectionType: Int, val maskType: Int, val tilingMode: Int, val postProcessing: Int) {
|
||||
companion object {
|
||||
const val CONNECT_MUTUAL = 0
|
||||
const val CONNECT_SELF = 1
|
||||
@@ -740,6 +743,9 @@ class CreateTileAtlas {
|
||||
const val TILING_BRICK_LARGE = 4
|
||||
const val TILING_BRICK_LARGE_NOFLIP = 5
|
||||
|
||||
const val POSTPROCESS_NONE = 0
|
||||
const val POSTPROCESS_DEBLOCKING = 1
|
||||
|
||||
fun maskTypeToTileCount(maskType: Int) = when (maskType) {
|
||||
MASK_NA -> 1
|
||||
MASK_16 -> 16
|
||||
|
||||
@@ -191,8 +191,8 @@ void main() {
|
||||
vec4 tileU = getFragColorForOnscreenCoord1(fragCoord + blurU);
|
||||
vec4 tileD = getFragColorForOnscreenCoord1(fragCoord + blurD);
|
||||
|
||||
vec4 blurH = (tileC + tileC + tileL + tileR) * _four;
|
||||
vec4 blurV = (tileC + tileC + tileU + tileD) * _four;
|
||||
vec4 blurH = (tileC + tileL + tileR) * _three;
|
||||
vec4 blurV = (tileC + tileU + tileD) * _three;
|
||||
vec4 blurPower = tile_breakage_blur[2];
|
||||
|
||||
vec4 finalTile = mix(
|
||||
@@ -206,5 +206,5 @@ void main() {
|
||||
vec4 finalColor = fma(mix(finalTile, finalBreakage, finalBreakage.a), bc.xxxy, finalTile * bc.yyyx);
|
||||
|
||||
fragColor = mix(colourFilter, colourFilter * finalColor, mulBlendIntensity);
|
||||
// fragColor = blurPower;
|
||||
// fragColor = mix(fragColor, blurPower, 0.18); // debug overlay
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user