Hello, I’m trying to draw a bunch o lines, each with a different style. If I understand correctly, to draw straight lines in OPENRNDR, I should use the LineSegment class.
I read in the docs that for other primitive shapes I can use
static approach: drawer.<<primitive>>Batch { }
dynamic approach: drawer.<<primitive>>s { }
which gives me <<primitive>>BatchBuilder where I can set the style and create the primitive object using build functions.
However, there doesn’t seem to be any drawer.lineSegments() function gives me LineSegmentBatchBuilder. As far as I can see, all lineSegments overloads take a list of vectors or LineSegments. In fact, the LineSegmentBatchBuilder class does not seem to exist.
If I use drawer.lineSegment() to draw each line separately, the performance drops quite quickly for relatively small number of lines.
How can I draw batched lines each with a different style, please?
Maybe that could be added to the framework based on the other 3 examples…
Meanwhile, I found this program among my sketches.
import org.openrndr.application
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.shadeStyle
import org.openrndr.draw.vertexBuffer
import org.openrndr.draw.vertexFormat
import org.openrndr.extra.noise.Random
import org.openrndr.extra.noise.simplex3D
import org.openrndr.extra.noise.uniform
import org.openrndr.extra.noise.withVector2Output
fun main() = application {
configure {
width = 800
height = 800
}
program {
// create a buffer and specify it's format and size.
val geometry = vertexBuffer(vertexFormat {
position(3)
color(4)
}, 2 * 210000)
// create an area with some padding around the edges
val area = drawer.bounds.offsetEdges(-50.0)
val n = simplex3D.withVector2Output()
// populate the vertex buffer.
geometry.put {
for (i in 0 until geometry.vertexCount / 2) {
val p = area.uniform()
write(p.vector3(z = 0.0)) // start
write(Random.vector4(0.0, 1.0)) // color
write(
(p + n(5, p.x * 0.01, p.y * 0.01, 0.0) * 5.0)
.vector3(z = 0.0)
) // end
write(Random.vector4(0.0, 1.0)) // color
}
}
extend {
// shader using the color attributes from our buffer
drawer.shadeStyle = shadeStyle {
fragmentTransform = "x_fill = va_color;"
}
drawer.vertexBuffer(geometry, DrawPrimitive.LINES)
}
}
}
The following lineSegments overload is sufficient for what I need. I should have really noticed it the first time I was looking at it!
fun lineSegments(segments: List<Vector3>, weights: List<Double>, colors: List<ColorRGBa>)
I played with it a bit (and checked the implementation of that function) and noticed a couple of things
The size of the vector list must be even. It crashes with ArrayIndexOutOfBounds otherwise
The odd items from weights and colors are ignored, only the even items are used for the corresponding line
There is no overload for Vector2, and it’s far less convenient than the BatchBuilder, but does the job! It also performs well even with large number of lines.
I’ll look into vertexBuffers when I hit the limits of this solution.
Since the only lineSegments() overload that allows setting colors takes Vector3, drawStyle.lineCap is not taken into account. Line caps are only applied when drawing lines in 2D.