Live coding with orx-olive

By using Kotlin’s ability to run script files we can build a live coding environment. The orx-olive library simplifies the work to be done to set up a live coding environment. Code and additional documentation for the library can be found in the Github repository.

Prerequisites

Assuming you are working on an openrndr-template based project, orx-olive is enabled by default.

Basic example

fun main() = application {
    configure {
        width = 768
        height = 576
    }
    oliveProgram {
        extend {
            // drawer.fill = ColorRGBa.PINK
            drawer.rectangle(0.0, 0.0, 100.0, 200.0)
        }
    }
}

Try editing the source code to change the fill color of the rectangle (or any other property) and save your changes. The new color should appear instantly without having to re-run the program.

Interaction with extensions

The Olive extension works well together with other extensions. In the following example we see the use of Camera2D in combination with Olive.

fun main() = application {
    oliveProgram {
        extend(Camera2D())
        extend {
            drawer.rectangle(0.0, 0.0, 100.0, 200.0)
        }
    }
}

Adding persistent state

Sometimes you want to keep parts of your application persistent, that means its state will survive a script reload.

This is how we can make the Camera2D from the previous example persistent:

fun main() = application {
    oliveProgram {
        val camera by Once {
            persistent {
                Camera2D()
            }
        }
        extend(camera)
        extend {
            drawer.rectangle(0.0, 0.0, 100.0, 200.0)
        }
    }
}

The same approach can be used to maintain a persistent connection to a webcam:

fun main() = application {
    oliveProgram {
        val webcam by Once {
            persistent {
                VideoPlayerFFMPEG.fromDevice()
            }
        }
        webcam.play()
        extend {
            webcam.colorBuffer?.let {
                drawer.image(it, 0.0, 0.0, 128.0, 96.0)
            }
        }
    }
}

GUI workflow

orx-gui is built with the orx-olive environment in mind. Its use is similar to the workflows described prior, however, in live mode the ui comes with some extra features to make live-coding more fun. The best part is that orx-gui can retain parameter settings between script changes by default, so nothing jumps around.

Notice the use of Reloadable() in the settings object.

@file:Suppress("UNUSED_LAMBDA_EXPRESSION")
import org.openrndr.Program
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.*
import org.openrndr.extra.compositor.compose
import org.openrndr.extra.compositor.draw
import org.openrndr.extra.compositor.layer
import org.openrndr.extra.compositor.post
import org.openrndr.extra.gui.GUI
import org.openrndr.extra.parameters.*

fun main() = application {
    configure {
        width = 800
        height = 800
    }
    oliveProgram {
        val gui = GUI()
        val settings = @Description("User settings") object : Reloadable() {
            @DoubleParameter("x", 0.0, 1000.0)
            var x = 0.0
        }
        val composite = compose {
            draw {
                drawer.clear(ColorRGBa.PINK)
                drawer.circle(settings.x, height / 2.0, 100.0)
            }
        }
        extend(gui) {
            add(settings)
        }
        extend {
            composite.draw(drawer)
        }
    }
}

edit on GitHub