[orx-compute-graph] Add compute graph code
This commit is contained in:
22
orx-compute-graph-nodes/README.md
Normal file
22
orx-compute-graph-nodes/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# orx-compute-graph-nodes
|
||||
|
||||
A collection of nodes that can be used with orx-computer-graph.
|
||||
|
||||
## List of nodes
|
||||
|
||||
### Multi-platform
|
||||
|
||||
Name | Description | Inputs | Outputs
|
||||
----------------|-----------------------|--------|---------
|
||||
`filterNode` | Wrap around a `Filter`| | `image`
|
||||
`fitImageNode` | Fit image to window bounds | `image` | `image`
|
||||
|
||||
### JVM only
|
||||
|
||||
Name | Description | Inputs | Outputs
|
||||
----------------|-------------------|--------|---------
|
||||
`drawCacheNode` | Cache drawing in an internal color buffer, commonly used as the final stage node | | `image`
|
||||
`dropImageNode` | Listen for window file drop events | | `image`
|
||||
|
||||
|
||||
|
||||
97
orx-compute-graph-nodes/build.gradle.kts
Normal file
97
orx-compute-graph-nodes/build.gradle.kts
Normal file
@@ -0,0 +1,97 @@
|
||||
import EmbedShadersTask
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
kotlin("plugin.serialization")
|
||||
}
|
||||
|
||||
val kotlinxSerializationVersion: String by rootProject.extra
|
||||
val kotestVersion: String by rootProject.extra
|
||||
val junitJupiterVersion: String by rootProject.extra
|
||||
val jvmTarget: String by rootProject.extra
|
||||
val kotlinApiVersion: String by rootProject.extra
|
||||
val kotlinVersion: String by rootProject.extra
|
||||
val kotlinLoggingVersion: String by rootProject.extra
|
||||
val kluentVersion: String by rootProject.extra
|
||||
val openrndrVersion: String by rootProject.extra
|
||||
val openrndrOS: String by rootProject.extra
|
||||
val spekVersion: String by rootProject.extra
|
||||
|
||||
kotlin {
|
||||
jvm {
|
||||
compilations {
|
||||
val demo by creating {
|
||||
defaultSourceSet {
|
||||
kotlin.srcDir("src/demo")
|
||||
dependencies {
|
||||
implementation(project(":orx-camera"))
|
||||
implementation("org.openrndr:openrndr-application:$openrndrVersion")
|
||||
implementation("org.openrndr:openrndr-extensions:$openrndrVersion")
|
||||
runtimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
|
||||
runtimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")
|
||||
implementation(compilations["main"]!!.output.allOutputs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
compilations.all {
|
||||
kotlinOptions.jvmTarget = jvmTarget
|
||||
kotlinOptions.apiVersion = kotlinApiVersion
|
||||
}
|
||||
testRuns["test"].executionTask.configure {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
js(IR) {
|
||||
browser()
|
||||
nodejs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(project(":orx-parameters"))
|
||||
implementation(project(":orx-shader-phrases"))
|
||||
implementation(project(":orx-compute-graph"))
|
||||
implementation(project(":orx-image-fit"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinxSerializationVersion")
|
||||
implementation("org.openrndr:openrndr-application:$openrndrVersion")
|
||||
implementation("org.openrndr:openrndr-draw:$openrndrVersion")
|
||||
implementation("org.openrndr:openrndr-filter:$openrndrVersion")
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
|
||||
implementation("io.github.microutils:kotlin-logging:$kotlinLoggingVersion")
|
||||
}
|
||||
}
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion")
|
||||
implementation("io.kotest:kotest-assertions-core:$kotestVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation(kotlin("test-junit5"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion")
|
||||
runtimeOnly("org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion")
|
||||
runtimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion")
|
||||
implementation("org.spekframework.spek2:spek-dsl-jvm:$spekVersion")
|
||||
implementation("org.amshove.kluent:kluent:$kluentVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val jsTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-js"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
orx-compute-graph-nodes/src/commonMain/kotlin/FilterNode.kt
Normal file
27
orx-compute-graph-nodes/src/commonMain/kotlin/FilterNode.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
package org.openrndr.extra.computegraph.nodes
|
||||
|
||||
import org.openrndr.draw.ColorBuffer
|
||||
import org.openrndr.draw.Filter
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.extra.computegraph.ComputeGraph
|
||||
import org.openrndr.extra.computegraph.ComputeNode
|
||||
import org.openrndr.extra.computegraph.withKey
|
||||
|
||||
fun <T : Filter> ComputeGraph.filterNode(
|
||||
filter: T, input: ComputeNode, inputKey: String = "image", outputKey: String = "image",
|
||||
config: ComputeNode.(f: Filter) -> Unit
|
||||
): ComputeNode {
|
||||
return node {
|
||||
name = "filter-${filter::class.simpleName}"
|
||||
inputs = filter.parameters
|
||||
config(filter)
|
||||
val inputImage by input.outputs.withKey<ColorBuffer>(inputKey)
|
||||
var outputImage by outputs.withKey<ColorBuffer>(outputKey)
|
||||
outputImage = inputImage.createEquivalent()
|
||||
compute {
|
||||
filter.apply(inputImage, outputImage)
|
||||
}
|
||||
dependOn(input)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.openrndr.extra.computegraph.nodes
|
||||
|
||||
import org.openrndr.Program
|
||||
import org.openrndr.draw.ColorBuffer
|
||||
import org.openrndr.draw.isolatedWithTarget
|
||||
import org.openrndr.draw.renderTarget
|
||||
import org.openrndr.extra.computegraph.ComputeGraph
|
||||
import org.openrndr.extra.computegraph.ComputeNode
|
||||
import org.openrndr.extra.computegraph.withKey
|
||||
import org.openrndr.extras.imageFit.imageFit
|
||||
|
||||
fun ComputeGraph.fitImageNode(program: Program, input: ComputeNode) : ComputeNode {
|
||||
return node {
|
||||
name = "fit-image"
|
||||
val rt = renderTarget(program.width, program.height) {
|
||||
colorBuffer()
|
||||
}
|
||||
val inputImage: ColorBuffer by input.outputs.withKey("image")
|
||||
var outputImage:ColorBuffer by outputs.withKey("image")
|
||||
outputImage = rt.colorBuffer(0)
|
||||
compute {
|
||||
program.drawer.isolatedWithTarget(rt) {
|
||||
ortho(rt)
|
||||
imageFit(inputImage, bounds)
|
||||
}
|
||||
}
|
||||
dependOn(input)
|
||||
}
|
||||
}
|
||||
99
orx-compute-graph-nodes/src/jvmMain/kotlin/DrawCacheNode.kt
Normal file
99
orx-compute-graph-nodes/src/jvmMain/kotlin/DrawCacheNode.kt
Normal file
@@ -0,0 +1,99 @@
|
||||
package org.openrndr.extra.computegraph.nodes
|
||||
|
||||
import mu.KotlinLogging
|
||||
import org.openrndr.KEY_SPACEBAR
|
||||
import org.openrndr.Program
|
||||
import org.openrndr.RequestAssetsEvent
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.*
|
||||
import org.openrndr.extra.computegraph.ComputeGraph
|
||||
import org.openrndr.extra.computegraph.ComputeNode
|
||||
import org.openrndr.extra.computegraph.withKey
|
||||
import java.io.File
|
||||
|
||||
val logger = KotlinLogging.logger { }
|
||||
|
||||
private data class RenderTargetDescription(val width: Int, val height: Int, val contentScale: Double)
|
||||
|
||||
private fun RenderTarget.description() = RenderTargetDescription(width, height, contentScale)
|
||||
|
||||
|
||||
fun ComputeGraph.drawCacheNode(
|
||||
program: Program,
|
||||
inputNodes: List<ComputeNode>,
|
||||
draw: Program.(node: ComputeNode) -> Unit
|
||||
): ComputeNode {
|
||||
return node {
|
||||
var producingAssets: Boolean by inputs
|
||||
producingAssets = false
|
||||
|
||||
program.keyboard.keyDown.listen {
|
||||
if (!it.propagationCancelled) {
|
||||
logger.info { "requesting assets" }
|
||||
if (it.key == KEY_SPACEBAR) {
|
||||
program.requestAssets.trigger(RequestAssetsEvent(this, program))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var screenshotTarget = ""
|
||||
program.produceAssets.listen {
|
||||
producingAssets = true
|
||||
screenshotTarget = "screenshots/${it.assetMetadata.assetBaseName}.png"
|
||||
}
|
||||
|
||||
name = "draw-cache"
|
||||
var rt = renderTarget(program.width, program.height) {
|
||||
colorBuffer()
|
||||
depthBuffer()
|
||||
}
|
||||
var outputImage: ColorBuffer by outputs.withKey("image")
|
||||
outputImage = rt.colorBuffer(0)
|
||||
|
||||
var description: RenderTargetDescription by inputs
|
||||
description = RenderTarget.active.description()
|
||||
|
||||
update {
|
||||
description = RenderTarget.active.description()
|
||||
}
|
||||
val defaultContentScale = program.window.contentScale
|
||||
|
||||
compute {
|
||||
rt.colorBuffer(0).destroy()
|
||||
rt.depthBuffer?.destroy()
|
||||
rt.detachColorAttachments()
|
||||
rt.detachDepthBuffer()
|
||||
rt.destroy()
|
||||
rt = renderTarget(
|
||||
program.width,
|
||||
program.height,
|
||||
contentScale = if (producingAssets) 6.0 else defaultContentScale
|
||||
) {
|
||||
colorBuffer()
|
||||
depthBuffer()
|
||||
}
|
||||
program.drawer.isolatedWithTarget(rt) {
|
||||
clear(ColorRGBa.WHITE)
|
||||
|
||||
draw(program, this@node)
|
||||
}
|
||||
outputImage = rt.colorBuffer(0)
|
||||
println(outputImage)
|
||||
|
||||
if (producingAssets) {
|
||||
logger.info { "saving draw cache to file" }
|
||||
val directory = File("screenshots")
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs()
|
||||
}
|
||||
|
||||
outputImage.saveToFile(File(screenshotTarget), async = false)
|
||||
producingAssets = false
|
||||
screenshotTarget = ""
|
||||
}
|
||||
}
|
||||
for (input in inputNodes) {
|
||||
dependOn(input)
|
||||
}
|
||||
}
|
||||
}
|
||||
28
orx-compute-graph-nodes/src/jvmMain/kotlin/DropImageNode.kt
Normal file
28
orx-compute-graph-nodes/src/jvmMain/kotlin/DropImageNode.kt
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.openrndr.extra.computegraph.nodes
|
||||
|
||||
import org.openrndr.Program
|
||||
import org.openrndr.draw.ColorBuffer
|
||||
import org.openrndr.draw.colorBuffer
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.computegraph.ComputeGraph
|
||||
import org.openrndr.extra.computegraph.ComputeNode
|
||||
import java.io.File
|
||||
|
||||
fun ComputeGraph.dropImageNode(program: Program): ComputeNode {
|
||||
return node {
|
||||
name = "drop-image"
|
||||
var file: File by inputs
|
||||
file = File("data/images/cheeta.jpg")
|
||||
program.window.drop.listen {
|
||||
file = File(it.files.first())
|
||||
}
|
||||
var image: ColorBuffer by outputs
|
||||
|
||||
fun loadFileOrEmpty() = if (file.exists()) loadImage(file) else colorBuffer(256, 256)
|
||||
image = loadFileOrEmpty()
|
||||
compute {
|
||||
image.destroy()
|
||||
image = loadFileOrEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user