mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
rudimentary minimap draw only
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
} }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user