From d4bc2679ac13bed7424e4cd8f07125a856825a5d Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Fri, 5 Oct 2018 16:45:35 +0200 Subject: [PATCH] Added jump flood --- build.gradle | 3 + orx-examples/src/main/kotlin/jumpfil-001.kt | 0 orx-examples/src/main/kotlin/jumpfil-002.kt | 56 +++++++++++++ orx-jumpflood/src/main/kotlin/JumpFlood.kt | 81 +++++++++++++++++++ .../resources/shaders/gl3/encode-points.frag | 16 ++++ .../main/resources/shaders/gl3/jumpflood.frag | 39 +++++++++ settings.gradle | 3 +- 7 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 orx-examples/src/main/kotlin/jumpfil-001.kt create mode 100644 orx-examples/src/main/kotlin/jumpfil-002.kt create mode 100644 orx-jumpflood/src/main/kotlin/JumpFlood.kt create mode 100644 orx-jumpflood/src/main/resources/shaders/gl3/encode-points.frag create mode 100644 orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag diff --git a/build.gradle b/build.gradle index 0518509e..bc4677b3 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,8 @@ ext { subprojects { + group 'org.openrndr.extra' + version '0.0.1' apply plugin: 'kotlin' repositories { @@ -28,6 +30,7 @@ subprojects { dependencies { compile "org.openrndr:openrndr-core:$openrndrVersion" + compile "org.openrndr:openrndr-filter:$openrndrVersion" compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '0.27.0' } diff --git a/orx-examples/src/main/kotlin/jumpfil-001.kt b/orx-examples/src/main/kotlin/jumpfil-001.kt new file mode 100644 index 00000000..e69de29b diff --git a/orx-examples/src/main/kotlin/jumpfil-002.kt b/orx-examples/src/main/kotlin/jumpfil-002.kt new file mode 100644 index 00000000..8136f200 --- /dev/null +++ b/orx-examples/src/main/kotlin/jumpfil-002.kt @@ -0,0 +1,56 @@ +import org.openrndr.Program +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.configuration +import org.openrndr.draw.ColorType +import org.openrndr.draw.colorBuffer +import org.openrndr.extra.jumpfill.EncodePoints +import org.openrndr.extra.jumpfill.JumpFlood + +class JumpFill001 : Program() { + + + var drawFunc = {} + override fun setup() { + + val encodePoints = EncodePoints() + val jumpFill = JumpFlood() + + val input = colorBuffer(512, 1024) + val coordinates = + listOf(colorBuffer(input.width, input.height, type = ColorType.FLOAT32), + colorBuffer(input.width, input.height, type = ColorType.FLOAT32)) + + for (i in 0 until 100) { + input.shadow[(Math.random() * input.width).toInt(), (Math.random() * input.height).toInt()] = + ColorRGBa.WHITE + } + input.shadow.upload() + + drawFunc = { + encodePoints.apply(input, coordinates[0]) + drawer.image(coordinates[0]) + jumpFill.maxSteps = 10 + for (i in 0 until 10) { + jumpFill.step = i + jumpFill.apply(coordinates[i % 2], coordinates[(i + 1) % 2]) + } + + drawer.image(coordinates[0]) + + } + } + + override fun draw() { + drawFunc() + } +} + +fun main(args: Array) { + application(JumpFill001(), configuration { + + width = 1024 + height = 1024 + + }) +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/JumpFlood.kt b/orx-jumpflood/src/main/kotlin/JumpFlood.kt new file mode 100644 index 00000000..8d783e08 --- /dev/null +++ b/orx-jumpflood/src/main/kotlin/JumpFlood.kt @@ -0,0 +1,81 @@ +package org.openrndr.extra.jumpfill + +import org.openrndr.draw.* +import org.openrndr.filter.filterShaderFromUrl +import org.openrndr.math.Matrix44 +import org.openrndr.resourceUrl + +class EncodePoints: Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/encode-points.frag"))) +class JumpFlood: Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/jumpflood.frag"))) { + var maxSteps: Int by parameters + var step: Int by parameters +} + +val encodePoints by lazy { EncodePoints() } +val jumpFlood by lazy { JumpFlood() } + +/** [points] is square and power of 2 */ +fun jumpFlood(points:ColorBuffer, coordinates:List) { + encodePoints.apply(points, coordinates[0]) + val exp = Math.ceil(Math.log(points.width.toDouble()) / Math.log(2.0)).toInt() + for (i in 0 until exp) { + jumpFlood.step = i + jumpFlood.apply(coordinates[i % 2], coordinates[(i + 1) % 2]) + + } + +} + +fun jumpFlood(drawer: Drawer, points:ColorBuffer): ColorBuffer { + + val dimension = Math.max(points.width, points.height) + val exp = Math.ceil(Math.log(dimension.toDouble()) / Math.log(2.0)).toInt() + val squareDim = Math.pow(2.0, exp.toDouble()).toInt() + + val rt = renderTarget(squareDim, squareDim) { + colorBuffer() + } + + val coordinates = + listOf(colorBuffer(squareDim, squareDim, type = ColorType.FLOAT32), + colorBuffer(squareDim, squareDim, type = ColorType.FLOAT32)) + + drawer.isolatedWithTarget(rt) { + drawer.ortho(rt) + drawer.view = Matrix44.IDENTITY + drawer.model = Matrix44.IDENTITY + drawer.image(points) + } + + jumpFlood(rt.colorBuffer(0), coordinates) + +// encodePoints.apply(rt.colorBuffer(0), coordinates[0]) +// +// +// for (i in 0 until exp) { +// jumpFlood.step = i +// jumpFlood.apply(coordinates[i % 2], coordinates[(i + 1) % 2]) +// +// } + + val final = renderTarget(points.width, points.height) { + colorBuffer(type = ColorType.FLOAT32) + } + + drawer.isolatedWithTarget(final) { + drawer.ortho(final) + drawer.view = Matrix44.IDENTITY + drawer.model = Matrix44.IDENTITY + drawer.image(coordinates[exp%2]) + + } + + rt.colorBuffer(0).destroy() + rt.detachColorBuffers() + rt.destroy() + + val fcb = final.colorBuffer(0) + final.detachColorBuffers() + final.destroy() + return fcb +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/encode-points.frag b/orx-jumpflood/src/main/resources/shaders/gl3/encode-points.frag new file mode 100644 index 00000000..865745f6 --- /dev/null +++ b/orx-jumpflood/src/main/resources/shaders/gl3/encode-points.frag @@ -0,0 +1,16 @@ +#version 330 core + +uniform sampler2D tex0; +in vec2 v_texCoord0; + +out vec4 o_color; + +void main() { + float ref = texture(tex0, v_texCoord0).r; + vec4 outc = vec4(-1.0, -1.0, 0.0, 1.0); + + if (ref > 0.5) { + outc.xy = v_texCoord0.xy; + } + o_color = outc; +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag b/orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag new file mode 100644 index 00000000..b076f883 --- /dev/null +++ b/orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag @@ -0,0 +1,39 @@ +#version 330 core +in vec2 v_texCoord0; + +uniform sampler2D tex0; +uniform int maxSteps; +uniform int step; + +out vec4 o_color; +void main() { + + float stepwidth = 1.0 / pow(2.0, step+1); + + float bestDistance = 9999.0; + vec2 bestCoord = vec2(-1.0); + vec2 bestColor = vec2(-1.0); + + vec2 is = vec2(1.0) / textureSize(tex0, 0); + + float found = 0.0; + for (int y = -1; y <= 1; ++y) { + for (int x = -1; x <= 1; ++x) { + vec2 sampleCoord = v_texCoord0 + vec2(stepwidth) * vec2(x,y); + vec4 data = texture( tex0, sampleCoord); + vec2 seedCoord = data.xy; + vec2 seedColor = data.zw; + float dist = length(seedCoord - v_texCoord0); + if ((seedCoord.x >= 0.0 || seedCoord.y >= 0.0) && dist < bestDistance) + { + found = 1.0; + bestDistance = dist; + bestCoord = seedCoord; + bestColor = seedColor; + } + } + } + + o_color = vec4(bestCoord, found, 1.0); + +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index da03ac5f..857b6acb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,4 @@ rootProject.name = 'orx' -include 'orx-kdtree' \ No newline at end of file +include 'orx-jumpflood', + 'orx-kdtree' \ No newline at end of file