diff --git a/build.gradle b/build.gradle index a3d41a46..3973c126 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,7 @@ def multiplatformModules = [ "orx-fx", "orx-gradient-descent", "orx-image-fit", + "orx-jumpflood", "orx-no-clear", "orx-noise", "orx-parameters", diff --git a/orx-jumpflood/build.gradle.kts b/orx-jumpflood/build.gradle.kts index da982d22..25b4aa5b 100644 --- a/orx-jumpflood/build.gradle.kts +++ b/orx-jumpflood/build.gradle.kts @@ -1,15 +1,69 @@ +import ScreenshotsHelper.collectScreenshots + plugins { - org.openrndr.extra.convention.`kotlin-jvm` + org.openrndr.extra.convention.`kotlin-multiplatform` } -dependencies { - implementation(project(":orx-fx")) - implementation(project(":orx-parameters")) - implementation(libs.openrndr.application) - implementation(libs.openrndr.math) - demoImplementation(project(":orx-noise")) - demoImplementation(project(":orx-jvm:orx-gui")) - demoImplementation(project(":orx-compositor")) - demoImplementation(libs.openrndr.svg) - demoImplementation(libs.openrndr.ffmpeg) +val embedShaders = tasks.register("embedShaders") { + inputDir.set(file("$projectDir/src/shaders/glsl")) + outputDir.set(file("$buildDir/generated/shaderKotlin")) + defaultPackage.set("org.openrndr.extra.jumpflood") + defaultVisibility.set("internal") + namePrefix.set("jf_") +}.get() + + +kotlin { + jvm { + @Suppress("UNUSED_VARIABLE") + val demo by compilations.getting { + // TODO: Move demos to /jvmDemo + defaultSourceSet { + kotlin.srcDir("src/demo/kotlin") + } + collectScreenshots { } + } + } + + sourceSets { + val shaderKotlin by creating { + this.kotlin.srcDir(embedShaders.outputDir) + } + + @Suppress("UNUSED_VARIABLE") + val commonMain by getting { + dependencies { + implementation(project(":orx-parameters")) + implementation(project(":orx-fx")) + implementation(libs.openrndr.application) + implementation(libs.openrndr.draw) + implementation(libs.openrndr.filter) + implementation(libs.kotlin.reflect) + api(shaderKotlin.kotlin) + } + dependsOn(shaderKotlin) + } + + + @Suppress("UNUSED_VARIABLE") + val jvmTest by getting { + dependencies { + implementation(libs.spek.dsl) + implementation(libs.kluent) + } + } + + @Suppress("UNUSED_VARIABLE") + val jvmDemo by getting { + dependencies { + implementation(project(":orx-color")) + implementation(project(":orx-fx")) + implementation(project(":orx-noise")) + implementation(project(":orx-jumpflood")) + implementation(project(":orx-compositor")) + implementation(project(":orx-jvm:orx-gui")) + implementation(libs.openrndr.svg) + } + } + } } \ No newline at end of file diff --git a/orx-jumpflood/src/commonMain/kotlin/ClusteredField.kt b/orx-jumpflood/src/commonMain/kotlin/ClusteredField.kt new file mode 100644 index 00000000..cbe56c91 --- /dev/null +++ b/orx-jumpflood/src/commonMain/kotlin/ClusteredField.kt @@ -0,0 +1,123 @@ +package org.openrndr.extra.jumpfill + +import org.openrndr.draw.* +import org.openrndr.extra.fx.blend.Passthrough +import org.openrndr.extra.parameters.BooleanParameter +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.math.Vector2 +import org.openrndr.shape.IntRectangle +import kotlin.math.ceil +import kotlin.math.log2 +import kotlin.math.max +import kotlin.math.pow + +@Description("Clustered field") +class ClusteredField(decodeMode: DecodeMode = DecodeMode.DIRECTION, + private val outputDistanceToContours: Boolean = true) : Filter1to1() { + @DoubleParameter("threshold", 0.0, 1.0) + var threshold = 0.5 + + @DoubleParameter("distance scale", 0.0, 1.0) + var distanceScale = 1.0 + + @BooleanParameter("normalized distance") + var normalizedDistance = false + + @BooleanParameter("unit direction") + var unitDirection = false + + @BooleanParameter("flip v direction") + var flipV = true + + private val encodeFilter = EncodePoints() + private var encoded: ColorBuffer? = null + private val contourFilter = IdContourPoints() + private var contoured: ColorBuffer? = null + private var jumpFlooder: JumpFlooder? = null + + private val decodeFilter = PixelDirection(decodeMode) + + private var fit: ColorBuffer? = null + + override fun apply(source: Array, target: Array) { + val advisedWidth = 2.0.pow(ceil(log2(source[0].effectiveWidth.toDouble()))).toInt() + val advisedHeight = 2.0.pow(ceil(log2(source[0].effectiveHeight.toDouble()))).toInt() + val advisedSize = max(advisedWidth, advisedHeight) + + fit?.let { + if (it.effectiveWidth != advisedSize || it.effectiveHeight != advisedSize) { + it.destroy() + fit = null + encoded?.destroy() + encoded = null + contoured?.destroy() + contoured = null + jumpFlooder?.destroy() + jumpFlooder = null + } + } + + if (fit == null) { + fit = colorBuffer(advisedSize, advisedSize, type=ColorType.FLOAT32) + } + + source[0].copyTo( + fit!!, + sourceRectangle = IntRectangle(0, 0, source[0].effectiveWidth, source[0].effectiveHeight), + targetRectangle = IntRectangle( + 0, + advisedSize - source[0].effectiveHeight, + source[0].effectiveWidth, + source[0].effectiveHeight + ) + ) + + if (encoded == null) { + encoded = colorBuffer(advisedSize, advisedSize, format = ColorFormat.RGBa, type = ColorType.FLOAT32) + } + if (jumpFlooder == null) { + jumpFlooder = JumpFlooder(advisedSize, advisedSize, encodePoints = Passthrough()) + } + + if (outputDistanceToContours && contoured == null) { + contoured = colorBuffer(advisedSize, advisedSize, type = ColorType.FLOAT32) + } + + encodeFilter.apply(fit!!, encoded!!) + var result = jumpFlooder!!.jumpFlood(encoded!!) + + if (outputDistanceToContours) { + contourFilter.apply(result, contoured!!) + result = jumpFlooder!!.jumpFlood(contoured!!) + } + + decodeFilter.outputIds = true + decodeFilter.originalSize = Vector2(source[0].width.toDouble(), source[0].height.toDouble()) + decodeFilter.distanceScale = distanceScale + decodeFilter.normalizedDistance = normalizedDistance + decodeFilter.unitDirection = unitDirection + decodeFilter.flipV = flipV + decodeFilter.apply(arrayOf(result, encoded!!), arrayOf(result)) + + result.copyTo( + target[0], + sourceRectangle = IntRectangle( + 0, + advisedSize - source[0].effectiveHeight, + source[0].effectiveWidth, + source[0].effectiveHeight + ), + targetRectangle = IntRectangle(0, 0, source[0].effectiveWidth, source[0].effectiveHeight) + ) + } + + override fun destroy() { + encodeFilter.destroy() + contourFilter.destroy() + fit?.destroy() + encoded?.destroy() + contoured?.destroy() + jumpFlooder?.destroy() + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/DirectionalField.kt b/orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt similarity index 84% rename from orx-jumpflood/src/main/kotlin/DirectionalField.kt rename to orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt index bcdea827..7edaa435 100644 --- a/orx-jumpflood/src/main/kotlin/DirectionalField.kt +++ b/orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt @@ -1,9 +1,7 @@ package org.openrndr.extra.jumpfill -import org.openrndr.draw.ColorBuffer -import org.openrndr.draw.ColorFormat -import org.openrndr.draw.Filter -import org.openrndr.draw.colorBuffer +import org.openrndr.draw.* +import org.openrndr.extra.parameters.BooleanParameter import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.math.Vector2 @@ -14,13 +12,22 @@ import kotlin.math.max import kotlin.math.pow @Description("Directional field") -class DirectionalField : Filter() { +class DirectionalField : Filter1to1() { @DoubleParameter("threshold", 0.0, 1.0) var threshold = 0.5 @DoubleParameter("distance scale", 0.0, 1.0) var distanceScale = 1.0 + @BooleanParameter("normalized distance") + var normalizedDistance = false + + @BooleanParameter("unit direction") + var unitDirection = false + + @BooleanParameter("flip v direction") + var flipV = true + private val thresholdFilter = Threshold() private var thresholded: ColorBuffer? = null private val contourFilter = ContourPoints() @@ -71,8 +78,11 @@ class DirectionalField : Filter() { thresholdFilter.apply(fit!!, thresholded!!) contourFilter.apply(thresholded!!, contoured!!) val result = jumpFlooder!!.jumpFlood(contoured!!) - decodeFilter.originalSize = Vector2(advisedSize.toDouble(), advisedSize.toDouble()) + decodeFilter.originalSize = Vector2(source[0].width.toDouble(), source[0].height.toDouble()) decodeFilter.distanceScale = distanceScale + decodeFilter.normalizedDistance = normalizedDistance + decodeFilter.unitDirection = unitDirection + decodeFilter.flipV = flipV decodeFilter.apply(arrayOf(result, thresholded!!), arrayOf(result)) result.copyTo(target[0], sourceRectangle = IntRectangle(0, advisedSize-source[0].effectiveHeight, source[0].effectiveWidth, source[0].effectiveHeight), diff --git a/orx-jumpflood/src/main/kotlin/DistanceField.kt b/orx-jumpflood/src/commonMain/kotlin/DistanceField.kt similarity index 81% rename from orx-jumpflood/src/main/kotlin/DistanceField.kt rename to orx-jumpflood/src/commonMain/kotlin/DistanceField.kt index 72e207fe..622d2732 100644 --- a/orx-jumpflood/src/main/kotlin/DistanceField.kt +++ b/orx-jumpflood/src/commonMain/kotlin/DistanceField.kt @@ -1,9 +1,6 @@ package org.openrndr.extra.jumpfill -import org.openrndr.draw.ColorBuffer -import org.openrndr.draw.ColorFormat -import org.openrndr.draw.Filter -import org.openrndr.draw.colorBuffer +import org.openrndr.draw.* import org.openrndr.extra.parameters.BooleanParameter import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter @@ -15,7 +12,7 @@ import kotlin.math.max import kotlin.math.pow @Description("Distance field") -class DistanceField : Filter() { +class DistanceField : Filter1to1() { @DoubleParameter("threshold", 0.0, 1.0) var threshold = 0.5 @@ -63,27 +60,25 @@ class DistanceField : Filter() { ) if (thresholded == null) { - thresholded = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) + thresholded = colorBuffer(advisedSize, advisedSize, format = ColorFormat.R) } if (contoured == null) { - contoured = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) + contoured = colorBuffer(advisedSize, advisedSize, format = ColorFormat.R) } if (jumpFlooder == null) { - jumpFlooder = JumpFlooder(target[0].width, target[0].height) + jumpFlooder = JumpFlooder(advisedSize, advisedSize) } + thresholdFilter.threshold = threshold thresholdFilter.apply(fit!!, thresholded!!) contourFilter.apply(thresholded!!, contoured!!) val result = jumpFlooder!!.jumpFlood(contoured!!) - decodeFilter.signedDistance = signedDistance - decodeFilter.originalSize = Vector2(advisedSize.toDouble(), advisedSize.toDouble()) + decodeFilter.originalSize = Vector2(source[0].width.toDouble(), source[0].height.toDouble()) decodeFilter.distanceScale = distanceScale - decodeFilter.signedBit = false decodeFilter.apply(arrayOf(result, thresholded!!), arrayOf(result)) result.copyTo(target[0], sourceRectangle = IntRectangle(0, advisedSize-source[0].effectiveHeight, source[0].effectiveWidth, source[0].effectiveHeight), targetRectangle = IntRectangle(0, 0, source[0].effectiveWidth, source[0].effectiveHeight) ) - } } \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/JumpFlood.kt b/orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt similarity index 57% rename from orx-jumpflood/src/main/kotlin/JumpFlood.kt rename to orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt index 18896523..323583cb 100644 --- a/orx-jumpflood/src/main/kotlin/JumpFlood.kt +++ b/orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt @@ -3,46 +3,61 @@ package org.openrndr.extra.jumpfill import org.openrndr.color.ColorRGBa import org.openrndr.draw.* import org.openrndr.extra.fx.blend.Passthrough -import org.openrndr.extra.parameters.Description -import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.extra.jumpflood.* import org.openrndr.math.Vector2 -import org.openrndr.resourceUrl -import kotlin.math.ceil -import kotlin.math.max -import kotlin.math.pow +import kotlin.math.* -class EncodePoints : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/encode-points.frag"))) +class EncodePoints : Filter(filterShaderFromCode(jf_encode_points, "encode-points")) -class EncodeSubpixel : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/encode-subpixel.frag"))) { +class EncodeSubpixel : Filter(filterShaderFromCode(jf_encode_subpixel, "encode-subpixel")) { var threshold by parameters + init { threshold = 0.5 } - } -class JumpFlood : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/jumpflood.frag"))) { +class JumpFlood : Filter(filterShaderFromCode(jf_jumpflood, "jumpflood")) { var maxSteps: Int by parameters var step: Int by parameters } -class PixelDirection : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/pixel-direction.frag"))) { +enum class DecodeMode(val shaderDefine: String) { + DISTANCE("OUTPUT_DISTANCE"), + DIRECTION("OUTPUT_DIRECTION") +} + +class PixelDirection(val decodeMode: DecodeMode = DecodeMode.DIRECTION) : + Filter( + filterShaderFromCode( + "#define ${decodeMode.shaderDefine}\n $jf_pixel_direction", + "pixel-direction") + ) { var distanceScale: Double by parameters var originalSize: Vector2 by parameters + var normalizedDistance: Boolean by parameters + var unitDirection: Boolean by parameters + var flipV: Boolean by parameters + var outputIds: Boolean by parameters + init { distanceScale = 1.0 originalSize = Vector2(512.0, 512.0) - + normalizedDistance = false + unitDirection = false + flipV = true + outputIds = false } } -class PixelDistance : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/pixel-distance.frag"))) { +class PixelDistance : Filter(filterShaderFromCode(jf_pixel_distance, "pixel-distance")) { var distanceScale: Double by parameters var originalSize: Vector2 by parameters var signedBit: Boolean by parameters var signedDistance: Boolean by parameters + init { distanceScale = 1.0 originalSize = Vector2(512.0, 512.0) @@ -51,8 +66,12 @@ class PixelDistance : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/pixel } } -class ContourPoints : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/contour-points.frag"))) -class Threshold : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/threshold.frag"))) { +class ContourPoints : Filter(filterShaderFromCode(jf_contour_points, "contour-points")) + +class IdContourPoints : Filter(filterShaderFromCode(jf_id_contours, "id-contour-points")) + + +class Threshold : Filter(filterShaderFromCode(jf_threshold, "threshold")) { var threshold: Double by parameters init { @@ -60,7 +79,7 @@ class Threshold : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/threshold } } -class AlphaThreshold : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/alpha-threshold.frag"))) { +class AlphaThreshold : Filter(filterShaderFromCode(jf_alpha_threshold, "alpha-threshold")) { var threshold: Double by parameters init { @@ -70,23 +89,27 @@ class AlphaThreshold : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/alph private val encodePoints by lazy { persistent { EncodePoints() } } -private val pixelDistance by lazy { persistent { PixelDistance() } } +private val pixelDistance by lazy { persistent { PixelDistance() } } private val pixelDirection by lazy { persistent { PixelDirection() } } private val contourPoints by lazy { persistent { ContourPoints() } } -private val threshold by lazy { persistent { Threshold() } } +private val threshold by lazy { persistent { Threshold() } } private val passthrough by lazy { persistent { Passthrough() } } -class JumpFlooder(val width: Int, val height: Int, format: ColorFormat = ColorFormat.RGB, type: ColorType = ColorType.FLOAT32, - val encodePoints: Filter = EncodePoints()) { +class JumpFlooder( + val width: Int, val height: Int, format: ColorFormat = ColorFormat.RGBa, type: ColorType = ColorType.FLOAT32, + val encodePoints: Filter = EncodePoints() +) { private val dimension = max(width, height) - private val exp = ceil(Math.log(dimension.toDouble()) / Math.log(2.0)).toInt() + private val exp = ceil(log2(dimension.toDouble())).toInt() val squareDim = 2.0.pow(exp.toDouble()).toInt() val jumpFlood = JumpFlood() private val coordinates = - listOf(colorBuffer(squareDim, squareDim, format = format, type = type), - colorBuffer(squareDim, squareDim, format = format, type = type)) + listOf( + colorBuffer(squareDim, squareDim, format = format, type = type), + colorBuffer(squareDim, squareDim, format = format, type = type) + ) val final = colorBuffer(squareDim, squareDim, format = format, type = type) @@ -122,9 +145,10 @@ class JumpFlooder(val width: Int, val height: Int, format: ColorFormat = ColorFo } } -private fun encodeDecodeBitmap(preprocess: Filter, decoder: Filter, bitmap: ColorBuffer, - jumpFlooder: JumpFlooder? = null, - result: ColorBuffer? = null +private fun encodeDecodeBitmap( + preprocess: Filter, decoder: Filter, bitmap: ColorBuffer, + jumpFlooder: JumpFlooder? = null, + result: ColorBuffer? = null ): ColorBuffer { val _jumpFlooder = jumpFlooder ?: JumpFlooder(bitmap.width, bitmap.height) val _result = result ?: colorBuffer(bitmap.width, bitmap.height, type = ColorType.FLOAT16) @@ -145,17 +169,20 @@ private fun encodeDecodeBitmap(preprocess: Filter, decoder: Filter, bitmap: Colo * Creates a color buffer containing the coordinates of the nearest centroids * @param bitmap a ColorBuffer with centroids in red (> 0) */ -fun centroidsFromBitmap(bitmap: ColorBuffer, - jumpFlooder: JumpFlooder? = null, - result: ColorBuffer? = null +fun centroidsFromBitmap( + bitmap: ColorBuffer, + jumpFlooder: JumpFlooder? = null, + result: ColorBuffer? = null ): ColorBuffer = encodeDecodeBitmap(passthrough, passthrough, bitmap, jumpFlooder, result) -fun distanceFieldFromBitmap(bitmap: ColorBuffer, - jumpFlooder: JumpFlooder? = null, - result: ColorBuffer? = null +fun distanceFieldFromBitmap( + bitmap: ColorBuffer, + jumpFlooder: JumpFlooder? = null, + result: ColorBuffer? = null ): ColorBuffer = encodeDecodeBitmap(contourPoints, pixelDistance, bitmap, jumpFlooder, result) -fun directionFieldFromBitmap(bitmap: ColorBuffer, - jumpFlooder: JumpFlooder? = null, - result: ColorBuffer? = null +fun directionFieldFromBitmap( + bitmap: ColorBuffer, + jumpFlooder: JumpFlooder? = null, + result: ColorBuffer? = null ): ColorBuffer = encodeDecodeBitmap(contourPoints, pixelDirection, bitmap, jumpFlooder, result) \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/draw/SDFDraw.kt b/orx-jumpflood/src/commonMain/kotlin/draw/SDFDraw.kt similarity index 85% rename from orx-jumpflood/src/main/kotlin/draw/SDFDraw.kt rename to orx-jumpflood/src/commonMain/kotlin/draw/SDFDraw.kt index 55ba9f6d..cfbb43a1 100644 --- a/orx-jumpflood/src/main/kotlin/draw/SDFDraw.kt +++ b/orx-jumpflood/src/commonMain/kotlin/draw/SDFDraw.kt @@ -3,14 +3,14 @@ package org.openrndr.extra.jumpfill.draw import org.openrndr.color.ColorRGBa import org.openrndr.draw.ColorBuffer import org.openrndr.draw.Filter -import org.openrndr.draw.filterShaderFromUrl +import org.openrndr.draw.filterShaderFromCode +import org.openrndr.extra.jumpflood.jf_sdf_stroke_fill import org.openrndr.extra.parameters.ColorParameter import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter -import org.openrndr.resourceUrl @Description("SDF stroke and fill") -class SDFStrokeFill : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/draw/sdf-stroke-fill.frag"))) { +class SDFStrokeFill : Filter(filterShaderFromCode(jf_sdf_stroke_fill, "sdf-stroke-fill")) { @DoubleParameter("stroke weight", 0.0, 20.0, order = 0) var strokeWeight: Double by parameters diff --git a/orx-jumpflood/src/main/kotlin/fx/InnerBevel.kt b/orx-jumpflood/src/commonMain/kotlin/fx/InnerBevel.kt similarity index 93% rename from orx-jumpflood/src/main/kotlin/fx/InnerBevel.kt rename to orx-jumpflood/src/commonMain/kotlin/fx/InnerBevel.kt index 750f7a01..61d13dc8 100644 --- a/orx-jumpflood/src/main/kotlin/fx/InnerBevel.kt +++ b/orx-jumpflood/src/commonMain/kotlin/fx/InnerBevel.kt @@ -4,12 +4,13 @@ import org.openrndr.draw.* import org.openrndr.extra.jumpfill.EncodeSubpixel import org.openrndr.extra.jumpfill.JumpFlooder import org.openrndr.extra.jumpfill.PixelDirection +import org.openrndr.extra.jumpflood.jf_inner_bevel import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.math.Vector2 import org.openrndr.resourceUrl -private class InnerBevelFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/inner-bevel.frag"))) { +private class InnerBevelFilter : Filter(filterShaderFromCode(jf_inner_bevel, "inner-bevel")) { var angle: Double by parameters var width: Double by parameters diff --git a/orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt b/orx-jumpflood/src/commonMain/kotlin/fx/InnerGlow.kt similarity index 93% rename from orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt rename to orx-jumpflood/src/commonMain/kotlin/fx/InnerGlow.kt index adf7fe8a..d0b50bb7 100644 --- a/orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt +++ b/orx-jumpflood/src/commonMain/kotlin/fx/InnerGlow.kt @@ -5,13 +5,14 @@ import org.openrndr.draw.* import org.openrndr.extra.jumpfill.EncodeSubpixel import org.openrndr.extra.jumpfill.JumpFlooder import org.openrndr.extra.jumpfill.PixelDirection +import org.openrndr.extra.jumpflood.jf_inner_glow import org.openrndr.extra.parameters.ColorParameter import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.math.Vector2 import org.openrndr.resourceUrl -private class InnerGlowFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/inner-glow.frag"))) { +private class InnerGlowFilter : Filter(filterShaderFromCode(jf_inner_glow, "inner-glow")) { var angle: Double by parameters var width: Double by parameters @@ -31,7 +32,7 @@ private class InnerGlowFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders } @Description("Inner glow") -class InnerGlow : Filter() { +class InnerGlow : Filter1to1() { @DoubleParameter("width", 0.0, 50.0) var width = 5.0 diff --git a/orx-jumpflood/src/main/kotlin/fx/Inpaint.kt b/orx-jumpflood/src/commonMain/kotlin/fx/Inpaint.kt similarity index 94% rename from orx-jumpflood/src/main/kotlin/fx/Inpaint.kt rename to orx-jumpflood/src/commonMain/kotlin/fx/Inpaint.kt index 0fe27f80..b2db47c5 100644 --- a/orx-jumpflood/src/main/kotlin/fx/Inpaint.kt +++ b/orx-jumpflood/src/commonMain/kotlin/fx/Inpaint.kt @@ -4,12 +4,13 @@ import org.openrndr.draw.* import org.openrndr.extra.jumpfill.EncodeSubpixel import org.openrndr.extra.jumpfill.JumpFlooder import org.openrndr.extra.jumpfill.PixelDirection +import org.openrndr.extra.jumpflood.jf_inpaint import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.math.Vector2 import org.openrndr.resourceUrl -private class InpaintFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/inpaint.frag"))) { +private class InpaintFilter : Filter(filterShaderFromCode(jf_inpaint, "inpaint")) { var noise: Double by parameters var imageOpacity: Double by parameters diff --git a/orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt b/orx-jumpflood/src/commonMain/kotlin/fx/OuterGlow.kt similarity index 94% rename from orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt rename to orx-jumpflood/src/commonMain/kotlin/fx/OuterGlow.kt index a48af6a1..c2181409 100644 --- a/orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt +++ b/orx-jumpflood/src/commonMain/kotlin/fx/OuterGlow.kt @@ -5,13 +5,14 @@ import org.openrndr.draw.* import org.openrndr.extra.jumpfill.EncodeSubpixel import org.openrndr.extra.jumpfill.JumpFlooder import org.openrndr.extra.jumpfill.PixelDirection +import org.openrndr.extra.jumpflood.jf_outer_glow import org.openrndr.extra.parameters.ColorParameter import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.math.Vector2 import org.openrndr.resourceUrl -private class OuterGlowFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/outer-glow.frag"))) { +private class OuterGlowFilter : Filter(filterShaderFromCode(jf_outer_glow, "outer-glow")) { var angle: Double by parameters var width: Double by parameters diff --git a/orx-jumpflood/src/main/kotlin/fx/Skeleton.kt b/orx-jumpflood/src/commonMain/kotlin/fx/Skeleton.kt similarity index 95% rename from orx-jumpflood/src/main/kotlin/fx/Skeleton.kt rename to orx-jumpflood/src/commonMain/kotlin/fx/Skeleton.kt index 33bc1e94..60be4e27 100644 --- a/orx-jumpflood/src/main/kotlin/fx/Skeleton.kt +++ b/orx-jumpflood/src/commonMain/kotlin/fx/Skeleton.kt @@ -3,6 +3,7 @@ package org.openrndr.extra.jumpfill.fx import org.openrndr.color.ColorRGBa import org.openrndr.draw.* import org.openrndr.extra.jumpfill.* +import org.openrndr.extra.jumpflood.jf_skeleton import org.openrndr.extra.parameters.ColorParameter import org.openrndr.extra.parameters.Description @@ -10,7 +11,7 @@ import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.math.Vector2 import org.openrndr.resourceUrl -private class SkeletonFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/skeleton.frag"))) { +private class SkeletonFilter : Filter(filterShaderFromCode(jf_skeleton, "skeleton")) { var skeletonColor: ColorRGBa by parameters var foregroundColor: ColorRGBa by parameters var backgroundColor: ColorRGBa by parameters diff --git a/orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt b/orx-jumpflood/src/commonMain/kotlin/fx/StraightSkeleton.kt similarity index 94% rename from orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt rename to orx-jumpflood/src/commonMain/kotlin/fx/StraightSkeleton.kt index 54805a71..87acf2e8 100644 --- a/orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt +++ b/orx-jumpflood/src/commonMain/kotlin/fx/StraightSkeleton.kt @@ -3,6 +3,7 @@ package org.openrndr.extra.jumpfill.fx import org.openrndr.color.ColorRGBa import org.openrndr.draw.* import org.openrndr.extra.jumpfill.* +import org.openrndr.extra.jumpflood.jf_straight_skeleton import org.openrndr.extra.parameters.ColorParameter import org.openrndr.extra.parameters.Description @@ -11,7 +12,7 @@ import org.openrndr.math.Vector2 import org.openrndr.resourceUrl import kotlin.math.sqrt -private class StraightSkeletonFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/straight-skeleton.frag"))) { +private class StraightSkeletonFilter : Filter(filterShaderFromCode(jf_straight_skeleton, "straight-skeleton")) { var angleThreshold: Double by parameters var skeletonColor: ColorRGBa by parameters var foregroundColor: ColorRGBa by parameters diff --git a/orx-jumpflood/src/main/kotlin/ops/SDFOps.kt b/orx-jumpflood/src/commonMain/kotlin/ops/SDFOps.kt similarity index 78% rename from orx-jumpflood/src/main/kotlin/ops/SDFOps.kt rename to orx-jumpflood/src/commonMain/kotlin/ops/SDFOps.kt index f7055ce5..b4386fb9 100644 --- a/orx-jumpflood/src/main/kotlin/ops/SDFOps.kt +++ b/orx-jumpflood/src/commonMain/kotlin/ops/SDFOps.kt @@ -3,12 +3,13 @@ package org.openrndr.extra.jumpfill.ops import org.openrndr.draw.ColorBuffer import org.openrndr.draw.ColorType import org.openrndr.draw.Filter -import org.openrndr.draw.filterShaderFromUrl +import org.openrndr.draw.filterShaderFromCode +import org.openrndr.extra.jumpflood.* import org.openrndr.extra.parameters.Description import org.openrndr.extra.parameters.DoubleParameter import org.openrndr.resourceUrl -class SDFSmoothUnion : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-smooth-union.frag"))) { +class SDFSmoothUnion : Filter(filterShaderFromCode(jf_sdf_smooth_union, "sdf-smooth-union")) { var radius: Double by parameters init { @@ -23,7 +24,7 @@ class SDFSmoothUnion : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/ } } -class SDFSmoothIntersection : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-smooth-intersection.frag"))) { +class SDFSmoothIntersection : Filter(filterShaderFromCode(jf_sdf_smooth_intersection, "sdf-smooth-intersection")) { var radius: Double by parameters init { @@ -38,7 +39,7 @@ class SDFSmoothIntersection : Filter(filterShaderFromUrl(resourceUrl("/shaders/g } } @Description("SDF smooth difference") -class SDFSmoothDifference : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-smooth-difference.frag"))) { +class SDFSmoothDifference : Filter(filterShaderFromCode(jf_sdf_smooth_difference, "sdf-smooth-differecnce")) { @DoubleParameter("smooth radius", 0.0, 200.0, order = 0) var radius: Double by parameters @@ -54,7 +55,7 @@ class SDFSmoothDifference : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3 } } -class SDFRound : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-round.frag"))) { +class SDFRound : Filter(filterShaderFromCode(jf_sdf_round, "sdf-round")) { @DoubleParameter("rounding radius", 0.0, 200.0, order = 0) var radius: Double by parameters @@ -70,7 +71,7 @@ class SDFRound : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-ro } } -class SDFOnion : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-onion.frag"))) { +class SDFOnion : Filter(filterShaderFromCode(jf_sdf_onion, "sdf-onion")) { var radius: Double by parameters init { @@ -85,7 +86,7 @@ class SDFOnion : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-on } } -class SDFBlend : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-blend.frag"))) { +class SDFBlend : Filter(filterShaderFromCode(jf_sdf_blend, "sdf-blend")) { var factor: Double by parameters init { @@ -98,5 +99,4 @@ class SDFBlend : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/ops/sdf-bl } super.apply(source, target) } - } diff --git a/orx-jumpflood/src/demo/kotlin/DemoInnerGlow01.kt b/orx-jumpflood/src/demo/kotlin/DemoInnerGlow01.kt index f8efa0ca..7a0a485b 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoInnerGlow01.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoInnerGlow01.kt @@ -1,6 +1,5 @@ import org.openrndr.application import org.openrndr.color.ColorRGBa -import org.openrndr.extensions.SingleScreenshot import org.openrndr.extra.compositor.compose import org.openrndr.extra.compositor.draw import org.openrndr.extra.compositor.layer @@ -10,11 +9,6 @@ import org.openrndr.extra.jumpfill.fx.InnerGlow fun main() = application { program { - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } val c = compose { layer { post(Checkers()) diff --git a/orx-jumpflood/src/demo/kotlin/DemoInnerGlow02.kt b/orx-jumpflood/src/demo/kotlin/DemoInnerGlow02.kt index dcdec0ab..95c16b1e 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoInnerGlow02.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoInnerGlow02.kt @@ -10,11 +10,6 @@ import org.openrndr.extra.jumpfill.fx.InnerGlow fun main() = application { program { - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } val c = compose { layer { post(Checkers()) diff --git a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF01.kt b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF01.kt index b57b944d..1284d39a 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF01.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF01.kt @@ -20,11 +20,6 @@ fun main() { sdf.setShapes(shapes) sdf.apply(emptyArray(), df) - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } extend { if(mouse.pressedButtons.isEmpty()) drawer.image(df) diff --git a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF02.kt b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF02.kt index c3fe0e1b..ab181b57 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF02.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF02.kt @@ -33,12 +33,6 @@ fun main() { val strokeFill = SDFStrokeFill() - // -- this block is for automation purposes only - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } extend { drawer.clear(ColorRGBa.PINK) diff --git a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF03.kt b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF03.kt index cd50ab3b..2d0b26f2 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF03.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF03.kt @@ -8,7 +8,6 @@ import org.openrndr.extra.fx.distort.FluidDistort import org.openrndr.extra.jumpfill.ShapeSDF import org.openrndr.extra.jumpfill.draw.SDFStrokeFill import org.openrndr.extra.jumpfill.ops.* -import org.openrndr.math.transforms.transform import org.openrndr.svg.loadSVG fun main() { @@ -36,11 +35,6 @@ fun main() { val strokeFill = SDFStrokeFill() - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } extend { drawer.clear(ColorRGBa.PINK) diff --git a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF04.kt b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF04.kt index f98a6074..bba349ae 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF04.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF04.kt @@ -40,11 +40,6 @@ fun main() { val strokeFill = SDFStrokeFill() gui.add(perturb) - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } extend(gui) extend { drawer.clear(ColorRGBa.PINK) diff --git a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF05.kt b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF05.kt index 2848d279..86c04844 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoShapeSDF05.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoShapeSDF05.kt @@ -3,7 +3,6 @@ import org.openrndr.color.ColorRGBa import org.openrndr.draw.ColorFormat import org.openrndr.draw.ColorType import org.openrndr.draw.colorBuffer -import org.openrndr.extensions.SingleScreenshot import org.openrndr.extra.fx.distort.Perturb import org.openrndr.extra.gui.GUI import org.openrndr.extra.jumpfill.ShapeSDF @@ -49,12 +48,6 @@ fun main() { gui.add(strokeFill) gui.add(difference) - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } - extend(gui) extend { drawer.clear(ColorRGBa.PINK) diff --git a/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt b/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt index cbdb5d89..7895d5b9 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt @@ -22,11 +22,6 @@ fun main() { colorBuffer() } val field = input.colorBuffer(0).createEquivalent(type = ColorType.FLOAT32) - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } extend { drawer.isolatedWithTarget(input) { // -- draw something interesting diff --git a/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt b/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt index 9842bdf3..2f3dd70b 100644 --- a/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt +++ b/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt @@ -5,7 +5,6 @@ import org.openrndr.draw.createEquivalent import org.openrndr.draw.isolatedWithTarget import org.openrndr.draw.renderTarget -import org.openrndr.extensions.SingleScreenshot import org.openrndr.extra.jumpfill.fx.StraightSkeleton import org.openrndr.extra.noise.simplex @@ -16,12 +15,6 @@ fun main() { height = 720 } program { - if (System.getProperty("takeScreenshot") == "true") { - extend(SingleScreenshot()) { - this.outputFile = System.getProperty("screenshotPath") - } - } - val straightSkeleton = StraightSkeleton() val input = renderTarget(width, height) { colorBuffer() diff --git a/orx-jumpflood/src/demo/kotlin/DemoVoronoi01.kt b/orx-jumpflood/src/demo/kotlin/DemoVoronoi01.kt new file mode 100644 index 00000000..062f3cc1 --- /dev/null +++ b/orx-jumpflood/src/demo/kotlin/DemoVoronoi01.kt @@ -0,0 +1,68 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.extra.fx.blend.Passthrough +import org.openrndr.extra.jumpfill.EncodePoints +import org.openrndr.extra.jumpfill.IdContourPoints +import org.openrndr.extra.jumpfill.JumpFlooder +import kotlin.math.cos + +fun main() = application { + configure { + width = 512 + height = 512 + } + program { + val rt = renderTarget(512, 512, 1.0) { + colorBuffer(type = ColorType.FLOAT32) + } + val encoder = EncodePoints() + val jf = JumpFlooder(512, 512, encodePoints = Passthrough()) + val jf2 = JumpFlooder(512, 512, encodePoints = Passthrough()) + val idcontours = IdContourPoints() + val contoured = colorBuffer(512, 512, type = ColorType.FLOAT32) + extend { + fun plot(x: Double, y: Double, id: Double) { + drawer.fill = ColorRGBa(id, 0.0, 0.0, 1.0) + drawer.point(x, y) + } + + drawer.isolatedWithTarget(rt) { + drawer.clear(ColorRGBa(-1.0, -1.0, -1.0, 0.0)) + val o = cos(seconds) * 200.0 + 200.0 + + for (i in 0 until 20) { + plot(o + 100.0 + i * 4, 100.0, 0.25) + } + + for (i in 0 until 20) { + plot(200.0 + i * 4, 150.0 + i, 0.5) + } + for (i in 0 until 20) { + plot(300.0 + i * 4, 250.0 + i, 0.7) + } + + for (i in 0 until 20) { + plot(400.0 + i * 4, 250.0 + i, 0.75) + } + } + encoder.apply(rt.colorBuffer(0), rt.colorBuffer(0)) + val flooded = jf.jumpFlood(rt.colorBuffer(0)) + drawer.image(flooded) + idcontours.apply(flooded, contoured) + drawer.image(contoured) + val flooded2 = jf2.jumpFlood(contoured) + + drawer.image(flooded2, 512.0, 0.0) + + drawer.shadeStyle = shadeStyle { + fragmentTransform = """ + float d = length(va_texCoord0.xy - x_fill.xy); + x_fill = vec4(d,d,x_fill.z, 1.0); + """.trimIndent() + } + drawer.image(flooded2, 0.0, 0.0) + + } + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/demo/kotlin/DemoVoronoi02.kt b/orx-jumpflood/src/demo/kotlin/DemoVoronoi02.kt new file mode 100644 index 00000000..8e8d93cb --- /dev/null +++ b/orx-jumpflood/src/demo/kotlin/DemoVoronoi02.kt @@ -0,0 +1,55 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.extra.jumpfill.* +import kotlin.math.cos + +fun main() = application { + configure { + width = 512 + height = 512 + } + program { + val rt = renderTarget(512, 512, 1.0) { + colorBuffer(type = ColorType.FLOAT32) + } + + val flowfield = colorBuffer(512, 512, type = ColorType.FLOAT32) + val cluster = ClusteredField(decodeMode = DecodeMode.DISTANCE, outputDistanceToContours = true) + + + cluster.normalizedDistance = true + + extend { + fun plot(x: Double, y: Double, id: Double) { + drawer.fill = ColorRGBa(id, 0.0, 0.0, 1.0) + drawer.point(x, y) + } + + drawer.isolatedWithTarget(rt) { + drawer.clear(ColorRGBa(-1.0, -1.0, -1.0, 0.0)) + val o = cos(seconds) * 200.0 + 200.0 + + for (i in 0 until 20) { + plot(o + 100.0 + i * 4, 100.0, 0.25) + } + + for (i in 0 until 20) { + plot(200.0 + i * 4, 150.0 + i, 0.5) + } + for (i in 0 until 20) { + plot(300.0 + i * 4, 250.0 + i, 0.7) + } + + for (i in 0 until 20) { + plot(400.0 + i * 4, 250.0 + i, 0.75) + } + } + cluster.apply(rt.colorBuffer(0), flowfield) + drawer.drawStyle.colorMatrix = tint(ColorRGBa(10.0, 10.0, 1.0)) + drawer.image(flowfield) + + + } + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/demo/kotlin/DemoVoronoi03.kt b/orx-jumpflood/src/demo/kotlin/DemoVoronoi03.kt new file mode 100644 index 00000000..35d36042 --- /dev/null +++ b/orx-jumpflood/src/demo/kotlin/DemoVoronoi03.kt @@ -0,0 +1,43 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.extra.fx.blend.Passthrough +import org.openrndr.extra.jumpfill.* +import org.openrndr.extra.noise.scatter +import org.openrndr.extra.noise.uniformRing +import org.openrndr.math.Vector2 + +fun main() = application { + configure { + width = 720 + height = 720 + } + program { + val rt = renderTarget(720, 720, 1.0) { + colorBuffer(type = ColorType.FLOAT32) + } + val flowfield = colorBuffer(width, height, type = ColorType.FLOAT32) + val cluster = ClusteredField(decodeMode = DecodeMode.DISTANCE, outputDistanceToContours = true) + + cluster.normalizedDistance = true + + extend { + drawer.isolatedWithTarget(rt) { + drawer.ortho(rt) + drawer.clear(ColorRGBa(-1.0, -1.0, -1.0, 0.0)) + val points = drawer.bounds.scatter(20.0) + drawer.points { + for ((index, point) in points.withIndex()) { + fill = ColorRGBa((index+1.0)/points.size, 0.0, 0.0, 1.0) + for (i in 0 until 30) { + point(point + Vector2.uniformRing(15.0, 25.0)* Vector2(1.0, 1.0)) + } + } + } + } + cluster.apply(rt.colorBuffer(0), flowfield) + drawer.drawStyle.colorMatrix = tint(ColorRGBa(100.0, 100.0, 0.0)) + drawer.image(flowfield) + } + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/ShapeSDF.kt b/orx-jumpflood/src/jvmMain/kotlin/ShapeSDF.kt similarity index 91% rename from orx-jumpflood/src/main/kotlin/ShapeSDF.kt rename to orx-jumpflood/src/jvmMain/kotlin/ShapeSDF.kt index 9beb4dd2..76d99026 100644 --- a/orx-jumpflood/src/main/kotlin/ShapeSDF.kt +++ b/orx-jumpflood/src/jvmMain/kotlin/ShapeSDF.kt @@ -1,6 +1,7 @@ package org.openrndr.extra.jumpfill import org.openrndr.draw.* +import org.openrndr.extra.jumpflood.jf_shape_sdf import org.openrndr.extra.parameters.BooleanParameter import org.openrndr.math.Matrix44 import org.openrndr.math.Vector4 @@ -9,7 +10,7 @@ import org.openrndr.shape.Shape import org.openrndr.shape.ShapeContour -class ShapeSDF : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/shape-sdf.frag"))) { +class ShapeSDF : Filter(filterShaderFromCode(jf_shape_sdf, "shape-sdf")) { private val fromBuffer = bufferTexture(1024, format = ColorFormat.RGBa, type = ColorType.FLOAT32) private val toBuffer = bufferTexture(1024, format = ColorFormat.RGBa, type = ColorType.FLOAT32) private var segmentCount = 0 @@ -23,10 +24,10 @@ class ShapeSDF : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/shape-sdf. private var modelViewMatrixInverse by parameters var modelViewMatrix = Matrix44.IDENTITY - set(value) { - modelViewMatrixInverse = modelViewMatrix.inversed - field = value - } + set(value) { + modelViewMatrixInverse = modelViewMatrix.inversed + field = value + } init { useUV = false diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag b/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag deleted file mode 100644 index b2c2e5ca..00000000 --- a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag +++ /dev/null @@ -1,21 +0,0 @@ -uniform sampler2D tex0; -uniform sampler2D tex1; -uniform vec2 originalSize; -uniform vec2 directionalField; -uniform float distanceScale; -in vec2 v_texCoord0; - -out vec4 o_color; - -void main() { - vec2 sizeDF = textureSize(tex0, 0); // this is always square - vec2 sizeTF = textureSize(tex1, 0); // this can be non-square - - vec2 pixelPosition = v_texCoord0; - vec2 centroidPixelPosition = texture(tex0, v_texCoord0).xy; - vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * sizeDF * vec2(1.0, -1.0); - vec2 dfTf = sizeDF / sizeTF; // texture adjusment factor - float threshold = texture(tex1, v_texCoord0 * dfTf).r; - - o_color = vec4(pixelDistance * distanceScale, threshold, 1.0); -} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/alpha-threshold.frag b/orx-jumpflood/src/shaders/glsl/alpha-threshold.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/alpha-threshold.frag rename to orx-jumpflood/src/shaders/glsl/alpha-threshold.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/contour-points.frag b/orx-jumpflood/src/shaders/glsl/contour-points.frag similarity index 86% rename from orx-jumpflood/src/main/resources/shaders/gl3/contour-points.frag rename to orx-jumpflood/src/shaders/glsl/contour-points.frag index f37d7d96..21868278 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/contour-points.frag +++ b/orx-jumpflood/src/shaders/glsl/contour-points.frag @@ -4,10 +4,10 @@ in vec2 v_texCoord0; out vec4 o_color; void main() { - vec2 stepSize = 1.0 / textureSize(tex0, 0); + vec2 stepSize = 1.0 / vec2(textureSize(tex0, 0)); float ref = step(0.5 , texture(tex0, v_texCoord0).r); - float laplacian = -4 * ref; + float laplacian = -4.0 * ref; laplacian += step(0.5, texture(tex0, v_texCoord0 + vec2(stepSize.x, 0.0)).r); laplacian += step(0.5, texture(tex0, v_texCoord0 - vec2(stepSize.x, 0.0)).r); diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/encode-points.frag b/orx-jumpflood/src/shaders/glsl/encode-points.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/encode-points.frag rename to orx-jumpflood/src/shaders/glsl/encode-points.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/encode-subpixel.frag b/orx-jumpflood/src/shaders/glsl/encode-subpixel.frag similarity index 98% rename from orx-jumpflood/src/main/resources/shaders/gl3/encode-subpixel.frag rename to orx-jumpflood/src/shaders/glsl/encode-subpixel.frag index e1894097..c357759f 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/encode-subpixel.frag +++ b/orx-jumpflood/src/shaders/glsl/encode-subpixel.frag @@ -13,7 +13,7 @@ float zd(float d) { } void main() { - vec2 stepSize = 1.0 / textureSize(tex0, 0); + vec2 stepSize = 1.0 / vec2(textureSize(tex0, 0)); float ref = step(threshold, texture(tex0, v_texCoord0).a); diff --git a/orx-jumpflood/src/shaders/glsl/id-contours.frag b/orx-jumpflood/src/shaders/glsl/id-contours.frag new file mode 100644 index 00000000..8a636944 --- /dev/null +++ b/orx-jumpflood/src/shaders/glsl/id-contours.frag @@ -0,0 +1,25 @@ +uniform sampler2D tex0; +in vec2 v_texCoord0; + +out vec4 o_color; + +void main() { +vec4 colorMask = vec4(0.0, 0.0, 1.0, 0.0); + vec2 stepSize = 1.0 / vec2(textureSize(tex0, 0)); + vec4 ref = texture(tex0, v_texCoord0); + + float laplacian = 0.0; + + laplacian += abs(texture(tex0, v_texCoord0 + vec2(stepSize.x, 0.0)).b-ref.b); + laplacian += abs(texture(tex0, v_texCoord0 - vec2(stepSize.x, 0.0)).b-ref.b); + laplacian += abs(texture(tex0, v_texCoord0 + vec2(0.0, stepSize.y)).b-ref.b); + laplacian += abs(texture(tex0, v_texCoord0 - vec2(0.0, stepSize.y)).b-ref.b); + + float contour = step(0.0, laplacian); + + if (laplacian > 0.001) { + o_color = vec4(v_texCoord0.x, v_texCoord0.y, ref.b, 1.0); + } else { + o_color = vec4(-1.0, -1.0, -1.0, 1.0); + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/inner-bevel.frag b/orx-jumpflood/src/shaders/glsl/inner-bevel.frag similarity index 96% rename from orx-jumpflood/src/main/resources/shaders/gl3/fx/inner-bevel.frag rename to orx-jumpflood/src/shaders/glsl/inner-bevel.frag index cb844c59..1da77eb0 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/fx/inner-bevel.frag +++ b/orx-jumpflood/src/shaders/glsl/inner-bevel.frag @@ -22,7 +22,7 @@ void main() { vec4 color = texture(tex0, v_texCoord0); - vec2 step = 1.0 / textureSize(tex0, 0); + vec2 step = 1.0 / vec2(textureSize(tex0, 0)); vec2 distance = vec2(0.0); float totalWeight = 0.0; diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/inner-glow.frag b/orx-jumpflood/src/shaders/glsl/inner-glow.frag similarity index 95% rename from orx-jumpflood/src/main/resources/shaders/gl3/fx/inner-glow.frag rename to orx-jumpflood/src/shaders/glsl/inner-glow.frag index ab0c2c31..4dca66f0 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/fx/inner-glow.frag +++ b/orx-jumpflood/src/shaders/glsl/inner-glow.frag @@ -18,7 +18,7 @@ vec2 hash22(vec2 p) { void main() { vec4 original = texture(tex0, v_texCoord0); - vec2 step = 1.0 / textureSize(tex0, 0); + vec2 step = 1.0 / vec2(textureSize(tex0, 0)); vec2 distance = texture(tex1, v_texCoord0).rg; float d = length(distance); vec2 n = normalize(distance); diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/inpaint.frag b/orx-jumpflood/src/shaders/glsl/inpaint.frag similarity index 96% rename from orx-jumpflood/src/main/resources/shaders/gl3/fx/inpaint.frag rename to orx-jumpflood/src/shaders/glsl/inpaint.frag index 707ddb48..aa347583 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/fx/inpaint.frag +++ b/orx-jumpflood/src/shaders/glsl/inpaint.frag @@ -18,7 +18,7 @@ vec2 hash22(vec2 p) { void main() { vec4 original = texture(tex0, v_texCoord0); - vec2 ts = textureSize(tex0, 0); + vec2 ts = vec2(textureSize(tex0, 0)); vec2 step = 1.0 / ts; vec2 distance = texture(tex1, v_texCoord0).rg; diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag b/orx-jumpflood/src/shaders/glsl/jumpflood.frag similarity index 73% rename from orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag rename to orx-jumpflood/src/shaders/glsl/jumpflood.frag index 062170da..5c6e3c96 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/jumpflood.frag +++ b/orx-jumpflood/src/shaders/glsl/jumpflood.frag @@ -7,13 +7,13 @@ uniform int step; out vec4 o_color; void main() { - float stepwidth = 1.0 / pow(2.0, min(maxSteps, step+1)); + float stepwidth = 1.0 / pow(2.0, min(float(maxSteps), float(step+1))); - float bestDistance = 999999.0; - vec2 bestCoord = vec2(-1.0); + float bestDistance = 1E10; + vec2 bestCoord = vec2(-100.0); vec2 bestColor = vec2(-1.0); - vec2 is = vec2(1.0) / textureSize(tex0, 0); + vec2 is = vec2(1.0) / vec2(textureSize(tex0, 0)); float found = 0.0; for (int y = -1; y <= 1; ++y) { @@ -23,7 +23,7 @@ void main() { 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) + if ((seedCoord.x >= 0.0 && seedCoord.y >= 0.0) && dist <= bestDistance) { found = 1.0; bestDistance = dist; diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/outer-glow.frag b/orx-jumpflood/src/shaders/glsl/outer-glow.frag similarity index 94% rename from orx-jumpflood/src/main/resources/shaders/gl3/fx/outer-glow.frag rename to orx-jumpflood/src/shaders/glsl/outer-glow.frag index 52108385..674232b1 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/fx/outer-glow.frag +++ b/orx-jumpflood/src/shaders/glsl/outer-glow.frag @@ -18,7 +18,7 @@ vec2 hash22(vec2 p) { void main() { vec4 original = texture(tex0, v_texCoord0); - vec2 step = 1.0 / textureSize(tex0, 0); + vec2 step = 1.0 / vec2(textureSize(tex0, 0)); vec2 distance = texture(tex1, v_texCoord0).rg; float d = length(distance); vec2 n = normalize(distance); diff --git a/orx-jumpflood/src/shaders/glsl/pixel-direction.frag b/orx-jumpflood/src/shaders/glsl/pixel-direction.frag new file mode 100644 index 00000000..428fd7f5 --- /dev/null +++ b/orx-jumpflood/src/shaders/glsl/pixel-direction.frag @@ -0,0 +1,59 @@ + +/* +use #define OUTPUT_DISTANCE to output distance +use #define OUTPUT_DIRECTION to output direction +*/ + +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform vec2 originalSize; +uniform vec2 directionalField; +uniform float distanceScale; +uniform bool normalizedDistance; +uniform bool unitDirection; +uniform bool flipV; +uniform bool outputIds; +in vec2 v_texCoord0; + +out vec4 o_color; + +void main() { + vec2 sizeDF = vec2(textureSize(tex0, 0)); // this is always square + vec2 sizeTF = vec2(textureSize(tex1, 0)); // this can be non-square + + vec2 pixelPosition = v_texCoord0; + vec4 textureData = texture(tex0, v_texCoord0); + vec2 centroidPixelPosition = textureData.xy; + + + vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * sizeDF; + + if (flipV) { + pixelDistance *= vec2(1.0, -1.0); + } + + if (unitDirection) { + float length = length(pixelDistance); + if (length >= 1E-6) { + pixelDistance /= length; + } + } + + vec2 dfTf = sizeDF / sizeTF; // texture adjusment factor + + float outputData = (!outputIds) ? texture(tex1, v_texCoord0 * dfTf).r : textureData.b; + + #ifdef OUTPUT_DIRECTION + if (!normalizedDistance) { + o_color = vec4(pixelDistance * distanceScale, outputData, 1.0); + } else if (!unitDirection) { + o_color = vec4(pixelDistance / originalSize, outputData, 1.0); + } + #else + if (!normalizedDistance) { + o_color = vec4( length(pixelDistance * distanceScale).xx, outputData, 1.0); + } else if (!unitDirection) { + o_color = vec4( length(pixelDistance / originalSize).xx, outputData, 1.0); + } + #endif +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag b/orx-jumpflood/src/shaders/glsl/pixel-distance.frag similarity index 85% rename from orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag rename to orx-jumpflood/src/shaders/glsl/pixel-distance.frag index fb21559a..d7a444aa 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag +++ b/orx-jumpflood/src/shaders/glsl/pixel-distance.frag @@ -11,8 +11,8 @@ in vec2 v_texCoord0; out vec4 o_color; void main() { - vec2 sizeDF = textureSize(tex0, 0); // this is always square - vec2 sizeTF = textureSize(tex1, 0); // this can be non-square + vec2 sizeDF = vec2(textureSize(tex0, 0)); // this is always square + vec2 sizeTF = vec2(textureSize(tex1, 0)); // this can be non-square vec2 pixelPosition = v_texCoord0; vec2 centroidPixelPosition = texture(tex0, v_texCoord0).xy; diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-blend.frag b/orx-jumpflood/src/shaders/glsl/sdf-blend.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-blend.frag rename to orx-jumpflood/src/shaders/glsl/sdf-blend.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-onion.frag b/orx-jumpflood/src/shaders/glsl/sdf-onion.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-onion.frag rename to orx-jumpflood/src/shaders/glsl/sdf-onion.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-round.frag b/orx-jumpflood/src/shaders/glsl/sdf-round.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-round.frag rename to orx-jumpflood/src/shaders/glsl/sdf-round.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-smooth-difference.frag b/orx-jumpflood/src/shaders/glsl/sdf-smooth-difference.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-smooth-difference.frag rename to orx-jumpflood/src/shaders/glsl/sdf-smooth-difference.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-smooth-intersection.frag b/orx-jumpflood/src/shaders/glsl/sdf-smooth-intersection.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-smooth-intersection.frag rename to orx-jumpflood/src/shaders/glsl/sdf-smooth-intersection.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-smooth-union.frag b/orx-jumpflood/src/shaders/glsl/sdf-smooth-union.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/ops/sdf-smooth-union.frag rename to orx-jumpflood/src/shaders/glsl/sdf-smooth-union.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/draw/sdf-stroke-fill.frag b/orx-jumpflood/src/shaders/glsl/sdf-stroke-fill.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/draw/sdf-stroke-fill.frag rename to orx-jumpflood/src/shaders/glsl/sdf-stroke-fill.frag diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/shape-sdf.frag b/orx-jumpflood/src/shaders/glsl/shape-sdf.frag similarity index 98% rename from orx-jumpflood/src/main/resources/shaders/gl3/shape-sdf.frag rename to orx-jumpflood/src/shaders/glsl/shape-sdf.frag index 38e10fa6..77c5f54d 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/shape-sdf.frag +++ b/orx-jumpflood/src/shaders/glsl/shape-sdf.frag @@ -92,7 +92,7 @@ void main() { vec2 fixDistance = vec2(1.0); if (useUV) { - vec2 o = 0.5 / textureSize(tex0, 0); + vec2 o = 0.5 / vec2(textureSize(tex0, 0)); uv = texture(tex0, v_texCoord0 + o).xy; if (rectify) { fixDistance = (fwidth(uv))*vec2(1280.0, 720.0); diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag b/orx-jumpflood/src/shaders/glsl/skeleton.frag similarity index 96% rename from orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag rename to orx-jumpflood/src/shaders/glsl/skeleton.frag index 7fa80de4..0f1edc9f 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag +++ b/orx-jumpflood/src/shaders/glsl/skeleton.frag @@ -10,7 +10,7 @@ out vec4 o_color; void main() { float centerDistance = texture(tex0, v_texCoord0).r; - vec2 step = 1.0 / textureSize(tex0, 0); + vec2 step = 1.0 / vec2(textureSize(tex0, 0)); float minDistance = 1000.0; diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag b/orx-jumpflood/src/shaders/glsl/straight-skeleton.frag similarity index 96% rename from orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag rename to orx-jumpflood/src/shaders/glsl/straight-skeleton.frag index 64c65469..e0aaf907 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag +++ b/orx-jumpflood/src/shaders/glsl/straight-skeleton.frag @@ -11,7 +11,7 @@ out vec4 o_color; void main() { vec4 ct = texture(tex0, v_texCoord0); vec2 cd = normalize(ct.xy); - vec2 step = 1.0 / textureSize(tex0, 0); + vec2 step = 1.0 / vec2(textureSize(tex0, 0)); float minDistance = 1000.0; diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/threshold.frag b/orx-jumpflood/src/shaders/glsl/threshold.frag similarity index 100% rename from orx-jumpflood/src/main/resources/shaders/gl3/threshold.frag rename to orx-jumpflood/src/shaders/glsl/threshold.frag