sprite: emissive layer

This commit is contained in:
minjaesong
2024-01-27 01:27:45 +09:00
parent 3042b0659e
commit b02f4d7703
18 changed files with 175 additions and 29 deletions

View File

@@ -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<ParticleBase>?
) {
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()

View File

@@ -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)
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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)

View File

@@ -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)
}