Last active
December 17, 2024 10:05
-
-
Save sloev/a7492af4ccecf7b99f552da0fff660cc to your computer and use it in GitHub Desktop.
quad texture mapping
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import org.openrndr.application | |
| import org.openrndr.draw.* | |
| import org.openrndr.ffmpeg.VideoPlayerConfiguration | |
| import org.openrndr.ffmpeg.VideoPlayerFFMPEG | |
| import org.openrndr.math.Polar | |
| import org.openrndr.math.Vector2 | |
| import org.openrndr.math.Vector3 | |
| import kotlin.math.sin | |
| import org.openrndr.ffmpeg.PlayMode | |
| import org.openrndr.math.mix | |
| class QuadWriter(val vid:VideoPlayerFFMPEG) { | |
| private val vf = vertexFormat { | |
| position(3) | |
| textureCoordinate(2) | |
| } | |
| private val segments =8 | |
| private val quad = vertexBuffer(vf, 6*segments*segments) | |
| fun write(positions: List<Vector3>, textureCoords: List<Vector2>) { | |
| // b | |
| // 1 -- 2 | |
| // | / | | |
| // a | / | c | |
| // | / | | |
| // 0 -- 3 | |
| // d | |
| quad.put { | |
| for (v in 0 until segments) { | |
| for (u in 0 until segments) { | |
| // vertical first | |
| val p0y = mix(positions[0], positions[1], (1.0 * v) / segments) | |
| val p3y = mix(positions[3], positions[2], (1.0 * v) / segments) | |
| val p1y = mix(positions[0], positions[1], (1.0 * (v+1)) / segments) | |
| val p2y = mix(positions[3], positions[2], (1.0 * (v+1)) / segments) | |
| val p0 = mix(p0y, p3y, (1.0 * u) / segments) | |
| val p3 = mix(p0y, p3y, (1.0 * (u+1)) / segments) | |
| val p1 = mix(p1y, p2y, (1.0 * u) / segments) | |
| val p2 = mix(p1y, p2y, (1.0 * (u+1)) / segments) | |
| val t0y = mix(textureCoords[0], textureCoords[1], (1.0 * v) / segments) | |
| val t3y = mix(textureCoords[3], textureCoords[2], (1.0 * v) / segments) | |
| val t1y = mix(textureCoords[0], textureCoords[1], (1.0 * (v+1)) / segments) | |
| val t2y = mix(textureCoords[3], textureCoords[2], (1.0 * (v+1)) / segments) | |
| val t0 = mix(t0y, t3y, (1.0 * u) / segments) | |
| val t3 = mix(t0y, t3y, (1.0 * (u+1)) / segments) | |
| val t1 = mix(t1y, t2y, (1.0 * u) / segments) | |
| val t2 = mix(t1y, t2y, (1.0 * (u+1)) / segments) | |
| write(p0) | |
| write(t0) | |
| write(p1) | |
| write(t1) | |
| write(p3) | |
| write(t3) | |
| write(p1) | |
| write(t1) | |
| write(p2) | |
| write(t2) | |
| write(p3) | |
| write(t3) | |
| } | |
| } | |
| } | |
| } | |
| fun draw(colorBuffer: ColorBuffer, drawer: Drawer) { | |
| drawer.shadeStyle = shadeStyle { | |
| fragmentTransform = "x_fill = texture(p_tex, va_texCoord0.xy);" | |
| parameter("tex", colorBuffer) | |
| } | |
| drawer.vertexBuffer(quad, DrawPrimitive.TRIANGLES) | |
| } | |
| } | |
| fun main() = application { | |
| program { | |
| val videoPlayer = VideoPlayerFFMPEG.fromFile("data/video2.mov", | |
| PlayMode.VIDEO, | |
| VideoPlayerConfiguration().apply { | |
| useHardwareDecoding = false | |
| videoFrameQueueSize = 500 | |
| displayQueueCooldown = 5 | |
| //synchronizeToClock = false | |
| }) | |
| videoPlayer.play() | |
| videoPlayer.ended.listen { | |
| videoPlayer.restart() | |
| } | |
| val renderTarget = renderTarget(width, height) { | |
| colorBuffer() | |
| } | |
| val quadWriter = QuadWriter(videoPlayer) | |
| extend { | |
| drawer.withTarget(renderTarget) { | |
| videoPlayer.draw(drawer) | |
| } | |
| val center = drawer.bounds.center | |
| quadWriter.write( | |
| listOf( | |
| Vector3(50.0, 450.0,0.0), | |
| Vector3(50.0,100.0 ,0.0), | |
| Vector3(550.0, 50.0,0.0), | |
| Vector3(300.0, 400.0,0.0) | |
| ), listOf( | |
| Vector2(0.0, 0.0), | |
| Vector2(0.0, 1.0), | |
| Vector2(1.0, 1.0), | |
| Vector2(1.0, 0.0) | |
| ) | |
| ) | |
| quadWriter.draw(renderTarget.colorBuffer(0), drawer) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment