From 73f01a859ab62305a11fc30722fb843b920442bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D1=82=D0=B5=D0=BD=D0=B3=D0=B0=D1=83=D1=8D=D1=80=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=94=D0=BC=D0=B8=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 4 Dec 2023 11:48:53 +0300 Subject: [PATCH] FXAA integration changes --- .../canvas/async/AsyncBlitCanvasImpl.kt | 26 +++++++---- .../canvas/async/AsyncIOSurfaceCanvasImpl.kt | 44 +++++++++++-------- .../async/AsyncNVDXInteropCanvasImpl.kt | 6 ++- .../canvas/async/AsyncSharedCanvasImpl.kt | 14 +++--- .../openglfx/internal/shaders/FXAAShader.kt | 11 ++--- .../internal/shaders/PassthroughShader.kt | 18 +++----- 6 files changed, 65 insertions(+), 54 deletions(-) diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncBlitCanvasImpl.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncBlitCanvasImpl.kt index 7af434a..108294f 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncBlitCanvasImpl.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncBlitCanvasImpl.kt @@ -37,7 +37,7 @@ open class AsyncBlitCanvasImpl( private var resultSize = Size() private lateinit var fbo: Framebuffer - private lateinit var msaaFBO: MultiSampledFramebuffer + private var msaaFBO: MultiSampledFramebuffer? = null private lateinit var transferFBO: Framebuffer private lateinit var resultFBO: Framebuffer @@ -88,12 +88,17 @@ open class AsyncBlitCanvasImpl( } private fun paint(){ - drawSize.executeOnDifferenceWith(scaledSize, ::resizeDrawFramebuffer, canvas::fireReshapeEvent) + if(drawSize != scaledSize || + msaa != (msaaFBO?.requestedSamples ?: 0) + ){ + scaledSize.copyTo(drawSize) + resizeDrawFramebuffer(drawSize.width, drawSize.height) + canvas.fireReshapeEvent(drawSize.width, drawSize.height) + } glViewport(0, 0, drawSize.width, drawSize.height) - canvas.fireRenderEvent(if (msaa != 0) msaaFBO.id else fbo.id) - if (msaa != 0) - msaaFBO.blitTo(fbo) + canvas.fireRenderEvent(msaaFBO?.id ?: fbo.id) + msaaFBO?.blitTo(fbo) } override fun renderContent(g: Graphics){ @@ -122,14 +127,17 @@ open class AsyncBlitCanvasImpl( private fun resizeDrawFramebuffer(width: Int, height: Int) { if(::fbo.isInitialized){ fbo.delete() - if(msaa != 0) msaaFBO.delete() + msaaFBO?.delete() } fbo = Framebuffer(width, height) - if(msaa != 0) { + if(msaa > 0) { msaaFBO = MultiSampledFramebuffer(msaa, width, height) - msaaFBO.bindFramebuffer() - } else fbo.bindFramebuffer() + msaaFBO?.bindFramebuffer() + } else { + msaaFBO = null + fbo.bindFramebuffer() + } } private fun resizeTransferFramebuffer(width: Int, height: Int){ diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt index ac9485c..a7d9830 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt @@ -42,28 +42,26 @@ open class AsyncIOSurfaceCanvasImpl( private lateinit var sharedFboGL: Framebuffer private lateinit var fboFX: Framebuffer private lateinit var fboGL: Framebuffer - private lateinit var msaaFBO: MultiSampledFramebuffer + private var msaaFBO: MultiSampledFramebuffer? = null private lateinit var fxContext: GLContext - private lateinit var fxWrapperContext: GLContext + private lateinit var fxContextWrapper: GLContext private lateinit var context: GLContext private var needsBlit = AtomicBoolean(false) - private lateinit var filteredFBO: Framebuffer - private lateinit var filterShader: PassthroughShader + private val passthroughShader by lazy { PassthroughShader() } + private val fxaaShader by lazy { FXAAShader() } private fun initializeThread(){ fxContext = GLContext.current() - fxWrapperContext = GLContext.create(fxContext, false) + fxContextWrapper = GLContext.create(fxContext, false) thread(isDaemon = true) { context = GLContext.create(0, profile == GLProfile.Core) context.makeCurrent() executor.initGLFunctions() - if(canvas.fxaa) filterShader = FXAAShader() - while (!disposed){ paint() synchronized(blitLock) { @@ -93,12 +91,17 @@ open class AsyncIOSurfaceCanvasImpl( } private fun paint(){ - drawSize.executeOnDifferenceWith(scaledSize, ::updateFramebufferSize, canvas::fireReshapeEvent) + if(drawSize != scaledSize || + msaa != (msaaFBO?.requestedSamples ?: 0) + ){ + scaledSize.copyTo(drawSize) + updateFramebufferSize(drawSize.width, drawSize.height) + canvas.fireReshapeEvent(drawSize.width, drawSize.height) + } glViewport(0, 0, drawSize.width, drawSize.height) - canvas.fireRenderEvent(if(msaa != 0) msaaFBO.id else fboGL.id) - if(msaa != 0) - msaaFBO.blitTo(fboGL) + canvas.fireRenderEvent(msaaFBO?.id ?: fboGL.id) + msaaFBO?.blitTo(fboGL) } override fun renderContent(g: Graphics) { @@ -109,11 +112,13 @@ open class AsyncIOSurfaceCanvasImpl( initializeThread() if (needsBlit.getAndSet(false)) { + fxContextWrapper.makeCurrent() synchronized(blitLock){ - resultSize.executeOnDifferenceWith(interopTextureSize, ::updateResultTextureSize) - fxWrapperContext.makeCurrent() - glViewport(0, 0, scaledWidth, scaledHeight) - sharedFboFX.blitTo(fboFX) + resultSize.executeOnDifferenceWith(interopTextureSize) { width, height -> + updateResultTextureSize(width, height) + glViewport(0, 0, scaledWidth, scaledHeight) + } + (if(fxaa) fxaaShader else passthroughShader).apply(sharedFboFX, fboFX) fxContext.makeCurrent() } } @@ -124,7 +129,7 @@ open class AsyncIOSurfaceCanvasImpl( private fun updateFramebufferSize(width: Int, height: Int) { if (::fboGL.isInitialized) { fboGL.delete() - if(msaa != 0) msaaFBO.delete() + msaaFBO?.delete() } // Create simple framebuffer @@ -133,8 +138,11 @@ open class AsyncIOSurfaceCanvasImpl( // Create multi-sampled framebuffer if(msaa != 0) { msaaFBO = MultiSampledFramebuffer(msaa, width, height) - msaaFBO.bindFramebuffer() - } else fboGL.bindFramebuffer() + msaaFBO?.bindFramebuffer() + } else { + msaaFBO = null + fboGL.bindFramebuffer() + } } private fun updateSurfaceSize(width: Int, height: Int){ diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncNVDXInteropCanvasImpl.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncNVDXInteropCanvasImpl.kt index efec49c..1186c8d 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncNVDXInteropCanvasImpl.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncNVDXInteropCanvasImpl.kt @@ -112,13 +112,15 @@ open class AsyncNVDXInteropCanvasImpl( // Create GL texture fbo = Framebuffer(width, height) - fbo.bindFramebuffer() // Create multi-sampled framebuffer if(msaa > 0) { msaaFBO = MultiSampledFramebuffer(msaa, width, height) msaaFBO!!.bindFramebuffer() - }else msaaFBO = null + }else { + msaaFBO = null + fbo.bindFramebuffer() + } } private fun updateInterTextureSize(width: Int, height: Int){ diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncSharedCanvasImpl.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncSharedCanvasImpl.kt index cc41145..874bd3b 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncSharedCanvasImpl.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncSharedCanvasImpl.kt @@ -32,7 +32,7 @@ open class AsyncSharedCanvasImpl( private var resultSize = Size() private lateinit var context: GLContext - private lateinit var fxWrapperContext: GLContext + private lateinit var fxContextWrapper: GLContext private lateinit var fxContext: GLContext private lateinit var fbo: Framebuffer @@ -49,8 +49,8 @@ open class AsyncSharedCanvasImpl( private fun initializeThread(){ fxContext = GLContext.current() + fxContextWrapper = GLContext.create(fxContext, profile == GLProfile.Core) context = GLContext.create(fxContext, profile == GLProfile.Core) - fxWrapperContext = GLContext.create(fxContext, profile == GLProfile.Core) thread(isDaemon = true) { context.makeCurrent() @@ -82,7 +82,7 @@ open class AsyncSharedCanvasImpl( msaaFBO?.delete() GLContext.delete(context) - GLContext.delete(fxWrapperContext) + GLContext.delete(fxContextWrapper) fxContext.makeCurrent() } } @@ -110,7 +110,7 @@ open class AsyncSharedCanvasImpl( initializeThread() if (needsBlit.getAndSet(false)) { - fxWrapperContext.makeCurrent() + fxContextWrapper.makeCurrent() synchronized(blitLock){ resultSize.executeOnDifferenceWith(transferSize) { width, height -> updateResultFramebufferSize(width, height) @@ -152,13 +152,15 @@ open class AsyncSharedCanvasImpl( // Create framebuffer fbo = Framebuffer(width, height) - fbo.bindFramebuffer() // Create multi-sampled framebuffer if(msaa > 0){ msaaFBO = MultiSampledFramebuffer(msaa, width, height) msaaFBO!!.bindFramebuffer() - } else msaaFBO = null + } else { + msaaFBO = null + fbo.bindFramebuffer() + } } override fun repaint() { diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/FXAAShader.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/FXAAShader.kt index 70de24b..ad827fb 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/FXAAShader.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/FXAAShader.kt @@ -1,10 +1,7 @@ package com.huskerdev.openglfx.internal.shaders internal class FXAAShader: PassthroughShader( - fragmentSource = """ - #version 100 - precision highp float; - + fragmentSource = """ #define FXAA_SPAN_MAX 8.0 #define FXAA_REDUCE_MUL (1.0/FXAA_SPAN_MAX) #define FXAA_REDUCE_MIN (1.0/128.0) @@ -57,11 +54,11 @@ internal class FXAAShader: PassthroughShader( return rgbB; } - uniform sampler2D tex; - uniform vec2 tex_size; + uniform sampler2D texture; + uniform vec2 size; void main() { - gl_FragColor = fxaa(tex, gl_FragCoord.xy, tex_size); + gl_FragColor = fxaa(texture, gl_FragCoord.xy, size); } """.trimIndent() ) \ No newline at end of file diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt index f35440f..77174ae 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt @@ -29,24 +29,18 @@ import com.huskerdev.openglfx.internal.fbo.Framebuffer internal open class PassthroughShader( vertexSource: String = """ - #version 100 - precision highp float; - - attribute vec4 a_pos; + attribute vec4 position; void main() { - gl_Position = a_pos; + gl_Position = position; } """.trimIndent(), fragmentSource: String = """ - #version 100 - precision highp float; - - uniform sampler2D tex; - uniform vec2 tex_size; + uniform sampler2D texture; + uniform vec2 size; void main() { - gl_FragColor = texture2D(tex, gl_FragCoord.xy / tex_size); + gl_FragColor = texture2D(texture, gl_FragCoord.xy / size); } """.trimIndent() ) { @@ -74,7 +68,7 @@ internal open class PassthroughShader( glDeleteShader(vertex) glDeleteShader(fragment) - texSizeLoc = glGetUniformLocation(program, "tex_size") + texSizeLoc = glGetUniformLocation(program, "size") vao = glGenVertexArrays() glBindVertexArray(vao)