mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-16 00:26:07 +09:00
tileatlas: atlas size will automatically expand if it's too small
This commit is contained in:
@@ -699,7 +699,7 @@ open class ActorWithBody : Actor {
|
||||
}
|
||||
|
||||
private fun displaceHitbox() {
|
||||
val printdbg1 = true && App.IS_DEVELOPMENT_BUILD
|
||||
val printdbg1 = false && App.IS_DEVELOPMENT_BUILD
|
||||
// // HOW IT SHOULD WORK // //
|
||||
// ////////////////////////
|
||||
// combineVeloToMoveDelta now
|
||||
|
||||
@@ -349,7 +349,7 @@ internal object BlocksDrawer {
|
||||
val tileNumber = if (thisTile == Block.AIR) 0
|
||||
// special case: actorblocks and F3 key
|
||||
else if (BlockCodex.hasProp(thisTile) && BlockCodex[thisTile].isActorBlock &&
|
||||
!BlockCodex[thisTile].tags.contains("DORENDER") && !KeyToggler.isOn(Keys.F3))
|
||||
!BlockCodex[thisTile].hasTag("DORENDER") && !KeyToggler.isOn(Keys.F3))
|
||||
0
|
||||
// special case: fluids
|
||||
else if (mode == FLUID)
|
||||
|
||||
@@ -6,7 +6,9 @@ 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.jme3.math.FastMath
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.gdx.graphics.PixmapIO2
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
@@ -15,6 +17,7 @@ import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas.AtlasSource.*
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
|
||||
/**
|
||||
* This class implements work_files/dynamic_shape_2_0.psd
|
||||
@@ -28,13 +31,12 @@ import kotlin.math.roundToInt
|
||||
*/
|
||||
class CreateTileAtlas {
|
||||
|
||||
// min size 1024 = tile_size 16 * atlasCursor 64
|
||||
val MAX_TEX_SIZE = App.getConfigInt("atlastexsize").coerceIn(1024, App.glInfo.GL_MAX_TEXTURE_SIZE)
|
||||
val TILES_IN_X = MAX_TEX_SIZE / TILE_SIZE
|
||||
var MAX_TEX_SIZE = App.getConfigInt("atlastexsize").coerceIn(1024, App.glInfo.GL_MAX_TEXTURE_SIZE); private set
|
||||
var TILES_IN_X = MAX_TEX_SIZE / TILE_SIZE; private set
|
||||
|
||||
val SHADER_SIZE_KEYS = floatArrayOf(MAX_TEX_SIZE.toFloat(), MAX_TEX_SIZE.toFloat(), TILES_IN_X.toFloat(), TILES_IN_X.toFloat())
|
||||
var SHADER_SIZE_KEYS = floatArrayOf(MAX_TEX_SIZE.toFloat(), MAX_TEX_SIZE.toFloat(), TILES_IN_X.toFloat(), TILES_IN_X.toFloat()); private set
|
||||
|
||||
private val TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
private var TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
|
||||
val wallOverlayColour = Color(.65f, .65f, .65f, 1f)
|
||||
|
||||
@@ -66,12 +68,54 @@ class CreateTileAtlas {
|
||||
private val atlasInit = "./assets/graphics/blocks/init.tga"
|
||||
private var itemSheetCursor = 16
|
||||
|
||||
internal val itemTerrainPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal val itemTerrainPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal val itemWallPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal val itemWallPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
internal lateinit var itemTerrainPixmap: Pixmap
|
||||
internal lateinit var itemTerrainPixmapGlow: Pixmap
|
||||
internal lateinit var itemWallPixmap: Pixmap
|
||||
internal lateinit var itemWallPixmapGlow: Pixmap
|
||||
|
||||
|
||||
private fun drawInitPixmap() {
|
||||
val initPixmap = Pixmap(Gdx.files.internal(atlasInit))
|
||||
|
||||
val tilesInInitPixmap = (initPixmap.width * initPixmap.height) / (TILE_SIZE * TILE_SIZE)
|
||||
val tilesPossibleInCurrentPixmap = (atlas.width * atlas.height) / (TILE_SIZE * TILE_SIZE)
|
||||
|
||||
if (tilesInInitPixmap > tilesPossibleInCurrentPixmap) throw Error("Atlas size too small -- can't even fit the init.tga (MAX_TEX_SIZE must be at least ${FastMath.nextPowerOfTwo((sqrt(tilesInInitPixmap.toFloat()) * TILE_SIZE).ceilToInt())})")
|
||||
|
||||
if (MAX_TEX_SIZE >= initPixmap.width) {
|
||||
atlas.drawPixmap(initPixmap, 0, 0)
|
||||
atlasAutumn.drawPixmap(initPixmap, 0, 0)
|
||||
atlasWinter.drawPixmap(initPixmap, 0, 0)
|
||||
atlasSpring.drawPixmap(initPixmap, 0, 0)
|
||||
}
|
||||
else {
|
||||
/*
|
||||
What's happening:
|
||||
|
||||
src: dest:
|
||||
AAAABBBBCCCCDDDD AAAA
|
||||
BBBB
|
||||
CCCC
|
||||
DDDD
|
||||
*/
|
||||
val destX = 0
|
||||
val srcY = 0
|
||||
val scanW = MAX_TEX_SIZE
|
||||
val scanH = TILE_SIZE
|
||||
for (scantile in 0 until (initPixmap.width.toFloat() / MAX_TEX_SIZE).ceilToInt()) {
|
||||
val srcX = scantile * scanW
|
||||
val destY = scantile * TILE_SIZE
|
||||
|
||||
atlas.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
atlasAutumn.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
atlasWinter.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
atlasSpring.drawPixmap(initPixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
}
|
||||
}
|
||||
|
||||
initPixmap.dispose()
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called AFTER mods' loading so that all the block props are loaded
|
||||
*/
|
||||
@@ -80,27 +124,17 @@ class CreateTileAtlas {
|
||||
tags = HashMap<ItemID, RenderTag>()
|
||||
itemSheetNumbers = HashMap<ItemID, Int>()
|
||||
|
||||
atlas = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasAutumn = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasWinter = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasSpring = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasFluid = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
atlasGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
|
||||
atlas.blending = Pixmap.Blending.None
|
||||
atlasAutumn.blending = Pixmap.Blending.None
|
||||
atlasWinter.blending = Pixmap.Blending.None
|
||||
atlasSpring.blending = Pixmap.Blending.None
|
||||
atlasFluid.blending = Pixmap.Blending.None
|
||||
atlasGlow.blending = Pixmap.Blending.None
|
||||
atlas = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasAutumn = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasWinter = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasSpring = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasFluid = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
atlasGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
||||
|
||||
// populate the atlantes with atlasInit
|
||||
// this just directly copies the image to the atlantes :p
|
||||
val initPixmap = Pixmap(Gdx.files.internal(atlasInit))
|
||||
atlas.drawPixmap(initPixmap, 0, 0)
|
||||
atlasAutumn.drawPixmap(initPixmap, 0, 0)
|
||||
atlasWinter.drawPixmap(initPixmap, 0, 0)
|
||||
atlasSpring.drawPixmap(initPixmap, 0, 0)
|
||||
drawInitPixmap()
|
||||
|
||||
|
||||
// get all the files applicable
|
||||
// first, get all the '/blocks' directory, and add all the files, regardless of their extension, to the list
|
||||
@@ -135,8 +169,8 @@ class CreateTileAtlas {
|
||||
}
|
||||
|
||||
// test print
|
||||
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/atlas.tga"), atlas, false)
|
||||
//PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/atlasGlow.tga"), atlasGlow, false)
|
||||
// PixmapIO2.writeTGA(Gdx.files.absolute("${App.defaultDir}/atlas.tga"), atlas, false)
|
||||
// PixmapIO2.writeTGA(Gdx.files.absolute("${AppLoader.defaultDir}/atlasGlow.tga"), atlasGlow, false)
|
||||
|
||||
|
||||
|
||||
@@ -161,6 +195,11 @@ class CreateTileAtlas {
|
||||
// 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)
|
||||
|
||||
itemTerrainPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemTerrainPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemWallPixmap = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
itemWallPixmapGlow = Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888)
|
||||
|
||||
tags.toMap().forEach { id, tag ->
|
||||
val tilePosFromAtlas = tag.tileNumber + maskTypetoTileIDForItemImage(tag.maskType)
|
||||
val srcX = (tilePosFromAtlas % TILES_IN_X) * TILE_SIZE
|
||||
@@ -217,7 +256,6 @@ class CreateTileAtlas {
|
||||
itemWallTextureGlow = Texture(itemWallPixmapGlow)
|
||||
// itemTerrainPixmap.dispose()
|
||||
// itemWallPixmap.dispose()
|
||||
initPixmap.dispose()
|
||||
|
||||
initialised = true
|
||||
} }
|
||||
@@ -242,6 +280,7 @@ class CreateTileAtlas {
|
||||
val blockName = matte.nameWithoutExtension().split('-').last().toInt() // basically a filename
|
||||
val blockID = "$modname:$blockName"
|
||||
|
||||
|
||||
// determine the type of the block (populate tags list)
|
||||
// predefined by the image dimension: 16x16 for (1,0)
|
||||
if (tilesPixmap.width == TILE_SIZE && tilesPixmap.height == TILE_SIZE) {
|
||||
@@ -307,8 +346,10 @@ class CreateTileAtlas {
|
||||
}
|
||||
|
||||
private fun drawToAtlantes(matte: Pixmap, glow: Pixmap, tilesCount: Int) {
|
||||
if (atlasCursor >= TOTAL_TILES) {
|
||||
throw Error("Too much tiles for $MAX_TEX_SIZE texture size: $atlasCursor")
|
||||
if (atlasCursor + tilesCount >= TOTAL_TILES) {
|
||||
// throw Error("Too much tiles for $MAX_TEX_SIZE texture size: $atlasCursor")
|
||||
println("[CreateTileAtlas] Too much tiles for atlas of ${MAX_TEX_SIZE}x$MAX_TEX_SIZE (tiles so far: $atlasCursor/${(MAX_TEX_SIZE*MAX_TEX_SIZE)/(TILE_SIZE* TILE_SIZE)}, tiles to be added: $tilesCount), trying to expand the atlas...")
|
||||
expandAtlantes()
|
||||
}
|
||||
|
||||
val seasonal = matte.width == matte.height && matte.width == 14 * TILE_SIZE
|
||||
@@ -413,4 +454,60 @@ class CreateTileAtlas {
|
||||
private enum class AtlasSource {
|
||||
FOUR_SEASONS, SUMMER, AUTUMN, WINTER, SPRING, FLUID, GLOW
|
||||
}
|
||||
|
||||
private fun expandAtlantes() {
|
||||
if (MAX_TEX_SIZE >= App.glInfo.GL_MAX_TEXTURE_SIZE) {
|
||||
throw RuntimeException("Cannot expand atlas: texture size is already at its maximum possible size allowed by the graphics processor (${MAX_TEX_SIZE}x${MAX_TEX_SIZE})")
|
||||
}
|
||||
|
||||
val oldTexSize = MAX_TEX_SIZE
|
||||
val newTexSize = oldTexSize * 2
|
||||
|
||||
|
||||
MAX_TEX_SIZE = newTexSize
|
||||
TILES_IN_X = MAX_TEX_SIZE / TILE_SIZE
|
||||
SHADER_SIZE_KEYS = floatArrayOf(MAX_TEX_SIZE.toFloat(), MAX_TEX_SIZE.toFloat(), TILES_IN_X.toFloat(), TILES_IN_X.toFloat())
|
||||
TOTAL_TILES = TILES_IN_X * TILES_IN_X
|
||||
|
||||
|
||||
val newAtlantes = Array<Pixmap>(5) {
|
||||
Pixmap(TILES_IN_X * TILE_SIZE, TILES_IN_X * TILE_SIZE, Pixmap.Format.RGBA8888).also {
|
||||
it.blending = Pixmap.Blending.None
|
||||
it.filter = Pixmap.Filter.NearestNeighbour
|
||||
}
|
||||
}
|
||||
listOf(atlas, atlasAutumn, atlasWinter, atlasSpring, atlasGlow).forEachIndexed { index, pixmap ->
|
||||
/*
|
||||
How it works:
|
||||
|
||||
old: new:
|
||||
AAAAAAAA AAAAAAAABBBBBBBB
|
||||
BBBBBBBB CCCCCCCCDDDDDDDD
|
||||
CCCCCCCC ...
|
||||
DDDDDDDD
|
||||
...
|
||||
|
||||
*/
|
||||
for (scantile in 0 until pixmap.height / TILE_SIZE) {
|
||||
val srcX = 0
|
||||
val srcY = scantile * TILE_SIZE
|
||||
val destX = (scantile % 2) * oldTexSize
|
||||
val destY = (scantile / 2) * TILE_SIZE
|
||||
val scanW = pixmap.width
|
||||
val scanH = TILE_SIZE
|
||||
|
||||
newAtlantes[index].drawPixmap(pixmap, srcX, srcY, scanW, scanH, destX, destY, scanW, scanH)
|
||||
}
|
||||
pixmap.dispose()
|
||||
}
|
||||
|
||||
atlas = newAtlantes[0]
|
||||
atlasAutumn = newAtlantes[1]
|
||||
atlasWinter = newAtlantes[2]
|
||||
atlasSpring = newAtlantes[3]
|
||||
atlasGlow = newAtlantes[4]
|
||||
|
||||
|
||||
App.setConfig("atlastexsize", newTexSize)
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,12 @@ object FeaturesDrawer {
|
||||
TileSurvey.submitProposal(
|
||||
TileSurvey.SurveyProposal(
|
||||
"basegame.FeaturesDrawer.coldTiles", 72, 48, 2, 2
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].tags.contains("COLD") }
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].hasTag("COLD") }
|
||||
)
|
||||
TileSurvey.submitProposal(
|
||||
TileSurvey.SurveyProposal(
|
||||
"basegame.FeaturesDrawer.warmTiles", 72, 48, 2, 2
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].tags.contains("WARM") }
|
||||
) { world, x, y -> BlockCodex[world.getTileFromTerrain(x, y)].hasTag("WARM") }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user