Hello I’m struggling a little bit with setting up my sketch in a way that I want to.
I’m using orx-olive, orx-gui.
In my setup, I load in an image, and process every pixel. For every pixel I generate 5 semi-transparent rectangles with a positional offset relative to the pixels positions, and width, height defined by a gaussian distribution.
In my draw, I iterate over this List, and actually draw the rectangles.
Now I’ve added parameters for the deviation of the gaussian with orx-gui.
I want to achieve the following:
- I want to call the draw exactly ONCE
- when I update something manually in my code, I want to call draw exactly ONCE again (orx-olive)
- when I update a parameter with orx-gui, I want to draw exactly once again.
Seems like a plausible use-case.
Now the problems:
-
I’ve set PresentationMode.MANUAL, but when I spawn the window, the draw function is not called once, but several times. Even when I don’t move the window.
This settles after a while, but it is wasted time depending on the resolution of the input image. -
After I’ve registered orx-gui parameters, the draw function is called even more often than before. There must be something going on internally that triggers the draw function again, and again. Even when I don’t change the parameters.
-
The parameter changes through orx-gui don’t effect the setup of the rectangles. These rectangles are constructed in my setup, not in the draw. And it seems that the parameter changes are only respected in the draw… so nothing changes until I manually reload.
I tried to execute my drawing functionaly in the setup, but I just get a black windows.
Here is my code:
import org.openrndr.PresentationMode
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.loadImage
import org.openrndr.extra.gui.GUI
import org.openrndr.extra.noise.gaussian
import org.openrndr.extra.noise.random
import org.openrndr.extra.olive.Reloadable
import org.openrndr.extra.olive.oliveProgram
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
fun main() = application {
oliveProgram {
val parameters = @Description("Gaussian Parameters") object : Reloadable(){
@DoubleParameter("Position spread", 1.0, 100.0, precision = 2, order = 0)
var positionSpread = 1.0
@DoubleParameter("Size spread", 1.0, 20.0, precision = 2, order = 1)
var sizeSpread = 12.0
}
val gui = GUI()
gui.add(parameters)
extend(gui)
val image = loadImage("data/images/ramp2.png") // Replace with your image path
val pixels = image.shadow
pixels.download()
val scale = 1024.0 / image.width
val outputWidth = (image.width * scale).toInt()
val outputHeight = (image.height * scale).toInt()
window.size = Vector2(outputWidth.toDouble(), outputHeight.toDouble())
window.presentationMode = PresentationMode.MANUAL
window.requestDraw()
val splatterData = mutableListOf<Pair<ColorRGBa, List<Rectangle>>>()
for (y in 0 until image.height) {
for (x in 0 until image.width) {
val pixelColor = pixels[x, y]
val positions = (0 until 5).map {
val x1 = (x + gaussian(0.0, parameters.positionSpread)) * scale
val y1 = (y + gaussian(0.0, parameters.positionSpread)) * scale
Rectangle.fromCenter(
Vector2(x1, y1),
gaussian(1.0, parameters.sizeSpread) * scale,
gaussian(1.0, parameters.sizeSpread) * scale
)
}
splatterData.add(pixelColor to positions)
}
}
extend {
drawer.clear(ColorRGBa.BLACK)
splatterData.forEach { (color, rectangles) ->
drawer.fill = color.opacify(random(0.01, 0.1)) // Use pixel color with some transparency
drawer.stroke = null
drawer.rectangles(rectangles)
}
}
}
}
Does anyone have any idea how I can approach this?