diff --git a/orx-noise/build.gradle b/orx-noise/build.gradle index 3cc46fa0..03c037bc 100644 --- a/orx-noise/build.gradle +++ b/orx-noise/build.gradle @@ -1,3 +1,7 @@ dependencies { + compile "org.openrndr:openrndr-core:$openrndrVersion" + compile "org.openrndr:openrndr-gl3:$openrndrVersion" + compile "org.openrndr:openrndr-gl3-natives-macos:$openrndrVersion" implementation project(":orx-shader-phrases") + implementation project(":orx-gui") } \ No newline at end of file diff --git a/orx-noise/src/main/kotlin/filters/NoiseFilters.kt b/orx-noise/src/main/kotlin/filters/NoiseFilters.kt index dbad94fd..43678e53 100644 --- a/orx-noise/src/main/kotlin/filters/NoiseFilters.kt +++ b/orx-noise/src/main/kotlin/filters/NoiseFilters.kt @@ -3,6 +3,7 @@ package org.openrndr.extra.noise.filters import org.openrndr.color.ColorRGBa import org.openrndr.draw.Filter import org.openrndr.draw.filterShaderFromUrl +import org.openrndr.extra.parameters.* import org.openrndr.math.Vector2 import org.openrndr.math.Vector3 import org.openrndr.math.Vector4 @@ -25,11 +26,13 @@ class HashNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/no /** * is the noise monochrome, default is true */ + @BooleanParameter("Monochrome") var monochrome: Boolean by parameters /** * noise seed, feed it with time to animate */ + @DoubleParameter("Seed", 0.0, 10000.0) var seed: Double by parameters init { @@ -48,18 +51,20 @@ class SpeckleNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra /** * The color of the generated speckles */ + @ColorParameter("Color") var color: ColorRGBa by parameters /** * Density of the speckles, default is 0.1, min, 0.0, max is 1.0 */ - + @DoubleParameter("Density", 0.0, 1.0) var density: Double by parameters /** * Noisiness of the generated speckles, default is 0.0, min is 0.0, max is 1.0 */ + @DoubleParameter("Noise", 0.0, 1.0) var noise: Double by parameters /** @@ -70,6 +75,7 @@ class SpeckleNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra /** * noise seed, feed it with time to animate */ + @DoubleParameter("Seed", 0.0, 10000.0) var seed: Double by parameters init { @@ -110,6 +116,7 @@ class CellNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/no /** * the number of octaves of noise to generate, default is 4 */ + @IntParameter("Octaves", 1, 8) var octaves: Int by parameters /** @@ -138,6 +145,7 @@ class CellNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/no * Filter that produces value noise */ class ValueNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/value-noise.frag"))) { + @DoubleParameter("Seed", 0.0, 10000.0) var seed: Vector2 by parameters /** @@ -163,6 +171,7 @@ class ValueNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/n /** * the number of octaves of noise to generate, default is 4 */ + @IntParameter("Octaves", 1, 8) var octaves: Int by parameters /** @@ -190,6 +199,7 @@ class ValueNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/n /** * Filter that produces 3D Simplex Noise */ +@Description("Simplex Noise") class SimplexNoise3D : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/simplex-noise-3d.frag"))) { var seed: Vector3 by parameters @@ -216,6 +226,7 @@ class SimplexNoise3D : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/ext /** * the number of octaves of noise to generate, default is 4 */ + @IntParameter("Octaves", 1, 8) var octaves: Int by parameters /** @@ -226,6 +237,7 @@ class SimplexNoise3D : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/ext /** * should the output colors be multiplied by the alpha channel, default is true */ + @BooleanParameter("Premultiplied alpha") var premultipliedAlpha: Boolean by parameters init { @@ -238,4 +250,22 @@ class SimplexNoise3D : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/ext bias = Vector4.ONE / 2.0 premultipliedAlpha = true } -} \ No newline at end of file +} + + +/** + * Filter for Worley Noise + */ +@Description("Worley Noise") +class WorleyNoise : Filter(filterShaderFromUrl(resourceUrl("/org/openrndr/extra/noise/shaders/gl3/worley-noise.frag"))) { + @DoubleParameter("Scale", 0.1, 200.0) + var scale: Double by parameters + + @BooleanParameter("Premultiplied alpha") + var premultipliedAlpha: Boolean by parameters + + init { + premultipliedAlpha = true + scale = 5.0 + } +} diff --git a/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/worley-noise.frag b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/worley-noise.frag new file mode 100644 index 00000000..97e7ba6d --- /dev/null +++ b/orx-noise/src/main/resources/org/openrndr/extra/noise/shaders/gl3/worley-noise.frag @@ -0,0 +1,80 @@ +#version 330 + +// uniforms +//uniform vec4 gain; +//uniform vec4 bias; +//uniform vec3 seed; +uniform float scale; +// +//uniform vec3 lacunarity; +//uniform vec4 decay; +//uniform int octaves; +uniform bool premultipliedAlpha; + +// varyings +in vec2 v_texCoord0; + +// outputs +out vec4 o_output; + + +vec3 permute(vec3 x) { + return mod((34.0 * x + 1.0) * x, 289.0); +} + +vec3 dist(vec3 x, vec3 y, bool manhattanDistance) { + return manhattanDistance ? abs(x) + abs(y) : (x * x + y * y); +} + +vec2 worley(vec2 P, float jitter, bool manhattanDistance) { + float K= 0.142857142857; // 1/7 + float Ko= 0.428571428571 ;// 3/7 + vec2 Pi = mod(floor(P), 289.0); + vec2 Pf = fract(P); + vec3 oi = vec3(-1.0, 0.0, 1.0); + vec3 of = vec3(-0.5, 0.5, 1.5); + vec3 px = permute(Pi.x + oi); + vec3 p = permute(px.x + Pi.y + oi); // p11, p12, p13 + vec3 ox = fract(p*K) - Ko; + vec3 oy = mod(floor(p*K),7.0)*K - Ko; + vec3 dx = Pf.x + 0.5 + jitter*ox; + vec3 dy = Pf.y - of + jitter*oy; + vec3 d1 = dist(dx,dy, manhattanDistance); // d11, d12 and d13, squared + p = permute(px.y + Pi.y + oi); // p21, p22, p23 + ox = fract(p*K) - Ko; + oy = mod(floor(p*K),7.0)*K - Ko; + dx = Pf.x - 0.5 + jitter*ox; + dy = Pf.y - of + jitter*oy; + vec3 d2 = dist(dx,dy, manhattanDistance); // d21, d22 and d23, squared + p = permute(px.z + Pi.y + oi); // p31, p32, p33 + ox = fract(p*K) - Ko; + oy = mod(floor(p*K),7.0)*K - Ko; + dx = Pf.x - 1.5 + jitter*ox; + dy = Pf.y - of + jitter*oy; + vec3 d3 = dist(dx,dy, manhattanDistance); // d31, d32 and d33, squared + // Sort out the two smallest distances (F1, F2) + vec3 d1a = min(d1, d2); + d2 = max(d1, d2); // Swap to keep candidates for F2 + d2 = min(d2, d3); // neither F1 nor F2 are now in d3 + d1 = min(d1a, d2); // F1 is now in d1 + d2 = max(d1a, d2); // Swap to keep candidates for F2 + d1.xy = (d1.x < d1.y) ? d1.xy : d1.yx; // Swap if smaller + d1.xz = (d1.x < d1.z) ? d1.xz : d1.zx; // F1 is in d1.x + d1.yz = min(d1.yz, d2.yz); // F2 is now not in d2.yz + d1.y = min(d1.y, d1.z); // nor in d1.z + d1.y = min(d1.y, d2.x); // F2 is in d1.y, we're done. + return sqrt(d1.xy); +} + + +void main() { + vec2 F = worley(v_texCoord0 * scale, 1.0, false); + float F1 = F.x; + float F2 = F.y; + + o_output = vec4(vec3(F2-F1), 1.0); + + if (premultipliedAlpha) { + o_output.rgb *= o_output.a; + } +} diff --git a/orx-noise/src/test/kotlin/TestSimplex.kt b/orx-noise/src/test/kotlin/TestSimplex.kt new file mode 100644 index 00000000..e3558dee --- /dev/null +++ b/orx-noise/src/test/kotlin/TestSimplex.kt @@ -0,0 +1,29 @@ +import org.openrndr.application +import org.openrndr.draw.renderTarget +import org.openrndr.extra.gui.* +import org.openrndr.extra.noise.filters.SimplexNoise3D + +fun main() = application { + configure { + width = 1000 + height = 1000 + } + + program { + val gui = GUI() + + val simplexNoise3D = SimplexNoise3D() + val target = renderTarget(width, height) { + colorBuffer() + } + + gui.add(simplexNoise3D) + + extend(gui) + + extend { + simplexNoise3D.apply(target.colorBuffer(0), target.colorBuffer(0)) + drawer.image(target.colorBuffer(0)) + } + } +} \ No newline at end of file diff --git a/orx-noise/src/test/kotlin/TestWorley.kt b/orx-noise/src/test/kotlin/TestWorley.kt new file mode 100644 index 00000000..91d6f36d --- /dev/null +++ b/orx-noise/src/test/kotlin/TestWorley.kt @@ -0,0 +1,30 @@ +import org.openrndr.application +import org.openrndr.draw.renderTarget +import org.openrndr.extra.noise.filters.CellNoise +import org.openrndr.extra.noise.filters.WorleyNoise +import org.openrndr.extra.gui.* + +fun main() = application { + configure { + width = 1000 + height = 1000 + } + + program { + val gui = GUI() + + val worleyNoise = WorleyNoise() + val target = renderTarget(width, height) { + colorBuffer() + } + + gui.add(worleyNoise) + + extend(gui) + + extend { + worleyNoise.apply(target.colorBuffer(0), target.colorBuffer(0)) + drawer.image(target.colorBuffer(0)) + } + } +} \ No newline at end of file diff --git a/orx-syphon/README.md b/orx-syphon/README.md new file mode 100644 index 00000000..baf9c2de --- /dev/null +++ b/orx-syphon/README.md @@ -0,0 +1 @@ +# orx-syphon \ No newline at end of file diff --git a/orx-syphon/build.gradle b/orx-syphon/build.gradle new file mode 100644 index 00000000..86cb81c6 --- /dev/null +++ b/orx-syphon/build.gradle @@ -0,0 +1,6 @@ +dependencies { + compile "org.openrndr:openrndr-core:$openrndrVersion" + compile "org.openrndr:openrndr-gl3:$openrndrVersion" + compile "org.lwjgl:lwjgl-opengl:3.2.3" + compile "org.openrndr:openrndr-gl3-natives-macos:$openrndrVersion" +} \ No newline at end of file diff --git a/orx-syphon/src/main/kotlin/SyphonClient.kt b/orx-syphon/src/main/kotlin/SyphonClient.kt new file mode 100644 index 00000000..e69de29b diff --git a/orx-syphon/src/main/kotlin/SyphonServer.kt b/orx-syphon/src/main/kotlin/SyphonServer.kt new file mode 100644 index 00000000..aea2e475 --- /dev/null +++ b/orx-syphon/src/main/kotlin/SyphonServer.kt @@ -0,0 +1,54 @@ + +import jsyphon.JSyphonServer +import org.openrndr.Extension +import org.openrndr.Program +import org.openrndr.draw.Drawer +import org.openrndr.draw.RenderTarget +import org.openrndr.draw.renderTarget +import org.openrndr.internal.gl3.ColorBufferGL3 + + +class SyphonServer(private val name: String = "OPENRNDR", var target: RenderTarget? = null): Extension { + override var enabled = true + private val server = JSyphonServer() + + override fun setup(program: Program) { + server.initWithName(name) + + if (target == null) { + target = renderTarget(program.width, program.height) { + colorBuffer() + depthBuffer() + } + } + } + + override fun beforeDraw(drawer: Drawer, program: Program) { + target?.bind() + } + + override fun afterDraw(drawer: Drawer, program: Program) { + target?.unbind() + drawer.image(target?.colorBuffer(0)!!) + val glBuffer = target?.colorBuffer(0) as ColorBufferGL3 + + println(glBuffer.multisample) + + // Send to Syphon + server.publishFrameTexture( + glBuffer.texture, glBuffer.target, 0, 0, + program.width, program.height, program.width, program.height, false + ) + } + + override fun shutdown(program: Program) { + // Cleanup + server.stop() + } +} + + + + + + diff --git a/orx-syphon/src/main/kotlin/jsyphon/Syphon b/orx-syphon/src/main/kotlin/jsyphon/Syphon new file mode 100755 index 00000000..7cf6833f Binary files /dev/null and b/orx-syphon/src/main/kotlin/jsyphon/Syphon differ diff --git a/orx-syphon/src/main/kotlin/jsyphon/Util.kt b/orx-syphon/src/main/kotlin/jsyphon/Util.kt new file mode 100644 index 00000000..68b4681b --- /dev/null +++ b/orx-syphon/src/main/kotlin/jsyphon/Util.kt @@ -0,0 +1,11 @@ +package jsyphon + +class NSSize (var x: Int, var y: Int) +class NSPoint(var x: Int, var y: Int) + +class NSRect(var origin: NSPoint, var size: NSSize) { + constructor(startX: Int, xLength: Int, startY: Int, yLength: Int) : this( + NSPoint(startX, startY), + NSSize(xLength, yLength) + ) +} \ No newline at end of file diff --git a/orx-syphon/src/main/kotlin/jsyphon/libJSyphon.jnilib b/orx-syphon/src/main/kotlin/jsyphon/libJSyphon.jnilib new file mode 100755 index 00000000..062c85fd Binary files /dev/null and b/orx-syphon/src/main/kotlin/jsyphon/libJSyphon.jnilib differ diff --git a/orx-syphon/src/test/kotlin/ClientExample.kt b/orx-syphon/src/test/kotlin/ClientExample.kt new file mode 100644 index 00000000..cb13ddea --- /dev/null +++ b/orx-syphon/src/test/kotlin/ClientExample.kt @@ -0,0 +1,38 @@ +import jsyphon.JSyphonClient +import jsyphon.JSyphonImage +import org.lwjgl.opengl.GL11C.GL_TEXTURE_2D +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.internal.Driver +import org.openrndr.internal.gl3.ColorBufferGL3 +import kotlin.math.sin + + +fun main() = application { + configure { + width = 1000 + height = 1000 + } + + program { + val client = JSyphonClient() + client.init() + + + extend { + drawer.background(ColorRGBa.RED) + + if (client.hasNewFrame()) { + println("hasnewframe") + val img = client.newFrameImageForContext() + val buffer = ColorBufferGL3(GL_TEXTURE_2D, img.textureName(), img.textureWidth(), img.textureHeight(), + 1.0, ColorFormat.RGBa, ColorType.UINT8, 1, BufferMultisample.Disabled, Session.active) + + + drawer.image(buffer) + } + + } + } +} \ No newline at end of file diff --git a/orx-syphon/src/test/kotlin/ServerExample.kt b/orx-syphon/src/test/kotlin/ServerExample.kt new file mode 100644 index 00000000..2aa83e10 --- /dev/null +++ b/orx-syphon/src/test/kotlin/ServerExample.kt @@ -0,0 +1,20 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import kotlin.math.sin + + +fun main() = application { + configure { + width = 1000 + height = 1000 + } + + program { + extend(SyphonServer("Test")) + + extend { + drawer.background(ColorRGBa.RED) + drawer.circle(width/2.0, height/2.0, sin(seconds) * width / 2.0) + } + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7a23628d..9fff71e7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,6 +26,7 @@ include 'orx-camera', 'orx-runway', 'orx-shader-phrases', 'orx-shade-styles', + 'orx-syphon', 'orx-temporal-blur', 'orx-kinect-common', 'orx-kinect-v1',