Drawing per-vertex colored meshes and variable thickness lines

I just wrote a simple program drawing 300 triangles with unique colors in each vertex, the shader doing color interpolation. I like gradients :slight_smile:

imports
import aBeLibs.geometry.randomPoint
import org.openrndr.applicationSynchronous
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
// openrndr 0.4
fun main() = applicationSynchronous {
    configure {
        width = 800
        height = 800
    }
    program {
        // create a buffer and specify it's format and size.
        val geometry = vertexBuffer(vertexFormat {
            position(3)
            color(4)
        }, 3 * 100)

        // create an area with some padding around the edges
        val area = drawer.bounds.offsetEdges(-50.0)
        // populate the vertex buffer.
        geometry.put {
            for (i in 0 until geometry.vertexCount) {
                write(area.randomPoint().vector3(z = 0.0))
                write(Random.vector4(0.0, 1.0))
            }
        }
        extend {
            // shader using the color attributes from our buffer
            drawer.shadeStyle = shadeStyle {
                fragmentTransform = "x_fill = va_color;"
            }
            drawer.vertexBuffer(geometry, DrawPrimitive.TRIANGLES)
        }
    }
}

/**
 * Returns a random point inside a rectangle
 */

fun Rectangle.randomPoint(): Vector2 {
    return Vector2.uniform(this.corner, this.corner + this.dimensions)
}
1 Like

The code above was a preparation for this program, which converts an open animated shapeContour into a mesh (a triangle strip) with variable width and unique colors per vertex.

imports
import org.openrndr.applicationSynchronous
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.shadeStyle
import org.openrndr.draw.vertexBuffer
import org.openrndr.draw.vertexFormat
import org.openrndr.extensions.Screenshots
import org.openrndr.extra.noise.Random
import org.openrndr.math.Polar
import org.openrndr.shape.ShapeContour
fun main() = applicationSynchronous {
    configure {
        width = 800
        height = 800
    }
    program {
        val geometry = vertexBuffer(vertexFormat {
            position(3)
            color(4)
        }, 100)

        extend(Screenshots())
        extend {
            drawer.clear(ColorRGBa.WHITE)
            drawer.shadeStyle = shadeStyle {
                fragmentTransform = "x_fill = va_color;"
            }
            val line = ShapeContour.fromPoints(List(geometry.vertexCount / 2) {
                val theta = it * 10.0 + seconds * 20
                val radius = 200.0 + 80 * Random.perlin(theta * 0.01, 1.0)
                Polar(theta, radius).cartesian + drawer.bounds.center
            }, false)
            
            val points = geometry.vertexCount / 2
            geometry.put {
                for (i in 0 until points) {
                    val pc = i / (points - 1.0)
                    val color = ColorRGBa.GRAY.mix(ColorRGBa.PINK, pc).toVector4()
                    val pos = line.position(pc)
                    val normal = line.normal(pc).normalized *
                            (40 + 20 * Random.perlin(pos * 0.01))
                    write((pos + normal).vector3(z = 0.0))
                    write(color)
                    write((pos - normal).vector3(z = 0.0))
                    write(color)
                }
            }
            drawer.vertexBuffer(geometry, DrawPrimitive.TRIANGLE_STRIP)
        }
    }
}

1 Like