From b02f4d7703b1255b7a2d4cfe6a0b24e53dfacc54 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 27 Jan 2024 01:27:45 +0900 Subject: [PATCH] sprite: emissive layer --- .../{jukebox_illum.tga => jukebox_emsv.tga} | 0 ...> metalworking_furnace_and_anvil_emsv.tga} | 0 ..._basic_glow.tga => smelter_basic_emsv.tga} | 0 .../sprites/fixtures/smelter_tall_emsv.tga | 3 + .../sprites/fixtures/smelter_tall_illum.tga | 3 - .../spriteanimation/HasAssembledSprite.kt | 3 + .../terrarum/gameactors/ActorWithBody.kt | 17 ++++ .../terrarum/gameparticles/ParticleBase.kt | 10 +++ .../terrarum/modulebasegame/IngameRenderer.kt | 84 +++++++++++++++++-- .../gameactors/ActorHumanoid.kt | 9 ++ .../gameactors/FixtureFurnaceAndAnvil.kt | 6 +- .../gameactors/FixtureSmelterBasic.kt | 6 +- .../modulebasegame/gameactors/IngamePlayer.kt | 2 + .../gameactors/PlayerBuilderWerebeastTest.kt | 1 + .../modulebasegame/serialise/WriteActor.kt | 14 ++++ .../torvald/terrarum/savegame/VirtualDisk.kt | 3 + .../terrarum/worlddrawer/BlocksDrawer.kt | 22 ++--- src/shaders/blendGlowTex1Flip.frag | 21 +++++ 18 files changed, 175 insertions(+), 29 deletions(-) rename assets/mods/basegame/sprites/fixtures/{jukebox_illum.tga => jukebox_emsv.tga} (100%) rename assets/mods/basegame/sprites/fixtures/{metalworking_furnace_and_anvil_illum.tga => metalworking_furnace_and_anvil_emsv.tga} (100%) rename assets/mods/basegame/sprites/fixtures/{smelter_basic_glow.tga => smelter_basic_emsv.tga} (100%) create mode 100644 assets/mods/basegame/sprites/fixtures/smelter_tall_emsv.tga delete mode 100644 assets/mods/basegame/sprites/fixtures/smelter_tall_illum.tga create mode 100644 src/shaders/blendGlowTex1Flip.frag diff --git a/assets/mods/basegame/sprites/fixtures/jukebox_illum.tga b/assets/mods/basegame/sprites/fixtures/jukebox_emsv.tga similarity index 100% rename from assets/mods/basegame/sprites/fixtures/jukebox_illum.tga rename to assets/mods/basegame/sprites/fixtures/jukebox_emsv.tga diff --git a/assets/mods/basegame/sprites/fixtures/metalworking_furnace_and_anvil_illum.tga b/assets/mods/basegame/sprites/fixtures/metalworking_furnace_and_anvil_emsv.tga similarity index 100% rename from assets/mods/basegame/sprites/fixtures/metalworking_furnace_and_anvil_illum.tga rename to assets/mods/basegame/sprites/fixtures/metalworking_furnace_and_anvil_emsv.tga diff --git a/assets/mods/basegame/sprites/fixtures/smelter_basic_glow.tga b/assets/mods/basegame/sprites/fixtures/smelter_basic_emsv.tga similarity index 100% rename from assets/mods/basegame/sprites/fixtures/smelter_basic_glow.tga rename to assets/mods/basegame/sprites/fixtures/smelter_basic_emsv.tga diff --git a/assets/mods/basegame/sprites/fixtures/smelter_tall_emsv.tga b/assets/mods/basegame/sprites/fixtures/smelter_tall_emsv.tga new file mode 100644 index 000000000..58ac9d0ff --- /dev/null +++ b/assets/mods/basegame/sprites/fixtures/smelter_tall_emsv.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f035603054d9e70d57f7c8a2eae3aec11b5e32d618bee188ca8f7c7ebde1ca68 +size 12306 diff --git a/assets/mods/basegame/sprites/fixtures/smelter_tall_illum.tga b/assets/mods/basegame/sprites/fixtures/smelter_tall_illum.tga deleted file mode 100644 index 76aa67b4e..000000000 --- a/assets/mods/basegame/sprites/fixtures/smelter_tall_illum.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c58f356cf7d0d28b0f875f34d673be5a30d088b95de1ce7a4a6438e22b14e3f -size 12306 diff --git a/src/net/torvald/spriteanimation/HasAssembledSprite.kt b/src/net/torvald/spriteanimation/HasAssembledSprite.kt index 304909efb..2dc000537 100644 --- a/src/net/torvald/spriteanimation/HasAssembledSprite.kt +++ b/src/net/torvald/spriteanimation/HasAssembledSprite.kt @@ -18,6 +18,9 @@ interface HasAssembledSprite { /** ADL for glow sprite. Optional. */ var animDescGlow: ADProperties? + /** ADL for glow sprite. Optional. */ + var animDescEmissive: ADProperties? + var spriteHeadTexture: TextureRegion? // FIXME sometimes the animmation is invisible (row and nFrames mismatch -- row is changed to 1 but it's drawing 3rd frame?) diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 73e5ab3bb..6e44dcae6 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -87,6 +87,7 @@ open class ActorWithBody : Actor { @Transient var sprite: SpriteAnimation? = null @Transient var spriteGlow: SpriteAnimation? = null + @Transient var spriteEmissive: SpriteAnimation? = null var drawMode = BlendMode.NORMAL @@ -415,6 +416,13 @@ open class ActorWithBody : Actor { return spriteGlow as SheetSpriteAnimation } + fun makeNewSpriteEmissive(textureRegionPack: TextureRegionPack): SheetSpriteAnimation { + spriteEmissive = SheetSpriteAnimation(this).also { + it.setSpriteImage(textureRegionPack) + } + return spriteEmissive as SheetSpriteAnimation + } + /** * ONLY FOR INITIAL SETUP * @@ -523,6 +531,7 @@ open class ActorWithBody : Actor { if (sprite != null) sprite!!.update(delta) if (spriteGlow != null) spriteGlow!!.update(delta) + if (spriteEmissive != null) spriteEmissive!!.update(delta) // make NoClip work for player if (true) {//this == INGAME.actorNowPlaying) { @@ -1790,6 +1799,13 @@ open class ActorWithBody : Actor { } } + open fun drawEmissive(frameDelta: Float, batch: SpriteBatch) { + if (isVisible && spriteEmissive != null) { + blendNormalStraightAlpha(batch) + drawSpriteInGoodPosition(frameDelta, spriteEmissive!!, batch) + } + } + open fun drawBody(frameDelta: Float, batch: SpriteBatch) { if (isVisible && sprite != null) { BlendMode.resolve(drawMode, batch) @@ -2194,6 +2210,7 @@ open class ActorWithBody : Actor { override fun dispose() { App.disposables.add(sprite) App.disposables.add(spriteGlow) + App.disposables.add(spriteEmissive) } } diff --git a/src/net/torvald/terrarum/gameparticles/ParticleBase.kt b/src/net/torvald/terrarum/gameparticles/ParticleBase.kt index b855cbc1e..a5117a9b0 100644 --- a/src/net/torvald/terrarum/gameparticles/ParticleBase.kt +++ b/src/net/torvald/terrarum/gameparticles/ParticleBase.kt @@ -33,6 +33,7 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, var despawnUponCollision open lateinit var body: TextureRegion // you might want to use SpriteAnimation open var glow: TextureRegion? = null + open var emissive: TextureRegion? = null val drawColour = Color(1f, 1f, 1f, 1f) @@ -92,6 +93,15 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, var despawnUponCollision } } + open fun drawEmissive(frameDelta: Float, batch: SpriteBatch) { + if (!flagDespawn && emissive != null) { + batch.color = drawColour + drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat()) { x, y -> + batch.draw(emissive, x, y, hitbox.width.toFloat(), hitbox.height.toFloat()) + } + } + } + open fun dispose() { } diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 3ce5cb53b..6c89fed34 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.* +import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer import com.badlogic.gdx.graphics.glutils.FrameBuffer @@ -54,9 +55,11 @@ object IngameRenderer : Disposable { private lateinit var lightmapFbo: Float16FrameBuffer private lateinit var fboRGB: Float16FrameBuffer + private lateinit var fboRGB_lightMixed0: Float16FrameBuffer private lateinit var fboRGB_lightMixed: Float16FrameBuffer private lateinit var fboA: Float16FrameBuffer private lateinit var fboA_lightMixed: Float16FrameBuffer + private lateinit var fboEmissive: Float16FrameBuffer private lateinit var fboMixedOut: Float16FrameBuffer private lateinit var rgbTex: TextureRegion private lateinit var aTex: TextureRegion @@ -85,6 +88,7 @@ object IngameRenderer : Disposable { val shaderKawaseUp: ShaderProgram val shaderBlendGlow: ShaderProgram + val shaderBlendGlowTex1Flip: ShaderProgram val shaderForActors: ShaderProgram val shaderDemultiply: ShaderProgram @@ -127,6 +131,7 @@ object IngameRenderer : Disposable { shaderForActors = App.loadShaderFromClasspath("shaders/default.vert", "shaders/actors.frag") shaderBlendGlow = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlow.frag") + shaderBlendGlowTex1Flip = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlowTex1Flip.frag") shaderDemultiply = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/demultiply.frag") @@ -459,6 +464,8 @@ object IngameRenderer : Disposable { particlesContainer: CircularArray? ) { fboRGB.inAction(null, null) { clearBuffer() } + fboEmissive.inAction(null, null) { clearBuffer() } + fboRGB_lightMixed0.inAction(null, null) { clearBuffer() } fboRGB_lightMixed.inAction(null, null) { clearBuffer() } fboRGB.inAction(camera, batch) { @@ -503,7 +510,38 @@ object IngameRenderer : Disposable { } } - fboRGB_lightMixed.inAction(camera, batch) { + fboEmissive.inAction(camera, batch) { + batch.inUse { + batch.shader = shaderForActors + batch.color = Color.WHITE + moveCameraToWorldCoord() + actorsRenderBehind?.forEach { it.drawEmissive(frameDelta, batch) } + particlesContainer?.forEach { it.drawEmissive(frameDelta, batch) } + } + + setCameraPosition(0f, 0f) + BlocksDrawer.drawTerrain(batch.projectionMatrix, false, true) + + batch.shader = shaderForActors + batch.inUse { + batch.shader = shaderForActors + batch.color = Color.WHITE + ///////////////// + // draw actors // + ///////////////// + moveCameraToWorldCoord() + actorsRenderMiddle?.forEach { it.drawEmissive(frameDelta, batch) } + actorsRenderMidTop?.forEach { it.drawEmissive(frameDelta, batch) } + player?.drawEmissive(frameDelta, batch) + actorsRenderFront?.forEach { it.drawEmissive(frameDelta, batch) } + // --> Change of blend mode <-- introduced by children of ActorWithBody // + } + + setCameraPosition(0f, 0f) + BlocksDrawer.drawFront(batch.projectionMatrix, true) // blue coloured filter of water, etc. + } + + fboRGB_lightMixed0.inAction(camera, batch) { setCameraPosition(0f, 0f) val (xrem, yrem) = worldCamToRenderPos() @@ -515,6 +553,7 @@ object IngameRenderer : Disposable { batch.inUse { + batch.color = Color.WHITE blendNormalStraightAlpha(batch) // draw world @@ -542,20 +581,40 @@ object IngameRenderer : Disposable { ) // } - - - // if right texture coord for lightTex and fboRGB are obtainable, you can try this: - /* - vec4 skyboxColour = ... - gl_FragCoord = alphablend skyboxColour with (fboRGB * lightTex) - */ } - // NOTE TO SELF: thã„´is works. + + // NOTE TO SELF: this works. } + fboRGB_lightMixed.inActionF(camera, batch) { + + setCameraPosition(0f, 0f) + val (xrem, yrem) = worldCamToRenderPos() + + gdxEnableBlend() + + + fboEmissive.colorBufferTexture.bind(1) + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it + + + // draw emissive + batch.inUse { + batch.color = Color.WHITE + blendNormalStraightAlpha(batch) + batch.shader = shaderBlendGlowTex1Flip + shaderBlendGlowTex1Flip.setUniformi("tex1", 1) + shaderBlendGlowTex1Flip.setUniformi("tex1flip", 1) + + batch.color = Color.WHITE + batch.draw(fboRGB_lightMixed0.colorBufferTexture, 0f, 0f) + batch.flush() + } + } + blendNormalStraightAlpha(batch) } @@ -819,9 +878,11 @@ object IngameRenderer : Disposable { } else { fboRGB.dispose() + fboRGB_lightMixed0.dispose() fboRGB_lightMixed.dispose() fboA.dispose() fboA_lightMixed.dispose() + fboEmissive.dispose() lightmapFbo.dispose() fboBlurHalf.dispose() @@ -829,9 +890,11 @@ object IngameRenderer : Disposable { } fboRGB = Float16FrameBuffer(width, height, false) + fboRGB_lightMixed0 = Float16FrameBuffer(width, height, false) fboRGB_lightMixed = Float16FrameBuffer(width, height, false) fboA = Float16FrameBuffer(width, height, false) fboA_lightMixed = Float16FrameBuffer(width, height, false) + fboEmissive = Float16FrameBuffer(width, height, false) fboMixedOut = Float16FrameBuffer(width, height, false) lightmapFbo = Float16FrameBuffer( LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt(), @@ -889,8 +952,10 @@ object IngameRenderer : Disposable { if (::fboRGB.isInitialized) fboRGB.tryDispose() if (::fboA.isInitialized) fboA.tryDispose() + if (::fboRGB_lightMixed0.isInitialized) fboRGB_lightMixed0.tryDispose() if (::fboRGB_lightMixed.isInitialized) fboRGB_lightMixed.tryDispose() if (::fboA_lightMixed.isInitialized) fboA_lightMixed.tryDispose() + if (::fboEmissive.isInitialized) fboEmissive.tryDispose() if (::fboMixedOut.isInitialized) fboMixedOut.tryDispose() if (::lightmapFbo.isInitialized) lightmapFbo.tryDispose() @@ -914,6 +979,7 @@ object IngameRenderer : Disposable { shaderKawaseUp.dispose() shaderBlendGlow.dispose() + shaderBlendGlowTex1Flip.dispose() shaderForActors.dispose() shaderDemultiply.dispose() diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt index 8ad1510dc..51cfc869c 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt @@ -747,16 +747,19 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L open fun updateSprite(delta: Float) { sprite?.update(delta) spriteGlow?.update(delta) + spriteEmissive?.update(delta) if (walledBottom && controllerV?.x != 0.0) { //switch row if (this is HasAssembledSprite) { (sprite as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_RUN" (spriteGlow as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_RUN" + (spriteEmissive as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_RUN" } else { (sprite as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_WALK) (spriteGlow as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_WALK) + (spriteEmissive as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_WALK) } // set anim frame delay @@ -772,6 +775,7 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L (sprite as? AssembledSpriteAnimation)?.overrideDelay = finalDelay (spriteGlow as? AssembledSpriteAnimation)?.overrideDelay = finalDelay + (spriteEmissive as? AssembledSpriteAnimation)?.overrideDelay = finalDelay } catch (e: NullPointerException) { println(animDesc!!.animations.keys.joinToString()) @@ -784,10 +788,12 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L if (walkHeading == LEFT) { sprite?.flip(true, false) spriteGlow?.flip(true, false) + spriteEmissive?.flip(true, false) } else { sprite?.flip(false, false) spriteGlow?.flip(false, false) + spriteEmissive?.flip(false, false) } } else { @@ -795,12 +801,15 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L if (this is HasAssembledSprite) { (sprite as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_IDLE" (spriteGlow as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_IDLE" + (spriteEmissive as? AssembledSpriteAnimation)?.currentAnimation = "ANIM_IDLE" (sprite as? AssembledSpriteAnimation)?.overrideDelay = 0f (spriteGlow as? AssembledSpriteAnimation)?.overrideDelay = 0f + (spriteEmissive as? AssembledSpriteAnimation)?.overrideDelay = 0f } else { (sprite as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_IDLE) (spriteGlow as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_IDLE) + (spriteEmissive as? SheetSpriteAnimation)?.switchRow(SPRITE_ROW_IDLE) } } } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt index 9f58140d0..038c3c911 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureFurnaceAndAnvil.kt @@ -32,7 +32,7 @@ class FixtureFurnaceAndAnvil : FixtureBase, CraftingStation { val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/metalworking_furnace_and_anvil.tga") -// val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/metalworking_furnace_and_anvil_illum.tga") // put this sprite to the hypothetical "SpriteIllum" + val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/metalworking_furnace_and_anvil_emsv.tga") density = BlockCodex[Block.STONE].density.toDouble() setHitboxDimension(itemImage.texture.width, itemImage.texture.height, 0, 0) @@ -40,9 +40,9 @@ class FixtureFurnaceAndAnvil : FixtureBase, CraftingStation { makeNewSprite(TextureRegionPack(itemImage.texture, itemImage.texture.width, itemImage.texture.height)).let { it.setRowsAndFrames(1,1) } - /*makeNewSpriteGlow(TextureRegionPack(itemImage2.texture, itemImage.texture.width, itemImage.texture.height)).let { + makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, itemImage.texture.width, itemImage.texture.height)).let { it.setRowsAndFrames(1,1) - }*/ + } actorValue[AVKey.BASEMASS] = 100.0 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt index 9de0d8566..860d2836a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSmelterBasic.kt @@ -35,7 +35,7 @@ class FixtureSmelterBasic : FixtureBase, CraftingStation { val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/smelter_tall.tga") -// val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/smelter_tall_illum.tga") // put this sprite to the hypothetical "SpriteIllum" + val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/smelter_tall_emsv.tga") density = BlockCodex[Block.STONE].density.toDouble() setHitboxDimension(itemImage.texture.width, itemImage.texture.height, 0, 0) @@ -43,9 +43,9 @@ class FixtureSmelterBasic : FixtureBase, CraftingStation { makeNewSprite(TextureRegionPack(itemImage.texture, itemImage.texture.width, itemImage.texture.height)).let { it.setRowsAndFrames(1,1) } - /*makeNewSpriteGlow(TextureRegionPack(itemImage2.texture, itemImage.texture.width, itemImage.texture.height)).let { + makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, itemImage.texture.width, itemImage.texture.height)).let { it.setRowsAndFrames(1,1) - }*/ + } actorValue[AVKey.BASEMASS] = 100.0 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt index d6b7bc985..88845bc71 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt @@ -39,6 +39,8 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite, NoSerialise { @Transient override var animDesc: ADProperties? = null /** ADL for glow sprite. Optional. */ @Transient override var animDescGlow: ADProperties? = null + /** ADL for glow sprite. Optional. */ + @Transient override var animDescEmissive: ADProperties? = null private constructor() diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt index 477cf9a1f..b95c5252a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt @@ -26,6 +26,7 @@ object PlayerBuilderWerebeastTest { p.animDesc?.let { p.sprite = AssembledSpriteAnimation(it, p, false) } p.animDescGlow?.let { p.spriteGlow = AssembledSpriteAnimation(it, p, true) } + p.animDescEmissive?.let { p.spriteEmissive = AssembledSpriteAnimation(it, p, true) } p.setHitboxDimension(22, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 30, 0) p.setPosition(3.0 * TILE_SIZE, 3.0 * TILE_SIZE) diff --git a/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt b/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt index 3c7a41d53..9383bf1c9 100644 --- a/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt +++ b/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt @@ -10,12 +10,14 @@ import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.savegame.* +import net.torvald.terrarum.savegame.VDFileID.BODYPARTEMISSIVE_TO_ENTRY_MAP import net.torvald.terrarum.savegame.VDFileID.BODYPARTGLOW_TO_ENTRY_MAP import net.torvald.terrarum.savegame.VDFileID.BODYPART_TO_ENTRY_MAP import net.torvald.terrarum.savegame.VDFileID.LOADORDER import net.torvald.terrarum.savegame.VDFileID.ROOT import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF +import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF_EMISSIVE import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF_GLOW import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.spriteassembler.ADProperties @@ -169,6 +171,7 @@ object ReadActor { if (actor is ActorWithBody && actor is IngamePlayer) { val animFile = disk.getFile(SPRITEDEF) val animFileGlow = disk.getFile(SPRITEDEF_GLOW) + val animFileEmissive = disk.getFile(SPRITEDEF_EMISSIVE) val bodypartsFile = disk.getFile(BODYPART_TO_ENTRY_MAP) actor.animDesc = ADProperties(ByteArray64Reader(animFile!!.bytes, Common.CHARSET)) @@ -189,6 +192,16 @@ object ReadActor { true ) } + if (animFileEmissive != null) { + actor.animDescEmissive = ADProperties(ByteArray64Reader(animFileEmissive.bytes, Common.CHARSET)) + actor.spriteEmissive = AssembledSpriteAnimation( + actor.animDescEmissive!!, + actor, + if (bodypartsFile != null) disk else null, + if (bodypartsFile != null) BODYPARTEMISSIVE_TO_ENTRY_MAP else null, + true + ) + } ItemCodex.loadFromSave(disk.getBackingFile(), actor.dynamicToStaticTable, actor.dynamicItemInventory) @@ -202,6 +215,7 @@ object ReadActor { else if (actor is ActorWithBody && actor is HasAssembledSprite) { if (actor.animDesc != null) actor.sprite = AssembledSpriteAnimation(actor.animDesc!!, actor, false) if (actor.animDescGlow != null) actor.spriteGlow = AssembledSpriteAnimation(actor.animDescGlow!!, actor, true) + if (actor.animDescEmissive != null) actor.spriteEmissive = AssembledSpriteAnimation(actor.animDescEmissive!!, actor, true) //actor.reassembleSprite(actor.sprite, actor.spriteGlow, null) } diff --git a/src/net/torvald/terrarum/savegame/VirtualDisk.kt b/src/net/torvald/terrarum/savegame/VirtualDisk.kt index 4f336fe02..6b961096c 100644 --- a/src/net/torvald/terrarum/savegame/VirtualDisk.kt +++ b/src/net/torvald/terrarum/savegame/VirtualDisk.kt @@ -312,8 +312,10 @@ object VDFileID { const val SPRITEDEF_GLOW = -3L const val LOADORDER = -4L const val PLAYER_SCREENSHOT = -5L + const val SPRITEDEF_EMISSIVE = -6L const val BODYPART_TO_ENTRY_MAP = -1025L const val BODYPARTGLOW_TO_ENTRY_MAP = -1026L + const val BODYPARTEMISSIVE_TO_ENTRY_MAP = -1027L } fun diskIDtoReadableFilename(id: EntryID, saveKind: Int?): String = when (id) { @@ -345,6 +347,7 @@ fun diskIDtoReadableFilename(id: EntryID, saveKind: Int?): String = when (id) { // -1024L -> "apocryphas.json.gz" VDFileID.BODYPART_TO_ENTRY_MAP -> "bodypart-to-entry.map" VDFileID.BODYPARTGLOW_TO_ENTRY_MAP -> "bodypartglow-to-entry.map" + VDFileID.BODYPARTEMISSIVE_TO_ENTRY_MAP -> "bodypartemissive-to-entry.map" in 1..65535 -> if (saveKind == PLAYER_DATA) "bodypart #$id.tga.gz" diff --git a/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt b/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt index af486d1d3..230d9b146 100644 --- a/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt +++ b/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt @@ -217,28 +217,28 @@ internal object BlocksDrawer { } } - internal fun drawWall(projectionMatrix: Matrix4, drawGlow: Boolean) { + internal fun drawWall(projectionMatrix: Matrix4, drawGlow: Boolean, drawBlack: Boolean = false) { gdxBlendNormalStraightAlpha() - renderUsingBuffer(WALL, projectionMatrix, drawGlow) + renderUsingBuffer(WALL, projectionMatrix, drawGlow, drawBlack) gdxBlendMul() - renderUsingBuffer(OCCLUSION, projectionMatrix, false) + renderUsingBuffer(OCCLUSION, projectionMatrix, false, drawBlack) } - internal fun drawTerrain(projectionMatrix: Matrix4, drawGlow: Boolean) { + internal fun drawTerrain(projectionMatrix: Matrix4, drawGlow: Boolean, drawBlack: Boolean = false) { gdxBlendNormalStraightAlpha() - renderUsingBuffer(TERRAIN, projectionMatrix, drawGlow) - renderUsingBuffer(ORES, projectionMatrix, drawGlow) - renderUsingBuffer(FLUID, projectionMatrix, drawGlow) + renderUsingBuffer(TERRAIN, projectionMatrix, drawGlow, drawBlack) + renderUsingBuffer(ORES, projectionMatrix, drawGlow, drawBlack) + renderUsingBuffer(FLUID, projectionMatrix, drawGlow, drawBlack) } - internal fun drawFront(projectionMatrix: Matrix4) { + internal fun drawFront(projectionMatrix: Matrix4, drawBlack: Boolean = false) { gdxBlendMul() // let's just not MUL on terrain, make it FLUID only... - renderUsingBuffer(FLUID, projectionMatrix, false) + renderUsingBuffer(FLUID, projectionMatrix, false, drawBlack) @@ -708,7 +708,7 @@ internal object BlocksDrawer { private var _tilesBufferAsTex: Texture = Texture(1, 1, Pixmap.Format.RGBA8888) private val occlusionIntensity = 0.22222222f // too low value and dark-coloured walls won't darken enough - private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean) { + private fun renderUsingBuffer(mode: Int, projectionMatrix: Matrix4, drawGlow: Boolean, drawBlack: Boolean) { //Gdx.gl.glClearColor(.094f, .094f, .094f, 0f) //Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) @@ -732,7 +732,7 @@ internal object BlocksDrawer { OCCLUSION -> occlusionBuffer else -> throw IllegalArgumentException() } - val vertexColour = when (mode) { + val vertexColour = if (drawBlack) Color.BLACK else when (mode) { TERRAIN, /*WIRE,*/ ORES, FLUID, OCCLUSION -> Color.WHITE WALL -> WALL_OVERLAY_COLOUR else -> throw IllegalArgumentException() diff --git a/src/shaders/blendGlowTex1Flip.frag b/src/shaders/blendGlowTex1Flip.frag new file mode 100644 index 000000000..bec83192c --- /dev/null +++ b/src/shaders/blendGlowTex1Flip.frag @@ -0,0 +1,21 @@ + +#ifdef GL_ES + precision mediump float; +#endif + + +in vec4 v_color; +in vec2 v_texCoords; +uniform sampler2D u_texture; // world texture, has alpha value that is meaningful + +uniform sampler2D tex1; // glow texture, SHOULD contain alpha of all 1.0 +out vec4 fragColor; + +const vec2 boolean = vec2(0.0, 1.0); + +void main(void) { + vec4 colorTex0 = texture(u_texture, v_texCoords); // lightmap (RGB) pre-mixed + vec4 colorTex1 = texture(tex1, vec2(v_texCoords.x, 1.0 - v_texCoords.y)); // lightmap (A) pre-mixed +// fragColor = (max(colorTex0, colorTex1) * boolean.yyyx) + (colorTex0 * boolean.xxxy); + fragColor = fma(max(colorTex0, colorTex1), boolean.yyyx, colorTex0 * boolean.xxxy); +} \ No newline at end of file