abe
1
Hi! I have the following in my program:
val camera = OrbitalCamera(Vector3.UNIT_Z * 1000.0, Vector3.ZERO, 90.0, 0.1, 2000.0)
val controls = OrbitalControls(camera, keySpeed = 10.0)
extend(camera)
extend(controls)
which affects everything I draw with drawer. How can I draw things that are not affected by the camera?
edwin
2
You’d do this by not using the camera as an extension and setting the view and projection matrices manually.
val camera = OrbitalCamera(Vector3.UNIT_Z * 1000.0, Vector3.ZERO, 90.0, 0.1, 2000.0)
val controls = OrbitalControls(camera, keySpeed = 10.0)
extend(controls)
extend {
camera.update(deltaTime)
// -- draw in ortho here
drawer.isolated {
drawer.perspective(camera.fov, width.toDouble() / height, camera.near, camera.far)
drawer.view = camera.viewMatrix()
drawer.drawStyle.depthWrite = true
drawer.drawStyle.depthTestPass = DepthTestPass.LESS_OR_EQUAL
// draw in perspective here
}
// -- draw in ortho here
}
1 Like
abe
3
Thanks! That works almost perfectly. With that change I get a side effect: polygons seem to have the wrong z-sorting. Why could that be?
Note: to make it compile I used camera.update(deltaTime)
edwin
4
To get the right behaviour you need to enable depth writing and testing. The conventional settings are:
drawer.drawStyle.depthWrite = true
drawer.drawStyle.depthTestPass = DepthTestPass.LESS_OR_EQUAL
Adviced is to place them inside the isolated
block.
1 Like
abe
5
Since camera.update(deltaTime)
would no longer work (deltaTime
no longer exists), I’m sharing a newer approach.
A fixed 2D circle in the background, an interactive 3D shape in the middle, and a fixed 2D ring on front of everything.
imports
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.camera.OrbitalCamera
import org.openrndr.extra.camera.OrbitalControls
import org.openrndr.extra.camera.isolated
import org.openrndr.extra.meshgenerators.boxMesh
import org.openrndr.math.Vector3
fun main() = application {
program {
val box = boxMesh(50.0, 20.0, 5.0)
val camera = OrbitalCamera(Vector3.ONE * 20.0, Vector3.ZERO, 90.0, 0.1, 5000.0)
val controls = OrbitalControls(camera)
val gradientShading = shadeStyle {
fragmentTransform = """
vec3 c = sin(v_worldPosition * 0.1) * 0.5 + 0.5;
c = c * (dot(va_normal, vec3(0.1, 0.2, 0.8)) * 0.5 + 0.5);
x_fill = vec4(c, 1.0);
""".trimIndent()
}
var secondsLast = seconds
//extend(camera)
extend(controls)
extend {
camera.update(seconds - secondsLast)
secondsLast = seconds
// Draw in 2D on the back
drawer.circle(drawer.bounds.center, 200.0)
// Draw in 3D
camera.isolated(drawer) {
drawer.shadeStyle = gradientShading
drawer.vertexBuffer(box, DrawPrimitive.TRIANGLES)
}
// Draw in 2D on the front
drawer.strokeWeight = 4.0
drawer.shadeStyle = null
drawer.fill = null
drawer.stroke = ColorRGBa.WHITE
drawer.circle(drawer.bounds.center, 220.0)
}
}
}
Note: if you don’t need to revert back to 2D (ortho) mode, you can use
camera.applyTo(drawer)
instead of
camera.isolated(drawer) { ... }
which is a tiny bit faster.