From 06a6d2774cc98295e38ad39031711a3f59fc6a32 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 12 Dec 2021 13:09:59 +0900 Subject: [PATCH] screen blur without creating a texture --- src/net/torvald/terrarum/App.java | 23 ++++- .../torvald/terrarum/FrameBufferManager.java | 3 + src/net/torvald/terrarum/PostProcessor.kt | 30 +++--- src/net/torvald/terrarum/UIFakeGradOverlay.kt | 3 +- .../terrarum/modulebasegame/IngameRenderer.kt | 67 +++++--------- src/net/torvald/terrarum/ui/Toolkit.kt | 91 +++++++++---------- 6 files changed, 107 insertions(+), 110 deletions(-) diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index 00ec18721..53820b169 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -11,6 +11,7 @@ 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.FloatFrameBuffer; +import com.badlogic.gdx.graphics.glutils.GLFrameBuffer; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.utils.Disposable; @@ -46,6 +47,7 @@ import net.torvald.util.DebugTimers; import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; import java.util.*; import static net.torvald.terrarum.TerrarumKt.*; @@ -222,7 +224,8 @@ public class App implements ApplicationListener { private static ShaderProgram shaderBayerSkyboxFill; // ONLY to be used by the splash screen public static ShaderProgram shaderHicolour; public static ShaderProgram shaderDebugDiff; - public static ShaderProgram shaderPassthruRGB; + public static ShaderProgram shaderPassthruRGBA; + public static ShaderProgram shaderDitherRGBA; public static ShaderProgram shaderColLUT; public static ShaderProgram shaderReflect; @@ -428,7 +431,8 @@ public class App implements ApplicationListener { shaderBayerSkyboxFill = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_skyboxfill.frag"); shaderHicolour = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/hicolour.frag"); shaderDebugDiff = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/diff.frag"); - shaderPassthruRGB = SpriteBatch.createDefaultShader(); + shaderPassthruRGBA = SpriteBatch.createDefaultShader(); + shaderDitherRGBA = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer.frag"); // always load the shader regardless of config because the config may cange shaderColLUT = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/passthrurgb.frag"); shaderReflect = loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/reflect.frag"); @@ -723,6 +727,19 @@ public class App implements ApplicationListener { scr.getHeight(), false ); + + + if (IS_DEVELOPMENT_BUILD) { + try { + Field field = GLFrameBuffer.class.getDeclaredField("framebufferHandle"); + field.setAccessible(true); + System.out.println("Attachment ID for renderFBO: " + field.get(renderFBO)); + } + catch (NoSuchFieldException | IllegalAccessException e) { + System.err.println("Attachment ID for renderFBO: X_x"); + e.printStackTrace(); + } + } } Toolkit.INSTANCE.resize(); @@ -760,7 +777,7 @@ public class App implements ApplicationListener { shaderBayerSkyboxFill.dispose(); shaderHicolour.dispose(); shaderDebugDiff.dispose(); - shaderPassthruRGB.dispose(); + shaderPassthruRGBA.dispose(); shaderColLUT.dispose(); shaderReflect.dispose(); diff --git a/src/net/torvald/terrarum/FrameBufferManager.java b/src/net/torvald/terrarum/FrameBufferManager.java index ce79778f2..00533cc3e 100644 --- a/src/net/torvald/terrarum/FrameBufferManager.java +++ b/src/net/torvald/terrarum/FrameBufferManager.java @@ -28,4 +28,7 @@ public class FrameBufferManager { } } + public static FrameBuffer peek() { + return (stack.size() > 0) ? stack.peek() : null; + } } diff --git a/src/net/torvald/terrarum/PostProcessor.kt b/src/net/torvald/terrarum/PostProcessor.kt index e1a8cd392..abb8f7910 100644 --- a/src/net/torvald/terrarum/PostProcessor.kt +++ b/src/net/torvald/terrarum/PostProcessor.kt @@ -8,7 +8,6 @@ import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.FrameBuffer -import com.badlogic.gdx.graphics.glutils.ShaderProgram import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Matrix4 import com.badlogic.gdx.utils.Disposable @@ -43,7 +42,6 @@ object PostProcessor : Disposable { private val functionRowHelper = Texture(Gdx.files.internal("assets/graphics/function_row_help.png")) - private val shaderBayer = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer.frag") // always load the shader regardless of config because the config may cange init { App.disposables.add(this) @@ -57,7 +55,6 @@ object PostProcessor : Disposable { lutTex.dispose() } catch (e: UninitializedPropertyAccessException) { } - shaderBayer.dispose() } fun draw(projMat: Matrix4, fbo: FrameBuffer) { @@ -133,17 +130,26 @@ object PostProcessor : Disposable { private val rng = HQRNG() private fun postShader(projMat: Matrix4, fbo: FrameBuffer) { - val shader: ShaderProgram = shaderBayer - App.getCurrentDitherTex().bind(1) - fbo.colorBufferTexture.bind(0) + if (App.getConfigBoolean("fx_dither")) { + App.getCurrentDitherTex().bind(1) + fbo.colorBufferTexture.bind(0) - shader.bind() - shader.setUniformMatrix("u_projTrans", projMat) - shader.setUniformi("u_texture", 0) - shader.setUniformi("rnd", rng.nextInt(8192), rng.nextInt(8192)) - shader.setUniformi("u_pattern", 1) - App.fullscreenQuad.render(shader, GL20.GL_TRIANGLES) + App.shaderDitherRGBA.bind() + App.shaderDitherRGBA.setUniformMatrix("u_projTrans", projMat) + App.shaderDitherRGBA.setUniformi("u_texture", 0) + App.shaderDitherRGBA.setUniformi("rnd", rng.nextInt(8192), rng.nextInt(8192)) + App.shaderDitherRGBA.setUniformi("u_pattern", 1) + App.fullscreenQuad.render(App.shaderDitherRGBA, GL20.GL_TRIANGLES) + } + else { + fbo.colorBufferTexture.bind(0) + + App.shaderPassthruRGBA.bind() + App.shaderPassthruRGBA.setUniformMatrix("u_projTrans", projMat) + App.shaderPassthruRGBA.setUniformi("u_texture", 0) + App.fullscreenQuad.render(App.shaderPassthruRGBA, GL20.GL_TRIANGLES) + } Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it diff --git a/src/net/torvald/terrarum/UIFakeGradOverlay.kt b/src/net/torvald/terrarum/UIFakeGradOverlay.kt index 40106323b..a470cbe79 100644 --- a/src/net/torvald/terrarum/UIFakeGradOverlay.kt +++ b/src/net/torvald/terrarum/UIFakeGradOverlay.kt @@ -7,7 +7,6 @@ import com.badlogic.gdx.graphics.GL20 import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.random.HQRNG -import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas @@ -47,7 +46,7 @@ class UIFakeGradOverlay : UICanvas() { batch.begin() - batch.shader = if (dither) IngameRenderer.shaderBayer else null + batch.shader = null if (dither) { batch.shader.setUniformi("u_pattern", 1) batch.shader.setUniformi("rnd", renderng.nextInt(8192), renderng.nextInt(8192)) diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index f42125d35..997d60482 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -68,30 +68,21 @@ object IngameRenderer : Disposable { // you must have lightMixed FBO; otherwise you'll be reading from unbaked FBO and it freaks out GPU - inline fun isDither() = App.getConfigBoolean("fx_dither") +// inline fun isDither() = App.getConfigBoolean("fx_dither") private val rng = HQRNG() - val shaderBlur: ShaderProgram - get() = if (isDither()) shaderBlurDither else shaderBlurRaw - val shaderRGBOnly: ShaderProgram - get() = if (isDither()) shaderRGBOnlyDither else shaderRGBOnlyRaw - val shaderAtoGrey: ShaderProgram - get() = if (isDither()) shaderAtoGreyDither else shaderAtoGreyRaw - val shaderBlurDither: ShaderProgram - val shaderBlurRaw: ShaderProgram - val shaderRGBOnlyDither: ShaderProgram - val shaderRGBOnlyRaw: ShaderProgram - val shaderAtoGreyDither: ShaderProgram - val shaderAtoGreyRaw: ShaderProgram +// val shaderBlurDither: ShaderProgram +// val shaderRGBOnlyDither: ShaderProgram +// val shaderAtoGreyDither: ShaderProgram + val shaderBlur: ShaderProgram + val shaderRGBOnly: ShaderProgram + val shaderAtoGrey: ShaderProgram val shaderKawaseDown: ShaderProgram val shaderKawaseUp: ShaderProgram - val shaderBayer: ShaderProgram - val shaderPassthru = SpriteBatch.createDefaultShader() - val shaderBlendGlow: ShaderProgram val shaderAlphaDither: ShaderProgram @@ -125,16 +116,15 @@ object IngameRenderer : Disposable { // these codes will run regardless of the invocation of the "initialise()" function // the "initialise()" function will also be called init { - shaderBlurDither = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur_dither.frag") - shaderRGBOnlyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_rgb1.frag") - shaderAtoGreyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_aaa1.frag") +// shaderBlurDither = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur_dither.frag") +// shaderRGBOnlyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_rgb1.frag") +// shaderAtoGreyDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer_aaa1.frag") - shaderBlurRaw = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur.frag") - shaderRGBOnlyRaw = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/rgbonly.frag") - shaderAtoGreyRaw = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/aonly.frag") + shaderBlur = App.loadShaderFromFile("assets/shaders/blur.vert", "assets/shaders/blur.frag") + shaderRGBOnly = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/rgbonly.frag") + shaderAtoGrey = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/aonly.frag") - shaderBayer = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/4096_bayer.frag") // always load the shader regardless of config because the config may cange shaderAlphaDither = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/alphadither.frag") shaderBlendGlow = App.loadShaderFromFile("assets/shaders/blendGlow.vert", "assets/shaders/blendGlow.frag") @@ -152,12 +142,6 @@ object IngameRenderer : Disposable { exitProcess(1) } - if (isDither()) { - if (!shaderBayer.isCompiled) { - Gdx.app.log("shaderBayer", shaderBayer.log) - exitProcess(1) - } - } initialise() } @@ -694,10 +678,10 @@ object IngameRenderer : Disposable { blurtex0 = LightmapRenderer.draw() blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) blurtex0.bind(0) - shaderPassthru.bind() - shaderPassthru.setUniformMatrix("u_projTrans", camera.combined) - shaderPassthru.setUniformi("u_texture", 0) - blurWriteQuad.render(shaderPassthru, GL20.GL_TRIANGLES) + App.shaderPassthruRGBA.bind() + App.shaderPassthruRGBA.setUniformMatrix("u_projTrans", camera.combined) + App.shaderPassthruRGBA.setUniformi("u_texture", 0) + blurWriteQuad.render(App.shaderPassthruRGBA, GL20.GL_TRIANGLES) } fboBlurHalf.inAction(camera, batch) { @@ -870,21 +854,16 @@ object IngameRenderer : Disposable { batch.dispose() - shaderBlurDither.dispose() - shaderBlurRaw.dispose() - shaderRGBOnlyDither.dispose() - shaderRGBOnlyRaw.dispose() - shaderAtoGreyDither.dispose() - shaderAtoGreyRaw.dispose() - - shaderBayer.dispose() - shaderBlendGlow.dispose() - shaderPassthru.dispose() - shaderAlphaDither.dispose() + shaderBlur.dispose() + shaderRGBOnly.dispose() + shaderAtoGrey.dispose() shaderKawaseDown.dispose() shaderKawaseUp.dispose() + shaderBlendGlow.dispose() + shaderAlphaDither.dispose() + try { fboRGBexport.dispose() } diff --git a/src/net/torvald/terrarum/ui/Toolkit.kt b/src/net/torvald/terrarum/ui/Toolkit.kt index 9543478c4..5459b10cf 100644 --- a/src/net/torvald/terrarum/ui/Toolkit.kt +++ b/src/net/torvald/terrarum/ui/Toolkit.kt @@ -9,9 +9,9 @@ import com.badlogic.gdx.utils.Disposable import net.torvald.random.HQRNG import net.torvald.terrarum.App import net.torvald.terrarum.CommonResourcePool +import net.torvald.terrarum.FrameBufferManager import net.torvald.terrarum.inAction import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack -import org.lwjgl.opengl.GL20 /** @@ -31,8 +31,10 @@ object Toolkit : Disposable { } - private val shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxdown.frag") - private val shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxup.frag") + private val shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawasedown.frag") + private val shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag") + private val shaderBoxDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxdown.frag") + private val shaderBoxUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxup.frag") private lateinit var fboBlur: FloatFrameBuffer private lateinit var fboBlurHalf: FloatFrameBuffer @@ -75,11 +77,8 @@ object Toolkit : Disposable { shaderKawaseUp.dispose() shaderKawaseDown.dispose() - -// try { blurtex0.dispose() } catch (e: GdxRuntimeException) {} -// try { blurtex1.dispose() } catch (e: GdxRuntimeException) {} -// try { blurtex2.dispose() } catch (e: GdxRuntimeException) {} -// try { blurtex3.dispose() } catch (e: GdxRuntimeException) {} + shaderBoxDown.dispose() + shaderBoxUp.dispose() } val drawWidth: Int @@ -151,31 +150,21 @@ object Toolkit : Disposable { } -// private var blurtex0 = Texture(16, 16, Pixmap.Format.RGBA8888) - private var blurtex1 = Texture(16, 16, Pixmap.Format.RGBA8888) - private var blurtex2 = Texture(16, 16, Pixmap.Format.RGBA8888) - private var blurtex3 = Texture(16, 16, Pixmap.Format.RGBA8888) + 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) { batch.end() val blurRadius = blurRadius0 - -// blurtex0.dispose() -// blurtex1.dispose() -// blurtex2.dispose() -// blurtex3.dispose() - - - - val pixmap = Pixmap.createFromFrameBuffer(x, y, w, h) - val texture: Texture = Texture(pixmap) - val t = TextureRegion(texture, 0, h, w, -h) - pixmap.dispose() - + val renderTarget = FrameBufferManager.peek() /*fboBlurHalf.inAction(camera, batch) { - t.texture.bind(0) + 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) @@ -185,6 +174,7 @@ object Toolkit : Disposable { 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) @@ -195,6 +185,7 @@ object Toolkit : Disposable { 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) @@ -203,28 +194,6 @@ object Toolkit : Disposable { blurWriteQuad2.render(shaderKawaseUp, GL20.GL_TRIANGLES) } - // TODO apply dithering on this specific draw call - fboBlur.inAction(camera, batch) { - blurtex3 = fboBlurHalf.colorBufferTexture - 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_TRIANGLES) - }*/ - - - fboBlurHalf.inAction(camera, batch) { - t.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - t.texture.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_TRIANGLES) - } - fboBlur.inAction(camera, batch) { blurtex3 = fboBlurHalf.colorBufferTexture blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) @@ -234,9 +203,33 @@ object Toolkit : Disposable { shaderKawaseUp.setUniformi("u_texture", 0) shaderKawaseUp.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLES) + }*/ + + //////////////////////////////////////////////////////////////////////// + + fboBlurHalf.inAction(camera, batch) { + blurtex2 = renderTarget.colorBufferTexture + blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex2.bind(0) + shaderBoxDown.bind() + shaderBoxDown.setUniformMatrix("u_projTrans", camera.combined) + shaderBoxDown.setUniformi("u_texture", 0) + shaderBoxDown.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) + blurWriteQuad2.render(shaderBoxDown, GL20.GL_TRIANGLES) } - t.texture.dispose() + fboBlur.inAction(camera, batch) { + blurtex3 = fboBlurHalf.colorBufferTexture + blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex3.bind(0) + shaderBoxUp.bind() + shaderBoxUp.setUniformMatrix("u_projTrans", camera.combined) + shaderBoxUp.setUniformi("u_texture", 0) + shaderBoxUp.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) + blurWriteQuad.render(shaderBoxUp, GL20.GL_TRIANGLES) + } + + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it