screen blur helper class

This commit is contained in:
minjaesong
2024-11-23 21:17:16 +09:00
parent d460447331
commit f5846d9bae
6 changed files with 161 additions and 162 deletions

View File

@@ -38,6 +38,7 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer;
import net.torvald.terrarum.modulebasegame.TerrarumIngame; import net.torvald.terrarum.modulebasegame.TerrarumIngame;
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory; import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
import net.torvald.terrarum.serialise.WriteConfig; import net.torvald.terrarum.serialise.WriteConfig;
import net.torvald.terrarum.ui.BlurMgr;
import net.torvald.terrarum.ui.Toolkit; import net.torvald.terrarum.ui.Toolkit;
import net.torvald.terrarum.utils.JsonFetcher; import net.torvald.terrarum.utils.JsonFetcher;
import net.torvald.terrarum.worlddrawer.CreateTileAtlas; import net.torvald.terrarum.worlddrawer.CreateTileAtlas;
@@ -52,6 +53,7 @@ import org.apache.commons.csv.CSVParser;
import org.lwjgl.PointerBuffer; import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import javax.tools.Tool;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
@@ -1026,6 +1028,9 @@ public class App implements ApplicationListener {
deleteTempfiles(); deleteTempfiles();
Toolkit.INSTANCE.dispose();
BlurMgr.INSTANCE.dispose();
disposables.forEach((it) -> { disposables.forEach((it) -> {
try { try {
it.dispose(); it.dispose();

View File

@@ -69,7 +69,7 @@ basegame
* e.g. 0x02010034 will be translated as 2.1.52 * 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.0: 2259
// Commit counts up to the Release 0.3.1: 2278 // Commit counts up to the Release 0.3.1: 2278
// Commit counts up to the Release 0.3.2: 2732 // Commit counts up to the Release 0.3.2: 2732

View File

@@ -95,7 +95,7 @@ class UIFakeBlurOverlay(val blurRadius: Float, val nodarken: Boolean) : UICanvas
batchDrawCol.a = openness batchDrawCol.a = openness
batch.color = batchDrawCol batch.color = batchDrawCol
if (App.getConfigBoolean("fx_backgroundblur")) { 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) { if (!nodarken) {

View File

@@ -35,7 +35,7 @@ class UICheatDetected : UICanvas() {
Terrarum.ingame?.consoleHandler?.setAsClose() Terrarum.ingame?.consoleHandler?.setAsClose()
Terrarum.ingame?.consoleHandler?.isVisible = false 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 batch.color = backgroundCol
Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat()) Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat())
@@ -80,7 +80,7 @@ class UIPauseTheGame : UICanvas() {
Terrarum.ingame?.consoleHandler?.setAsClose() Terrarum.ingame?.consoleHandler?.setAsClose()
Terrarum.ingame?.consoleHandler?.isVisible = false 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 batch.color = backgroundCol
Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat()) Toolkit.fillArea(batch, 0f, 0f, width.toFloat(), height.toFloat())

View File

@@ -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<Long, FrameBufferSet>()
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()
}
}

View File

@@ -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 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 baloonTile = TextureRegionPack("assets/graphics/gui/message_black_tileable.tga", 36, 36)
val shadowTile = TextureRegionPack("assets/graphics/gui/blur_shadow.tga", 32, 32) val shadowTile = TextureRegionPack("assets/graphics/gui/blur_shadow.tga", 32, 32)
@@ -82,19 +70,6 @@ object Toolkit : Disposable {
// baloonTile.dispose() // baloonTile.dispose()
textureWhiteSquare.dispose() textureWhiteSquare.dispose()
textureWhiteCircle.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 val drawWidth: Int
@@ -201,87 +176,11 @@ object Toolkit : Disposable {
pixmap.fillRectangle(x + w, y, 1, h) pixmap.fillRectangle(x + w, y, 1, h)
} }
private lateinit var blurtex0: Texture fun blurEntireScreen(batch: SpriteBatch, blurRadius0: Float, x: Int, y: Int, w: Int, h: Int) {
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) {
batch.end() batch.end()
// val blurRadius = FastMath.pow(blurRadius0, 0.5f)
val renderTarget = FrameBufferManager.peek() val renderTarget = FrameBufferManager.peek()
BlurMgr.makeBlur(renderTarget, fboBlur, blurRadius0)
//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)
}*/
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it 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 init = true
} }
else { else {
blurWriteQuad.dispose()
blurWriteQuad2.dispose()
blurWriteQuad4.dispose()
fboBlur.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 fw = App.scr.width//MathUtils.nextPowerOfTwo(App.scr.width)
val fh = App.scr.height//MathUtils.nextPowerOfTwo(App.scr.height) val fh = App.scr.height//MathUtils.nextPowerOfTwo(App.scr.height)
@@ -379,36 +254,5 @@ object Toolkit : Disposable {
fh, fh,
false 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))
} }
} }