perf(render): Create dynamic texture for resources so swaps are only done on resource layer when we need the number (strategic resources)

This commit is contained in:
yairm210 2025-01-24 11:48:28 +02:00
parent 31aaf3c61a
commit 9f8c93d2ab
4 changed files with 35 additions and 39 deletions

View File

@ -48,5 +48,4 @@ abstract class TileLayer(val tileGroup: TileGroup, size: Float) : Group() {
protected abstract fun doUpdate(
viewingCiv: Civilization?,
localUniqueCache: LocalUniqueCache = LocalUniqueCache(false))
}

View File

@ -16,11 +16,7 @@ import com.unciv.ui.components.MapArrowType
import com.unciv.ui.components.MiscArrowTypes
import com.unciv.ui.components.TintedMapArrow
import com.unciv.ui.components.UnitMovementMemoryType
import com.unciv.ui.components.extensions.brighten
import com.unciv.ui.components.extensions.center
import com.unciv.ui.components.extensions.centerX
import com.unciv.ui.components.extensions.toLabel
import com.unciv.ui.components.extensions.toPrettyString
import com.unciv.ui.components.extensions.*
import com.unciv.ui.components.tilegroups.CityTileGroup
import com.unciv.ui.components.tilegroups.TileGroup
import com.unciv.ui.components.tilegroups.TileSetStrings
@ -124,17 +120,31 @@ class TileLayerResource(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup
if (resourceName != tile.resource || resourceAmount != tile.resourceAmount) {
resourceName = tile.resource
resourceAmount = tile.resourceAmount
resourceIcon?.remove()
clear()
resourceIcon = null
}
// Get a fresh Icon if and only if necessary
if (resourceName != null && effectiveVisible && resourceIcon == null) {
val icon = ImageGetter.getResourcePortrait(resourceName!!, 20f, resourceAmount)
val icon = ImageGetter.getImage(resourceName).apply { setSize(24f) }
icon.center(tileGroup)
icon.x -= 22 // left
icon.y += 10 // top
addActor(icon)
if (resourceAmount > 0) {
val label = resourceAmount.tr().toLabel(
fontSize = 8,
fontColor = Color.WHITE,
alignment = Align.center)
val amountGroup = label.surroundWithCircle(10f, true, ImageGetter.CHARCOAL)
label.y -= 0.5f
amountGroup.setPosition(icon.x + icon.width, icon.y, Align.bottomRight)
addActor(amountGroup)
}
resourceIcon = icon
}
@ -151,7 +161,7 @@ class TileLayerResource(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup
updateResourceIcon(null, false)
}
fun dimResource(dim: Boolean) { resourceIcon?.color?.a = if (dim) 0.5f else 1f }
private fun dimResource(dim: Boolean) { resourceIcon?.color?.a = if (dim) 0.5f else 1f }
override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) {
val showResourcesAndImprovements = if (tileGroup is WorldTileGroup)
@ -163,6 +173,10 @@ class TileLayerResource(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup
override fun determineVisibility() {
isVisible = resourceIcon?.isVisible == true
}
override fun act(delta: Float) {}
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? = null
override fun draw(batch: Batch?, parentAlpha: Float) = super.draw(batch, parentAlpha)
}

View File

@ -96,6 +96,7 @@ object ImageGetter {
FontRulesetIcons.addRulesetImages(ruleset)
setupStatImages()
setupResourcePortraits()
}
private fun setupStatImages() {
@ -107,14 +108,19 @@ object ImageGetter {
val nameToActorList = Stat.entries.map { it.name to getActor(it.name) }
packTexture(nameToActorList)
packTexture(nameToActorList, 100)
}
private fun setupResourcePortraits() {
val nameToActorList = ruleset.tileResources.values.map { it.name to getResourcePortrait(it.name, 100f, borderSize = 10f) }
packTexture(nameToActorList, 120)
}
private fun packTexture(nameToActorList: List<Pair<String, IconCircleGroup>>) {
private fun packTexture(nameToActorList: List<Pair<String, Group>>, size: Int) {
val pixmapPacker = PixmapPacker(2048, 2048, Pixmap.Format.RGBA8888, 2, false).apply { packToTexture = true }
for ((name, actor) in nameToActorList) {
actor.apply { isTransform = true; setScale(1f, -1f); setPosition(0f, height) } // flip Y axis
pixmapPacker.pack(name, FontRulesetIcons.getPixmapFromActorBase(actor, 100, 100))
pixmapPacker.pack(name, FontRulesetIcons.getPixmapFromActorBase(actor, size, size))
}
val yieldAtlas = pixmapPacker.generateTextureAtlas(
@ -316,8 +322,8 @@ object ImageGetter {
fun getPromotionPortrait(promotionName: String, size: Float = 30f): Group = PortraitPromotion(promotionName, size)
fun getResourcePortrait(resourceName: String, size: Float, amount: Int = 0): Group =
PortraitResource(resourceName, size, amount)
fun getResourcePortrait(resourceName: String, size: Float, borderSize: Float = 2f): Group =
PortraitResource(resourceName, size, borderSize)
fun getTechIconPortrait(techName: String, circleSize: Float): Group = PortraitTech(techName, circleSize)

View File

@ -10,14 +10,7 @@ import com.badlogic.gdx.utils.Align
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.unit.Promotion
import com.unciv.models.stats.Stats
import com.unciv.models.translations.tr
import com.unciv.ui.components.extensions.center
import com.unciv.ui.components.extensions.centerX
import com.unciv.ui.components.extensions.colorFromRGB
import com.unciv.ui.components.extensions.darken
import com.unciv.ui.components.extensions.surroundWithCircle
import com.unciv.ui.components.extensions.toGroup
import com.unciv.ui.components.extensions.toLabel
import com.unciv.ui.components.extensions.*
/**
* ### Manages "portraits" for a subset of RulesetObjects
@ -145,23 +138,7 @@ open class Portrait(val type: Type, val imageName: String, val size: Float, val
}
class PortraitResource(name: String, size: Float, amount: Int = 0) : Portrait(Type.Resource, name, size) {
init {
if (amount > 0) {
val label = amount.tr().toLabel(
fontSize = 8,
fontColor = Color.WHITE,
alignment = Align.center)
val amountGroup = label.surroundWithCircle(size/2, true, ImageGetter.CHARCOAL)
label.y -= 0.5f
amountGroup.x = width - amountGroup.width * 3 / 4
amountGroup.y = -amountGroup.height / 4
addActor(amountGroup)
}
}
class PortraitResource(name: String, size: Float, borderSize: Float) : Portrait(Type.Resource, name, size, borderSize) {
override fun getDefaultInnerBackgroundTint(): Color =
ruleset.tileResources[imageName]?.resourceType?.getColor() ?: Color.WHITE