rudimentary minimap draw only

This commit is contained in:
minjaesong
2019-03-08 18:49:38 +09:00
parent a1022a3db1
commit cd97b5c4ab
5 changed files with 160 additions and 46 deletions

View File

@@ -12,6 +12,8 @@ import javax.naming.OperationNotSupportedException
class GdxColorMap {
constructor(imageFile: FileHandle) {
AppLoader.printdbg(this, "Loading colormap from ${imageFile.name()}")
val pixmap = Pixmap(imageFile)
width = pixmap.width
height = pixmap.height
@@ -21,13 +23,21 @@ class GdxColorMap {
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
}
AppLoader.printdbg(this, "Loading colormap from ${imageFile.name()}; PixmapFormat: ${pixmap.format}; Dimension: $width x $height")
pixmap.dispose()
}
constructor(pixmap: Pixmap, disposePixmap: Boolean = true) {
width = pixmap.width
height = pixmap.height
is2D = pixmap.height > 1
data = kotlin.IntArray(pixmap.width * pixmap.height) {
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
}
if (disposePixmap) pixmap.dispose()
}
constructor(color: Color) {
data = intArrayOf(color.toIntBits())
width = 1

View File

@@ -1,12 +1,16 @@
package net.torvald.terrarum.blockstats
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.utils.GdxRuntimeException
import com.badlogic.gdx.utils.Queue
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.worlddrawer.toRGBA
import net.torvald.terrarum.worlddrawer.BlocksDrawer
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
object MinimapComposer {
@@ -32,7 +36,6 @@ object MinimapComposer {
}
var tempTex = Texture(1,1,Pixmap.Format.RGBA8888)
val minimap = Pixmap(Gdx.files.internal("./assets/testimage.png"))
// total size of the minimap. Remember: textures can be mosaic-ed to display full map.
var totalWidth = 0
var totalHeight = 0
@@ -45,14 +48,20 @@ object MinimapComposer {
const val LIVETILE_SIZE = 64
const val DISPLAY_CANVAS_WIDTH = 2048
const val DISPLAY_CANVAS_HEIGHT = 1024
val minimap = Pixmap(DISPLAY_CANVAS_WIDTH, DISPLAY_CANVAS_HEIGHT, Pixmap.Format.RGBA8888)
const val TILES_IN_X = DISPLAY_CANVAS_WIDTH / LIVETILE_SIZE
const val TILES_IN_Y = DISPLAY_CANVAS_HEIGHT / LIVETILE_SIZE
private val displayPixmap = Pixmap(DISPLAY_CANVAS_WIDTH, DISPLAY_CANVAS_HEIGHT, Pixmap.Format.RGBA8888)
// numbers inside of it will change a lot
private val tileSlot = Array(TILES_IN_Y) { IntArray(TILES_IN_X) }
private val tilemap = Array(TILES_IN_Y) { y -> IntArray(TILES_IN_X) { x -> y * TILES_IN_X + x } }
// pixmaps inside of this will never be redefined
private val liveTiles = Array(TILES_IN_X * TILES_IN_Y) { Pixmap(LIVETILE_SIZE, LIVETILE_SIZE, Pixmap.Format.RGBA8888) }
// indices are exacly the same as liveTiles
private val liveTilesMeta = Array(TILES_IN_X * TILES_IN_Y) { LiveTileMeta(revalidate = true) }
private val updaterQueue = Queue<Runnable>(TILES_IN_X * TILES_IN_Y * 2)
private var currentThreads = Array(maxOf(1, Terrarum.THREADS.times(2).div(3))) {
Thread()
}
init {
totalWidth = minimap.width
@@ -60,24 +69,74 @@ object MinimapComposer {
}
fun update() {
// make the queueing work
// enqueue first
for (y in 0 until tilemap.size) {
for (x in 0 until tilemap[0].size) {
if (liveTilesMeta[tilemap[y][x]].revalidate) {
liveTilesMeta[tilemap[y][x]].revalidate = false
updaterQueue.addLast(createUpdater(x, y))
printdbg(this, "Queueing tilemap update ($x,$y); queue size now: ${updaterQueue.size}")
}
}
}
// consume the queue
for (k in 0 until currentThreads.size) {
if (currentThreads[k].state == Thread.State.TERMINATED && !updaterQueue.isEmpty) {
currentThreads[k] = Thread(updaterQueue.removeFirst(), "MinimapLivetilePainter")
printdbg(this, "Consuming from queue; queue size now: ${updaterQueue.size}")
}
if (currentThreads[k].state == Thread.State.NEW) {
currentThreads[k].start()
}
}
// assign tiles to the tilemap
// TODO
}
fun renderToBackground() {
for (y in 0 until TILES_IN_Y) {
for (x in 0 until TILES_IN_X) {
minimap.drawPixmap(liveTiles[tilemap[y][x]], x * LIVETILE_SIZE, y * LIVETILE_SIZE)
}
}
}
private val HQRNG = net.torvald.random.HQRNG()
private fun createUpdater(tileSlotIndexX: Int, tileSlotIndexY: Int) = Runnable {
val pixmap = liveTiles[tileSlot[tileSlotIndexY][tileSlotIndexX]]
val pixmap = liveTiles[tilemap[tileSlotIndexY][tileSlotIndexX]]
val topLeftX = topLeftCoordX + LIVETILE_SIZE * tileSlotIndexX
val topLeftY = topLeftCoordY + LIVETILE_SIZE * tileSlotIndexY
for (y in topLeftY until topLeftY + LIVETILE_SIZE) {
for (x in if (tileSlotIndexY >= TILES_IN_X / 2) (topLeftX + LIVETILE_SIZE - 1) downTo topLeftX else topLeftX until topLeftX + LIVETILE_SIZE) {
val color = Color.WHITE // TODO
pixmap.drawPixel(x - topLeftX, y - topLeftY, color.toRGBA())
val tileTerr = world.getTileFromTerrain(x, y) ?: throw Error("OoB: $x, $y")
val wallTerr = world.getTileFromWall(x, y) ?: Block.AIR
val colTerr = CreateTileAtlas.terrainTileColourMap.get(tileTerr % 16, tileTerr / 16)
val colWall = CreateTileAtlas.terrainTileColourMap.get(wallTerr % 16, wallTerr / 16).mul(BlocksDrawer.wallOverlayColour)
if (colTerr.a < 1f) {
pixmap.setColor(colWall)
pixmap.drawPixel(x - topLeftX, y - topLeftY)
}
pixmap.setColor(colTerr)
pixmap.drawPixel(x - topLeftX, y - topLeftY)
}
}
}
fun dispose() {
liveTiles.forEach { it.dispose() }
minimap.dispose()
try {
tempTex.dispose()
}
catch (e: GdxRuntimeException) {}
}
private data class LiveTileMeta(var revalidate: Boolean)
}

View File

@@ -216,6 +216,10 @@ class UIInventoryFull(
transitionalUpdateUIs.forEach { it.update(delta) }
if (currentScreen > 1f + epsilon) {
MinimapComposer.setWorld(Terrarum.ingame!!.world)
MinimapComposer.update()
}
}
private val gradStartCol = Color(0x404040_60)
@@ -393,6 +397,9 @@ class UIInventoryFull(
// render minimap
batch.end()
MinimapComposer.renderToBackground()
minimapFBO.inAction(minimapCamera, batch) {
// whatever.
MinimapComposer.tempTex.dispose()
@@ -421,7 +428,7 @@ class UIInventoryFull(
batch.begin()
//Terrarum.fontSmallNumbers.draw(batch, "$minimapPanX, $minimapPanY; x$minimapZoom", 10f, 10f)
Terrarum.fontSmallNumbers.draw(batch, "$minimapPanX, $minimapPanY; x$minimapZoom", minimapScrOffX + (Terrarum.WIDTH - MINIMAP_WIDTH) / 2, -10f + itemList.posY)
batch.projectionMatrix = camera.combined

View File

@@ -129,43 +129,13 @@ internal object BlocksDrawer {
printdbg(this, "Making terrain and wall item textures...")
// create item_wall images
fun maskTypetoTileIDForItemImage(maskType: Int) = when(maskType) {
CreateTileAtlas.RenderTag.MASK_47 -> 17
CreateTileAtlas.RenderTag.MASK_PLATFORM -> 7
else -> 0
}
val itemTerrainPixmap = Pixmap(16 * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
val itemWallPixmap = Pixmap(16 * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
CreateTileAtlas.tags.toMap().forEach { t, u ->
val tilePosFromAtlas = u.tileNumber + maskTypetoTileIDForItemImage(u.maskType)
val srcX = (tilePosFromAtlas % TILES_IN_X) * TILE_SIZE
val srcY = (tilePosFromAtlas / TILES_IN_X) * TILE_SIZE
val destX = (t % 16) * TILE_SIZE
val destY = (t / 16) * TILE_SIZE
itemTerrainPixmap.drawPixmap(CreateTileAtlas.atlas, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
itemWallPixmap.drawPixmap(CreateTileAtlas.atlas, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
}
// darken things for the wall
for (y in 0 until itemWallPixmap.height) {
for (x in 0 until itemWallPixmap.width) {
val c = Color(itemWallPixmap.getPixel(x, y)).mulAndAssign(wallOverlayColour).toRGBA()
itemWallPixmap.drawPixel(x, y, c)
}
}
// test print
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/terrainitem.tga"), itemTerrainPixmap, false)
val itemTerrainTexture = Texture(itemTerrainPixmap)
val itemWallTexture = Texture(itemWallPixmap)
itemTerrainPixmap.dispose()
itemWallPixmap.dispose()
tileItemTerrain = TextureRegionPack(itemTerrainTexture, TILE_SIZE, TILE_SIZE)
tileItemWall = TextureRegionPack(itemWallTexture, TILE_SIZE, TILE_SIZE)
tileItemTerrain = TextureRegionPack(CreateTileAtlas.itemTerrainTexture, TILE_SIZE, TILE_SIZE)
tileItemWall = TextureRegionPack(CreateTileAtlas.itemWallTexture, TILE_SIZE, TILE_SIZE)

View File

@@ -4,11 +4,14 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.GdxColorMap
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.mulAndAssign
import net.torvald.terrarum.toInt
import kotlin.math.roundToInt
@@ -35,6 +38,9 @@ object CreateTileAtlas {
lateinit var atlasWinter: Pixmap
lateinit var atlasSpring: Pixmap
lateinit var atlasFluid: Pixmap
lateinit var itemTerrainTexture: Texture
lateinit var itemWallTexture: Texture
lateinit var terrainTileColourMap: GdxColorMap
internal lateinit var tags: HashMap<Int, RenderTag>
private set
private val defaultRenderTag = RenderTag(3, RenderTag.CONNECT_SELF, RenderTag.MASK_NA) // 'update' block
@@ -176,6 +182,68 @@ object CreateTileAtlas {
fluidMasterPixmap.dispose()
// create item_wall images
fun maskTypetoTileIDForItemImage(maskType: Int) = when(maskType) {
CreateTileAtlas.RenderTag.MASK_47 -> 17
CreateTileAtlas.RenderTag.MASK_PLATFORM -> 7
else -> 0
}
val itemTerrainPixmap = Pixmap(16 * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
val itemWallPixmap = Pixmap(16 * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
val terrainColormapPixmap = Pixmap(16, TILES_IN_X, Pixmap.Format.RGBA8888)
CreateTileAtlas.tags.toMap().forEach { t, u ->
val tilePosFromAtlas = u.tileNumber + maskTypetoTileIDForItemImage(u.maskType)
val srcX = (tilePosFromAtlas % TILES_IN_X) * TILE_SIZE
val srcY = (tilePosFromAtlas / TILES_IN_X) * TILE_SIZE
val destX = (t % 16) * TILE_SIZE
val destY = (t / 16) * TILE_SIZE
itemTerrainPixmap.drawPixmap(CreateTileAtlas.atlas, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
itemWallPixmap.drawPixmap(CreateTileAtlas.atlas, srcX, srcY, TILE_SIZE, TILE_SIZE, destX, destY, TILE_SIZE, TILE_SIZE)
}
// darken things for the wall
for (y in 0 until itemWallPixmap.height) {
for (x in 0 until itemWallPixmap.width) {
val c = Color(itemWallPixmap.getPixel(x, y)).mulAndAssign(BlocksDrawer.wallOverlayColour).toRGBA()
itemWallPixmap.drawPixel(x, y, c)
}
}
// create terrain colourmap
val pxCount = TILE_SIZE * TILE_SIZE
for (id in 0 until BlockCodex.MAX_TERRAIN_TILES) {
val tx = (id % 16) * TILE_SIZE
val ty = (id / 16) * TILE_SIZE
var r = 0; var g = 0; var b = 0; var a = 0
// average out the whole block
for (y in ty until ty + TILE_SIZE) {
for (x in tx until tx + TILE_SIZE) {
val data = itemTerrainPixmap.getPixel(x, y)
r += (data ushr 24) and 255
g += (data ushr 16) and 255
b += (data ushr 8) and 255
a += data and 255
}
}
terrainColormapPixmap.drawPixel(tx / TILE_SIZE, ty / TILE_SIZE,
(r / pxCount).shl(24) or
(g / pxCount).shl(16) or
(b / pxCount).shl(8) or
(a / pxCount)
)
}
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/terrain_colormap.tga"), terrainColormapPixmap, false)
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/terrainitem.tga"), itemTerrainPixmap, false)
terrainTileColourMap = GdxColorMap(terrainColormapPixmap)
itemTerrainTexture = Texture(itemTerrainPixmap)
itemWallTexture = Texture(itemWallPixmap)
itemTerrainPixmap.dispose()
itemWallPixmap.dispose()
initialised = true
} }