From cf2932a519cc0f525ed1f7692d2ccbac8b9379af Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 4 Jul 2017 23:30:48 +0900 Subject: [PATCH] blur shader works --- assets/blur.frag | 29 ++++- src/net/torvald/terrarum/TestTestTest.kt | 137 +++++++++++++++-------- 2 files changed, 117 insertions(+), 49 deletions(-) diff --git a/assets/blur.frag b/assets/blur.frag index 5c14b92a7..babfa6f5f 100644 --- a/assets/blur.frag +++ b/assets/blur.frag @@ -1,12 +1,31 @@ -#ifdef GL_ES - precision mediump float; -#endif varying vec4 v_color; varying vec2 v_texCoords; uniform sampler2D u_texture; + + +uniform vec3 iResolution; +uniform float flip; +uniform vec2 direction; + +vec4 blur(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) { + vec4 color = vec4(0.0); + vec2 off1 = vec2(1.3846153846) * direction; + vec2 off2 = vec2(3.2307692308) * direction; + color += texture2D(image, uv) * 0.2270270270; + color += texture2D(image, uv + (off1 / resolution)) * 0.3162162162; + color += texture2D(image, uv - (off1 / resolution)) * 0.3162162162; + color += texture2D(image, uv + (off2 / resolution)) * 0.0702702703; + color += texture2D(image, uv - (off2 / resolution)) * 0.0702702703; + return color; +} + void main() { - //gl_FragColor = v_color * texture2D(u_texture, v_texCoords); - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + vec2 uv = vec2(gl_FragCoord.xy / iResolution.xy); + if (flip == 1.0) { + uv.y = 1.0 - uv.y; + } + + gl_FragColor = blur(u_texture, uv, iResolution.xy, direction); } \ No newline at end of file diff --git a/src/net/torvald/terrarum/TestTestTest.kt b/src/net/torvald/terrarum/TestTestTest.kt index cbc0415e9..ab0346de4 100644 --- a/src/net/torvald/terrarum/TestTestTest.kt +++ b/src/net/torvald/terrarum/TestTestTest.kt @@ -4,12 +4,17 @@ import com.badlogic.gdx.ApplicationAdapter import com.badlogic.gdx.Gdx import com.badlogic.gdx.backends.lwjgl.LwjglApplication import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration -import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.GL20 +import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.BitmapFont import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.FrameBuffer +import com.badlogic.gdx.graphics.glutils.ShaderProgram import net.torvald.terrarumsansbitmap.gdx.GameFontBase +import com.badlogic.gdx.graphics.OrthographicCamera + + /** @@ -22,6 +27,13 @@ class TestTestTest : ApplicationAdapter() { lateinit var gameFont: BitmapFont + lateinit var blurShader: ShaderProgram + + lateinit var blurFboA: FrameBuffer + lateinit var blurFboB: FrameBuffer + + lateinit var cam: OrthographicCamera + override fun create() { batch = SpriteBatch() img = Texture("assets/test_texture.tga") @@ -29,59 +41,89 @@ class TestTestTest : ApplicationAdapter() { gameFont = GameFontBase("assets/graphics/fonts/terrarum-sans-bitmap") //gameFont = BitmapFont() + + blurFboA = FrameBuffer(Pixmap.Format.RGBA8888, img.width, img.height, false) + blurFboB = FrameBuffer(Pixmap.Format.RGBA8888, img.width, img.height, false) + + ShaderProgram.pedantic = false + blurShader = ShaderProgram(Gdx.files.internal("assets/blur.vert"), Gdx.files.internal("assets/blur.frag")) + + blurShader.begin() + blurShader.setUniformf("iResolution", img.width.toFloat(), img.height.toFloat(), 0f) + blurShader.end() + + + cam = OrthographicCamera(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat()) + cam.setToOrtho(false) } - val text = arrayOf( - "x64またはx86-64とは、x86アーキテクチャを64ビットに拡張した命令セットアーキテクチャ。", - "実際には、AMDが発表したAMD64命令セット、続けてインテルが採用したIntel 64命令セット (かつてIA-32eまたはEM64Tと呼ばれていた)", - "などを含む、各社のAMD64互換命令セットの総称である。x86命令セットと互換性を持っていることから、広義にはx86にx64を含む場合がある。", - "", - "x86-64는 x86 명령어 집합 아키텍처의 64비트 모임이다. x86-64 명령어 집합은 에뮬레이션 없이 인텔의 x86를 지원하며 AMD64로 이름 붙인", - "AMD에 의해 고안되었다. 이 아키텍처는 인텔 64라는 이름으로 인텔에 의해 복제되기도 했다. (옘힐, 클래카마스 기술, CT, IA-32e, EM64T 등으로", - "불렸음) 이로써 x86-64 또는 x64의 이름을 일상적으로 사용하기에 이르렀다.", - "", - "x86-64 (также AMD64/Intel64/EM64T) — 64-битное расширение, набор команд для архитектуры x86, разработанное", - "компанией AMD, позволяющее выполнять программы в 64-разрядном режиме. Это расширение архитектуры x86 с", - "почти полной обратной совместимостью.", - "", - "Επίσης η x86-64 έχει καταχωρητές γενικής χρήσης 64-bit και πολλές άλλες βελτιώσεις. Η αρχική προδιαγραφή", - "δημιουργήθηκε από την AMD και έχει υλοποιηθεί από την AMD, την Intel, τη VIA και άλλες εταιρείες. Διατηρεί πλήρη", - "συμβατότητα προς τα πίσω με κώδικα 32-bit.", - "", - "x86-64 (簡稱x64) 是64位版本的x86指令集,向后相容於16位及32位的x86架構。x64於1999年由AMD設計,AMD首次公開", - "64位元集以擴充給x86,稱為「AMD64」。其後也為英特爾所採用,現時英特爾稱之為「Intel 64」,在之前曾使用過「Clackamas", - "Technology」 (CT)、「IA-32e」及「EM64T」", - "", - "x86-64, ou x64, est une extension du jeu d'instructions x86 d'Intel, introduite par la société AMD avec la gamme", - "AMD64. Intel utilisera cette extension en l'appelant initialement EM64T renommé aujourd'hui en Intel 64.", - "", - "Amd64 (також x86-64/intel64/em64t/x64) — 64-бітова архітектура мікропроцесора і відповідний набір інструкцій,", - "розроблені компанією AMD. Це розширення архітектури x86 з повною зворотною сумісністю.", - "", - "x86-64 е наименованието на наборът от 64-битови разширения към x86 процесорната архитектура. Като синоним", - "на това наименование, се използват и съкращенията AMD64 (използвано от AMD), EM64T и IA-32e (използвани от", - "Intel) и x64 (използвано от Microsoft).", - "", - "เอกซ์86-64 (x86-64) เป็นชื่อของสถาปัตยกรรมคอมพิวเตอร์สำหรับไมโครโพรเซสเซอร์แบบ 64 บิต และชุดคำสั่งที่ใช้งานด้วยกัน x86-64", - "เป็นส่วนขยายของสถาปัตยกรรมแบบ x86 ออกแบบโดยบริษัท AMD และใช้ชื่อทางการค้าว่า AMD64 ในภายหลังบริษัทอินเทลได้นำสถาปัตยกร", - "รมนี้ไปใช้ใต้ชื่อการค้าว่า Intel 64 หรือ EM64T ซึ่งชื่อทั่วไปที่ใช้กันโดยไม่อิงกับชื่อการค้าคือ x86-64 หรือ x64" - ) - override fun render() { + val iterations = 16 + val radius = 4f + + Gdx.gl.glClearColor(.157f, .157f, .157f, 0f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) - Gdx.graphics.setTitle("$GAME_NAME — F: ${Gdx.graphics.framesPerSecond}") - (gameFont as GameFontBase).reload("bg") + blurFboA.inAction { + Gdx.gl.glClearColor(0f, 0f, 0f, 0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } - batch.inBatch { + blurFboB.inAction { + Gdx.gl.glClearColor(0f, 0f, 0f, 0f) + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) + } - text.forEachIndexed { index, s -> - gameFont.color = Color(1f, 1f, 1f, 1f) - gameFont.draw(batch, s, 10f, 10 + (20 * text.size) - 20f * index) + + var writeBuffer = blurFboA + var readBuffer = blurFboB + + + for (i in 0..iterations - 1) { + writeBuffer.inAction { + batch.inUse { + cam.setToOrtho(false, writeBuffer.width.toFloat(), writeBuffer.height.toFloat()) + batch.projectionMatrix = cam.combined + + + val texture = if (i == 0) + img + else + readBuffer.colorBufferTexture + + texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + + batch.shader = blurShader + batch.shader.setUniformf("flip", 1f) + if (i % 2 == 0) + batch.shader.setUniformf("direction", radius, 0f) + else + batch.shader.setUniformf("direction", 0f, radius) + + + + batch.draw(texture, 0f, 0f) + + + // swap + val t = writeBuffer + writeBuffer = readBuffer + readBuffer = t + } } + } + // draw last FBO to screen + batch.inUse { + cam.setToOrtho(false, Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat()) + batch.projectionMatrix = cam.combined + + + batch.shader.setUniformf("direction", 0f, 0f) + batch.shader.setUniformf("flip", if (iterations % 2 != 0) 1f else 0f) + batch.draw(writeBuffer.colorBufferTexture, 0f, 0f) } } @@ -91,11 +133,18 @@ class TestTestTest : ApplicationAdapter() { } - private inline fun SpriteBatch.inBatch(action: () -> Unit) { + private inline fun SpriteBatch.inUse(action: () -> Unit) { this.begin() action() this.end() } + + inline fun FrameBuffer.inAction(action: (FrameBuffer) -> Unit) { + this.begin() + action(this) + this.end() + } + } fun main(args: Array) { // LWJGL 3 won't work? java.lang.VerifyError