diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index 8b65e7a7a..bf5352359 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -590,6 +590,8 @@ public class App implements ApplicationListener { gl40capable = (Gdx.graphics.getGLVersion().getMajorVersion() >= 4); printdbg(this, "GL40 capable? "+gl40capable); + ShaderMgr.INSTANCE.compile(Gdx.files.classpath("shaders/shaders.csv")); + CommonResourcePool.INSTANCE.addToLoadingList("title_health1", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_take_a_break.tga"))); CommonResourcePool.INSTANCE.addToLoadingList("title_health2", () -> new Texture(Gdx.files.internal("./assets/graphics/gui/health_distance.tga"))); CommonResourcePool.INSTANCE.addToLoadingList("sound:haptic_bup", () -> new MusicContainer("haptic_bup", Gdx.files.internal("./assets/audio/effects/haptic_bup.ogg").file(), false, true, (AudioBank m) -> { return null; })); @@ -1002,6 +1004,7 @@ public class App implements ApplicationListener { shaderGhastlyWhite.dispose(); hq2x.dispose(); + ShaderMgr.INSTANCE.dispose(); CommonResourcePool.INSTANCE.dispose(); fullscreenQuad.dispose(); logoBatch.dispose(); diff --git a/src/net/torvald/terrarum/ShaderMgr.kt b/src/net/torvald/terrarum/ShaderMgr.kt new file mode 100644 index 000000000..192c51d80 --- /dev/null +++ b/src/net/torvald/terrarum/ShaderMgr.kt @@ -0,0 +1,38 @@ +package net.torvald.terrarum + +import com.badlogic.gdx.files.FileHandle +import com.badlogic.gdx.graphics.glutils.ShaderProgram +import com.badlogic.gdx.utils.Disposable +import net.torvald.terrarum.utils.CSVFetcher + +/** + * `default`, `default-batch`, and `default-shaperenderer` is pre-allocated. `default` is identical to `default-batch`. + * + * Created by minjaesong on 2024-12-16. + */ +object ShaderMgr : Disposable { + + private val mapping = HashMap() + + fun compile(path: FileHandle) { + CSVFetcher.readFromString(path.readString("utf-8")).forEach { + val vert = it["vert"] + val frag = it["frag"] + val name = it["name"] + + mapping[name] = App.loadShaderFromClasspath("shaders/$vert", "shaders/$frag") + } + + + mapping["default"] = DefaultGL32Shaders.createSpriteBatchShader() + mapping["default-batch"] = DefaultGL32Shaders.createSpriteBatchShader() + mapping["default-shaperenderer"] = DefaultGL32Shaders.createShapeRendererShader() + } + + operator fun get(name: String): ShaderProgram = mapping[name]!! + + override fun dispose() { + mapping.values.forEach { it.dispose() } + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/TerrarumPostProcessor.kt b/src/net/torvald/terrarum/TerrarumPostProcessor.kt index 9bdf5743e..e3120a98b 100644 --- a/src/net/torvald/terrarum/TerrarumPostProcessor.kt +++ b/src/net/torvald/terrarum/TerrarumPostProcessor.kt @@ -52,8 +52,8 @@ object TerrarumPostProcessor : Disposable { private val batteryTex = TextureRegionPack(Gdx.files.internal("assets/graphics/gui/fullscreen_bat_ind.tga"), 23, 14) - private val shaderPostDither = App.loadShaderFromClasspath("shaders/default.vert", "shaders/postproc_dither.frag") - private val shaderPostNoDither = App.loadShaderFromClasspath("shaders/default.vert", "shaders/postproc_nodither.frag") + private val shaderPostDither = ShaderMgr["postDither"] + private val shaderPostNoDither = ShaderMgr["postNoDither"] private val recommendRatio = 1.5f @@ -83,8 +83,6 @@ object TerrarumPostProcessor : Disposable { batch.dispose() shapeRenderer.dispose() functionRowHelper.dispose() - shaderPostDither.dispose() - shaderPostNoDither.dispose() if (::lutTex.isInitialized) lutTex.tryDispose() if (::outFBO.isInitialized) outFBO.dispose() // testfill.dispose() diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 8430174a6..07a79039b 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -154,24 +154,24 @@ object IngameRenderer : Disposable { // these codes will run regardless of the invocation of the "initialise()" function // the "initialise()" function will also be called init { - shaderBlur = App.loadShaderFromClasspath("shaders/blur.vert", "shaders/blur.frag") - shaderRGBOnly = App.loadShaderFromClasspath("shaders/default.vert", "shaders/rgbonly.frag") - shaderAtoGrey = App.loadShaderFromClasspath("shaders/default.vert", "shaders/aonly.frag") + shaderBlur = ShaderMgr["irBlur"] + shaderRGBOnly = ShaderMgr["irRGBOnly"] + shaderAtoGrey = ShaderMgr["irAtoGrey"] - shaderForActors = App.loadShaderFromClasspath("shaders/default.vert", "shaders/actors.frag") - shaderShadowShallow = App.loadShaderFromClasspath("shaders/default.vert", "shaders/shadowshallow.frag") - shaderShadowDeep = App.loadShaderFromClasspath("shaders/default.vert", "shaders/shadowdeep.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") + shaderForActors = ShaderMgr["irForActors"] + shaderShadowShallow = ShaderMgr["irShadowShallow"] + shaderShadowDeep = ShaderMgr["irShadowDeep"] + shaderBlendGlow = ShaderMgr["irBlendGlow"] + shaderBlendGlowTex1Flip = ShaderMgr["irBlendGlowTex1Flip"] + shaderDemultiply = ShaderMgr["irDemultiply"] - shaderBayerAlpha = App.loadShaderFromClasspath("shaders/default.vert", "shaders/alphadither.frag") + shaderBayerAlpha = ShaderMgr["irBayerAlpha"] - shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag") - shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag") + shaderKawaseDown = ShaderMgr["irKawaseDown"] + shaderKawaseUp = ShaderMgr["irKawaseUp"] - shaderVibrancy = App.loadShaderFromClasspath("shaders/default.vert", "shaders/vibrancy.frag") + shaderVibrancy = ShaderMgr["irVibrancy"] if (!shaderBlendGlow.isCompiled) { Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log) @@ -1403,26 +1403,6 @@ object IngameRenderer : Disposable { WeatherMixer.dispose() if (::batch.isInitialized) batch.tryDispose() - - - shaderBlur.dispose() - shaderRGBOnly.dispose() - shaderAtoGrey.dispose() - - shaderKawaseDown.dispose() - shaderKawaseUp.dispose() - - shaderBlendGlow.dispose() - shaderBlendGlowTex1Flip.dispose() - shaderForActors.dispose() - shaderShadowShallow.dispose() - shaderShadowDeep.dispose() - shaderDemultiply.dispose() - - shaderBayerAlpha.dispose() - - shaderVibrancy.dispose() - if (::fboRGBexport.isInitialized) fboRGBexport.tryDispose() } diff --git a/src/net/torvald/terrarum/ui/BlurMgr.kt b/src/net/torvald/terrarum/ui/BlurMgr.kt index d1adcc905..ff8c402be 100644 --- a/src/net/torvald/terrarum/ui/BlurMgr.kt +++ b/src/net/torvald/terrarum/ui/BlurMgr.kt @@ -5,10 +5,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.jme3.math.FastMath -import net.torvald.terrarum.App -import net.torvald.terrarum.ceilToInt -import net.torvald.terrarum.gdxClearAndEnableBlend -import net.torvald.terrarum.inAction +import net.torvald.terrarum.* /** * Created by minjaesong on 2024-11-23. @@ -84,9 +81,9 @@ object BlurMgr { private lateinit var blurtex2: Texture private lateinit var blurtex3: Texture - private val shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag") - private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag") - private val shaderGauss3 = App.loadShaderFromClasspath("shaders/default.vert", "shaders/gaussian3x3.frag") + private val shaderKawaseDown = ShaderMgr["irKawaseDown"] + private val shaderKawaseUp = ShaderMgr["irKawaseUp"] + private val shaderGauss3 = ShaderMgr["gaus3"] fun makeBlur(`in`: FrameBuffer, out: FrameBuffer, strength: Float) { assert(`in`.width == out.width && `in`.height == out.height) { @@ -198,9 +195,6 @@ object BlurMgr { fun dispose() { fboDict.values.forEach { it.dispose() } - shaderKawaseUp.dispose() - shaderKawaseDown.dispose() - shaderGauss3.dispose() } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/ui/Toolkit.kt b/src/net/torvald/terrarum/ui/Toolkit.kt index 9927f479b..810aeb82e 100644 --- a/src/net/torvald/terrarum/ui/Toolkit.kt +++ b/src/net/torvald/terrarum/ui/Toolkit.kt @@ -184,8 +184,8 @@ object Toolkit : Disposable { Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it - batch.begin() batch.shader = null + batch.begin() (batch as FlippingSpriteBatch).drawFlipped(fboBlur.colorBufferTexture, x.toFloat(), y.toFloat()) } diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 6941c4ed3..c6eaf5c62 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -102,9 +102,8 @@ internal object WeatherMixer : RNGConsumer { it.texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat) } - private val shaderAstrum = - App.loadShaderFromClasspath("shaders/blendSkyboxStars.vert", "shaders/blendSkyboxStars.frag") - private val shaderClouds = App.loadShaderFromClasspath("shaders/default.vert", "shaders/clouds.frag") + private val shaderAstrum = ShaderMgr["astrum"] + private val shaderClouds = ShaderMgr["clouds"] private var astrumOffX = 0f private var astrumOffY = 0f @@ -891,8 +890,6 @@ internal object WeatherMixer : RNGConsumer { fun dispose() { starmapTex.texture.dispose() - shaderAstrum.dispose() - shaderClouds.dispose() } private fun Cvec.linearise(): Cvec { diff --git a/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt b/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt index f26ba8989..b1985c403 100644 --- a/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt +++ b/src/net/torvald/terrarum/worlddrawer/BlocksDrawer.kt @@ -110,8 +110,8 @@ internal object BlocksDrawer { private var nullBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888) private lateinit var tilesQuad: Mesh - private val shaderTiling = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling.frag") - private val shaderDeblock = App.loadShaderFromClasspath("shaders/default.vert", "shaders/deblocking.frag") + private val shaderTiling = ShaderMgr["tiling"] + private val shaderDeblock = ShaderMgr["deblock"] private lateinit var deblockingFBO: Float16FrameBuffer private lateinit var blurmapFBO: Float16FrameBuffer @@ -1493,8 +1493,6 @@ internal object BlocksDrawer { _tilesBufferAsTex2.dispose() // _blurTilesBuffer.dispose() tilesQuad.tryDispose() - shaderTiling.dispose() - shaderDeblock.dispose() nullTex.dispose() nullBuffer.dispose() diff --git a/src/shaders/shaders.csv b/src/shaders/shaders.csv new file mode 100644 index 000000000..9b64da401 --- /dev/null +++ b/src/shaders/shaders.csv @@ -0,0 +1,27 @@ +name;frag;vert;comment + +astrum;blendSkyboxStars.frag;blendSkyboxStars.vert;WeatherMixer +clouds;clouds.frag;default.vert;WeatherMixer + +tiling;tiling.frag;default.vert;BlocksDrawer +deblock;deblocking.frag;default.vert;BlocksDrawer + +postDither;postproc_dither.frag;default.vert;TerrarumPostProcessor +postNoDither;postproc_nodither.frag;default.vert;TerrarumPostProcessor + +irBlur;blur.frag;blur.vert;IngameRenderer +irRGBOnly;rgbonly.frag;default.vert;IngameRenderer +irAtoGrey;aonly.frag;default.vert;IngameRenderer +irForActors;actors.frag;default.vert;IngameRenderer +irShadowShallow;shadowshallow.frag;default.vert;IngameRenderer +irShadowDeep;shadowdeep.frag;default.vert;IngameRenderer +irBlendGlow;blendGlow.frag;default.vert;IngameRenderer +irBlendGlowTex1Flip;blendGlowTex1Flip.frag;default.vert;IngameRenderer +irDemultiply;demultiply.frag;default.vert;IngameRenderer +irBayerAlpha;alphadither.frag;default.vert;IngameRenderer +irKawaseDown;kawasedown.frag;default.vert;IngameRenderer +irKawaseUp;kawaseup.frag;default.vert;IngameRenderer +irVibrancy;vibrancy.frag;default.vert;IngameRenderer + +gaus3;gaussian3x3.frag;default.vert;BlurMgr +