From f5846d9baed54c37d58c7e7e752db16cecc375fb Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 23 Nov 2024 21:17:16 +0900 Subject: [PATCH] screen blur helper class --- src/net/torvald/terrarum/App.java | 5 + .../terrarum/TerrarumAppConfiguration.kt | 2 +- src/net/torvald/terrarum/UIFakeGradOverlay.kt | 2 +- .../modulebasegame/ui/UICheatDetected.kt | 4 +- src/net/torvald/terrarum/ui/BlurMgr.kt | 150 ++++++++++++++++ src/net/torvald/terrarum/ui/Toolkit.kt | 160 +----------------- 6 files changed, 161 insertions(+), 162 deletions(-) create mode 100644 src/net/torvald/terrarum/ui/BlurMgr.kt diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index aa63d26b1..9ead2b552 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -38,6 +38,7 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer; import net.torvald.terrarum.modulebasegame.TerrarumIngame; import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory; import net.torvald.terrarum.serialise.WriteConfig; +import net.torvald.terrarum.ui.BlurMgr; import net.torvald.terrarum.ui.Toolkit; import net.torvald.terrarum.utils.JsonFetcher; import net.torvald.terrarum.worlddrawer.CreateTileAtlas; @@ -52,6 +53,7 @@ import org.apache.commons.csv.CSVParser; import org.lwjgl.PointerBuffer; import org.lwjgl.glfw.GLFW; +import javax.tools.Tool; import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -1026,6 +1028,9 @@ public class App implements ApplicationListener { deleteTempfiles(); + Toolkit.INSTANCE.dispose(); + BlurMgr.INSTANCE.dispose(); + disposables.forEach((it) -> { try { it.dispose(); diff --git a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt index c99b6e6d8..02f1d4446 100644 --- a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt +++ b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt @@ -69,7 +69,7 @@ basegame * e.g. 0x02010034 will be translated as 2.1.52 * */ - const val VERSION_RAW: Long = 0x0000_000005_000000 + const val VERSION_RAW: Long = 0x0000_000005_000001 // Commit counts up to the Release 0.3.0: 2259 // Commit counts up to the Release 0.3.1: 2278 // Commit counts up to the Release 0.3.2: 2732 diff --git a/src/net/torvald/terrarum/UIFakeGradOverlay.kt b/src/net/torvald/terrarum/UIFakeGradOverlay.kt index 2ad26e662..f5f376cd4 100644 --- a/src/net/torvald/terrarum/UIFakeGradOverlay.kt +++ b/src/net/torvald/terrarum/UIFakeGradOverlay.kt @@ -95,7 +95,7 @@ class UIFakeBlurOverlay(val blurRadius: Float, val nodarken: Boolean) : UICanvas batchDrawCol.a = openness batch.color = batchDrawCol if (App.getConfigBoolean("fx_backgroundblur")) { - Toolkit.blurEntireScreen(batch, camera as OrthographicCamera, blurRadius * openness, 0, 0, width, height) + Toolkit.blurEntireScreen(batch, blurRadius * openness, 0, 0, width, height) } if (!nodarken) { diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UICheatDetected.kt b/src/net/torvald/terrarum/modulebasegame/ui/UICheatDetected.kt index bd3809912..d2ea36b48 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UICheatDetected.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UICheatDetected.kt @@ -35,7 +35,7 @@ class UICheatDetected : UICanvas() { Terrarum.ingame?.consoleHandler?.setAsClose() Terrarum.ingame?.consoleHandler?.isVisible = false - Toolkit.blurEntireScreen(batch, camera as OrthographicCamera, 2f, 0, 0, width, height) + Toolkit.blurEntireScreen(batch, 2f, 0, 0, width, height) batch.color = backgroundCol Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat()) @@ -80,7 +80,7 @@ class UIPauseTheGame : UICanvas() { Terrarum.ingame?.consoleHandler?.setAsClose() Terrarum.ingame?.consoleHandler?.isVisible = false - Toolkit.blurEntireScreen(batch, camera as OrthographicCamera, 2f, 0, 0, width, height) + Toolkit.blurEntireScreen(batch, 2f, 0, 0, width, height) batch.color = backgroundCol Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat()) diff --git a/src/net/torvald/terrarum/ui/BlurMgr.kt b/src/net/torvald/terrarum/ui/BlurMgr.kt new file mode 100644 index 000000000..b3dd4f71c --- /dev/null +++ b/src/net/torvald/terrarum/ui/BlurMgr.kt @@ -0,0 +1,150 @@ +package net.torvald.terrarum.ui + +import com.badlogic.gdx.graphics.* +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.inAction + +/** + * Created by minjaesong on 2024-11-23. + */ +object BlurMgr { + + private class FrameBufferSet(val width: Int, val height: Int) { + private val internalWidth = (width.toFloat() / 4f).ceilToInt() * 4 + private val internalHeight = (height.toFloat() / 4f).ceilToInt() * 4 + + val full = Float16FrameBuffer(width, height, false) + val half = Float16FrameBuffer(internalWidth / 2, internalHeight / 2, false) + val quarter = Float16FrameBuffer(internalWidth / 4, internalHeight / 4, false) + val camera = OrthographicCamera(width.toFloat(), height.toFloat()) + + val quadFull = Mesh( + true, 4, 4, + VertexAttribute.Position(), + VertexAttribute.ColorUnpacked(), + VertexAttribute.TexCoords(0) + ) + val quadHalf = Mesh( + true, 4, 4, + VertexAttribute.Position(), + VertexAttribute.ColorUnpacked(), + VertexAttribute.TexCoords(0) + ) + val quadQuarter = Mesh( + true, 4, 4, + VertexAttribute.Position(), + VertexAttribute.ColorUnpacked(), + VertexAttribute.TexCoords(0) + ) + + init { + camera.setToOrtho(true) + + quadFull.setVertices(floatArrayOf( + 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, + width.toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, + width.toFloat(), height.toFloat(),0f, 1f,1f,1f,1f, 1f,0f, + 0f, height.toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) + quadFull.setIndices(shortArrayOf(0, 1, 2, 3)) + + quadHalf.setVertices(floatArrayOf( + 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, + width.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, + width.div(2).toFloat(), height.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, + 0f, height.div(2).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) + quadHalf.setIndices(shortArrayOf(0, 1, 2, 3)) + + quadQuarter.setVertices(floatArrayOf( + 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, + width.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, + width.div(4).toFloat(), height.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, + 0f, height.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) + quadQuarter.setIndices(shortArrayOf(0, 1, 2, 3)) + } + + fun dispose() { + full.dispose() + half.dispose() + quarter.dispose() + } + } + + private val fboDict = HashMap() + + private lateinit var blurtex0: Texture + private lateinit var blurtex1: Texture + 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") + + fun makeBlur(`in`: FrameBuffer, out: FrameBuffer, strength: Float) { + assert(`in`.width == out.width && `in`.height == out.height) { + "Input and Output dimension mismatch: In(${`in`.width}x${`in`.height}), Out(${out.width}x${out.height})" + } + + val fbos = fboDict.getOrPut(`in`.width.toLong().shl(32) or `in`.height.toLong()) { + FrameBufferSet(`in`.width, `in`.height) + } + + val batch: SpriteBatch? = null // placeholder + + val radius3 = FastMath.pow(strength / 2, 0.5f)//(blurRadius - 3f) / 8f + fbos.half.inAction(fbos.camera, batch) { + blurtex0 = `in`.colorBufferTexture + blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex0.bind(0) + shaderKawaseDown.bind() + shaderKawaseDown.setUniformMatrix("u_projTrans", fbos.camera.combined) + shaderKawaseDown.setUniformi("u_texture", 0) + shaderKawaseDown.setUniformf("halfpixel", radius3 / fbos.half.width, radius3 / fbos.half.height) + fbos.quadHalf.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN) + } + + fbos.quarter.inAction(fbos.camera, batch) { + blurtex1 = fbos.half.colorBufferTexture + blurtex1.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex1.bind(0) + shaderKawaseDown.bind() + shaderKawaseDown.setUniformMatrix("u_projTrans", fbos.camera.combined) + shaderKawaseDown.setUniformi("u_texture", 0) + shaderKawaseDown.setUniformf("halfpixel", radius3 / fbos.quarter.width, radius3 / fbos.quarter.height) + fbos.quadQuarter.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN) + } + + fbos.half.inAction(fbos.camera, batch) { + blurtex2 = fbos.quarter.colorBufferTexture + blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex2.bind(0) + shaderKawaseUp.bind() + shaderKawaseUp.setUniformMatrix("u_projTrans", fbos.camera.combined) + shaderKawaseUp.setUniformi("u_texture", 0) + shaderKawaseUp.setUniformf("halfpixel", radius3 / fbos.quarter.width, radius3 / fbos.quarter.height) + fbos.quadHalf.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN) + } + + out.inAction(fbos.camera, batch) { + blurtex3 = fbos.half.colorBufferTexture + blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex3.bind(0) + shaderKawaseUp.bind() + shaderKawaseUp.setUniformMatrix("u_projTrans", fbos.camera.combined) + shaderKawaseUp.setUniformi("u_texture", 0) + shaderKawaseUp.setUniformf("halfpixel", radius3 / fbos.half.width, radius3 / fbos.half.height) + fbos.quadFull.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN) + } + } + + fun dispose() { + fboDict.values.forEach { it.dispose() } + shaderKawaseUp.dispose() + shaderKawaseDown.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 8768beb26..9927f479b 100644 --- a/src/net/torvald/terrarum/ui/Toolkit.kt +++ b/src/net/torvald/terrarum/ui/Toolkit.kt @@ -44,19 +44,7 @@ object Toolkit : Disposable { */ } - - - private val shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag") - private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag") - private val shaderBoxDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/boxdown.frag") - private val shaderBoxUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/boxup.frag") - private lateinit var fboBlur: Float16FrameBuffer - private lateinit var fboBlurHalf: Float16FrameBuffer - private lateinit var fboBlurQuarter: Float16FrameBuffer - private lateinit var blurWriteQuad: Mesh - private lateinit var blurWriteQuad2: Mesh - private lateinit var blurWriteQuad4: Mesh // val baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36) val shadowTile = TextureRegionPack("assets/graphics/gui/blur_shadow.tga", 32, 32) @@ -82,19 +70,6 @@ object Toolkit : Disposable { // baloonTile.dispose() textureWhiteSquare.dispose() textureWhiteCircle.dispose() - - fboBlur.dispose() - fboBlurHalf.dispose() - fboBlurQuarter.dispose() - - blurWriteQuad.dispose() - blurWriteQuad2.dispose() - blurWriteQuad4.dispose() - - shaderKawaseUp.dispose() - shaderKawaseDown.dispose() - shaderBoxDown.dispose() - shaderBoxUp.dispose() } val drawWidth: Int @@ -201,87 +176,11 @@ object Toolkit : Disposable { pixmap.fillRectangle(x + w, y, 1, h) } - private lateinit var blurtex0: Texture - private lateinit var blurtex1: Texture - private lateinit var blurtex2: Texture - private lateinit var blurtex3: Texture - - fun blurEntireScreen(batch: SpriteBatch, camera: OrthographicCamera, blurRadius0: Float, x: Int, y: Int, w: Int, h: Int) { + fun blurEntireScreen(batch: SpriteBatch, blurRadius0: Float, x: Int, y: Int, w: Int, h: Int) { batch.end() -// val blurRadius = FastMath.pow(blurRadius0, 0.5f) val renderTarget = FrameBufferManager.peek() - - //if (blurRadius > 3f) { - val radius3 = FastMath.pow(blurRadius0 / 2, 0.5f)//(blurRadius - 3f) / 8f - fboBlurHalf.inAction(camera, batch) { - blurtex0 = renderTarget.colorBufferTexture - blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurtex0.bind(0) - shaderKawaseDown.bind() - shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) - shaderKawaseDown.setUniformi("u_texture", 0) - shaderKawaseDown.setUniformf("halfpixel", radius3 / fboBlurHalf.width, radius3 / fboBlurHalf.height) - blurWriteQuad2.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN) - } - - fboBlurQuarter.inAction(camera, batch) { - blurtex1 = fboBlurHalf.colorBufferTexture - blurtex1.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurtex1.bind(0) - shaderKawaseDown.bind() - shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) - shaderKawaseDown.setUniformi("u_texture", 0) - shaderKawaseDown.setUniformf("halfpixel", radius3 / fboBlurQuarter.width, radius3 / fboBlurQuarter.height) - blurWriteQuad4.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN) - } - - fboBlurHalf.inAction(camera, batch) { - blurtex2 = fboBlurQuarter.colorBufferTexture - blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurtex2.bind(0) - shaderKawaseUp.bind() - shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) - shaderKawaseUp.setUniformi("u_texture", 0) - shaderKawaseUp.setUniformf("halfpixel", radius3 / fboBlurQuarter.width, radius3 / fboBlurQuarter.height) - blurWriteQuad2.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN) - } - - fboBlur.inAction(camera, batch) { - blurtex3 = fboBlurHalf.colorBufferTexture - blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurtex3.bind(0) - shaderKawaseUp.bind() - shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) - shaderKawaseUp.setUniformi("u_texture", 0) - shaderKawaseUp.setUniformf("halfpixel", radius3 / fboBlurHalf.width, radius3 / fboBlurHalf.height) - blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN) - } - //} - - /*fboBlurHalf.inAction(camera, batch) { - blurtex2 = renderTarget.colorBufferTexture - blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurtex2.bind(0) - shaderKawaseDown.bind() - shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) - shaderKawaseDown.setUniformi("u_texture", 0) - shaderKawaseDown.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) - blurWriteQuad2.render(shaderKawaseDown, GL20.GL_TRIANGLE_FAN) - } - - fboBlur.inAction(camera, batch) { - blurtex3 = fboBlurHalf.colorBufferTexture - blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurtex3.bind(0) - shaderKawaseUp.bind() - shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) - shaderKawaseUp.setUniformi("u_texture", 0) - shaderKawaseUp.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) - blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLE_FAN) - }*/ - - + BlurMgr.makeBlur(renderTarget, fboBlur, blurRadius0) Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it @@ -344,33 +243,9 @@ object Toolkit : Disposable { init = true } else { - blurWriteQuad.dispose() - blurWriteQuad2.dispose() - blurWriteQuad4.dispose() fboBlur.dispose() - fboBlurHalf.dispose() - fboBlurQuarter.dispose() } - blurWriteQuad = Mesh( - true, 4, 4, - VertexAttribute.Position(), - VertexAttribute.ColorUnpacked(), - VertexAttribute.TexCoords(0) - ) - blurWriteQuad2 = Mesh( - true, 4, 4, - VertexAttribute.Position(), - VertexAttribute.ColorUnpacked(), - VertexAttribute.TexCoords(0) - ) - blurWriteQuad4 = Mesh( - true, 4, 4, - VertexAttribute.Position(), - VertexAttribute.ColorUnpacked(), - VertexAttribute.TexCoords(0) - ) - val fw = App.scr.width//MathUtils.nextPowerOfTwo(App.scr.width) val fh = App.scr.height//MathUtils.nextPowerOfTwo(App.scr.height) @@ -379,36 +254,5 @@ object Toolkit : Disposable { fh, false ) - fboBlurHalf = Float16FrameBuffer( - fw / 2, - fh / 2, - false - ) - fboBlurQuarter = Float16FrameBuffer( - fw / 4, - fh / 4, - false - ) - - blurWriteQuad.setVertices(floatArrayOf( - 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, - fw.toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, - fw.toFloat(), fh.toFloat(),0f, 1f,1f,1f,1f, 1f,0f, - 0f, fh.toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) - blurWriteQuad.setIndices(shortArrayOf(0, 1, 2, 3)) - - blurWriteQuad2.setVertices(floatArrayOf( - 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, - fw.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, - fw.div(2).toFloat(), fh.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, - 0f, fh.div(2).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) - blurWriteQuad2.setIndices(shortArrayOf(0, 1, 2, 3)) - - blurWriteQuad4.setVertices(floatArrayOf( - 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, - fw.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, - fw.div(4).toFloat(), fh.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, - 0f, fh.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) - blurWriteQuad4.setIndices(shortArrayOf(0, 1, 2, 3)) } } \ No newline at end of file