Files
orx/orx-mesh-generators/src/jvmDemo/kotlin/decal/DemoDecal02.kt
2025-01-24 23:05:40 +01:00

86 lines
3.0 KiB
Kotlin

package decal
import org.openrndr.application
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.isolated
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.camera.Orbital
import org.openrndr.extra.objloader.loadOBJMeshData
import org.openrndr.extra.mesh.toVertexBuffer
import org.openrndr.extra.meshgenerators.decal.decal
import org.openrndr.math.Vector3
import org.openrndr.math.transforms.buildTransform
import java.io.File
import kotlin.math.PI
/**
* Demonstrate decal generation and rendering
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal02Kt.png">
*/
fun main() = application {
configure {
width = 720
height = 720
}
program {
/** base object */
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj"))
.toMeshData() // convert from CompoundMeshData to MeshData
.triangulate() // convert to triangles, we need this for the decal generation steps
/** object [VertexBuffer] */
val objVB = obj.toVertexBuffer()
/** positions for the decal projectors */
val decalPositions = listOf(
Vector3(0.35, 0.245, 0.8),
Vector3(-0.35, 0.245, 0.8)
)
/** decal vertex buffers */
val decalVBs = decalPositions.map {
val projector = buildTransform {
translate(it)
}
val decal = obj.decal(projector, Vector3(2.0, 2.0, 0.5))
val vb = decal.toVertexBuffer()
vb
}
extend(Orbital()) {
eye = Vector3(0.0, 0.0, 2.0)
}
extend {
/* draw the base mesh */
drawer.isolated {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """x_fill.rgb = vec3(v_viewNormal * 0.5 + 0.5); """
}
drawer.vertexBuffer(objVB, DrawPrimitive.TRIANGLES)
}
/* draw the decals */
drawer.isolated {
for ((index, decal) in decalVBs.withIndex()) {
/* offset the projection transform to avoid z-fighting */
drawer.projection = buildTransform {
translate(0.0, 0.0, -1e-4)
} * drawer.projection
/* draw effects on the decal geometry */
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
float d = length(va_texCoord0.xy - vec2(0.5));
float sd = smoothstep(-0.01, 0.01, cos(p_time + d * 3.1415 * 2.0 * 10.0));
float l = max(0.0, va_normal.z);
x_fill = vec4(0.0, 0.0, 0.0, l * sd * 0.5); """
parameter("time", seconds * PI * 2 + index * PI)
}
drawer.vertexBuffer(decal, DrawPrimitive.TRIANGLES)
}
}
}
}
}