pxl8/demo/cube3d.fnl

152 lines
4.8 KiB
Text
Raw Normal View History

2025-10-04 04:13:48 -05:00
(local pxl8 (require :pxl8))
(var angle-x 0)
(var angle-y 0)
(var angle-z 0)
(var auto-rotate true)
(var orthographic true)
(var wireframe true)
(var time 0)
(var zoom 5.0)
2025-10-05 16:25:17 -05:00
(var texture-id nil)
(var use-texture false)
(var affine false)
(var texture-initialized false)
(fn init-texture []
(when (not texture-initialized)
(pxl8.load_palette "sprites/pxl8_logo.ase")
(set texture-id (pxl8.load_sprite "sprites/pxl8_logo.ase"))
(pxl8.upload_atlas)
(set texture-initialized true)))
2025-10-04 04:13:48 -05:00
(fn make-cube-vertices []
[[-1 -1 -1] [1 -1 -1] [1 1 -1] [-1 1 -1]
[-1 -1 1] [1 -1 1] [1 1 1] [-1 1 1]])
(fn make-cube-faces []
[[0 1 2] [0 2 3]
[1 5 6] [1 6 2]
[5 4 7] [5 7 6]
[4 0 3] [4 3 7]
[3 2 6] [3 6 7]
[4 5 1] [4 1 0]])
2025-10-05 16:25:17 -05:00
(fn make-cube-faces-with-uvs []
[{:tri [0 1 2] :uvs [[0 0] [1 0] [1 1]]}
{:tri [0 2 3] :uvs [[0 0] [1 1] [0 1]]}
{:tri [1 5 6] :uvs [[0 0] [1 0] [1 1]]}
{:tri [1 6 2] :uvs [[0 0] [1 1] [0 1]]}
{:tri [5 4 7] :uvs [[0 0] [1 0] [1 1]]}
{:tri [5 7 6] :uvs [[0 0] [1 1] [0 1]]}
{:tri [4 0 3] :uvs [[0 0] [1 0] [1 1]]}
{:tri [4 3 7] :uvs [[0 0] [1 1] [0 1]]}
{:tri [3 2 6] :uvs [[0 0] [1 0] [1 1]]}
{:tri [3 6 7] :uvs [[0 0] [1 1] [0 1]]}
{:tri [4 5 1] :uvs [[0 0] [1 0] [1 1]]}
{:tri [4 1 0] :uvs [[0 0] [1 1] [0 1]]}])
2025-10-04 04:13:48 -05:00
(fn get-face-color [face-idx]
(let [colors [12 22 30 16 28 20]]
(. colors (+ 1 (% face-idx 6)))))
(fn cube-update [dt]
(set time (+ time dt))
(when (pxl8.key_down "w")
(set angle-x (- angle-x (* dt 2.0))))
(when (pxl8.key_down "s")
(set angle-x (+ angle-x (* dt 2.0))))
(when (pxl8.key_down "a")
(set angle-y (- angle-y (* dt 2.0))))
(when (pxl8.key_down "d")
(set angle-y (+ angle-y (* dt 2.0))))
(when (pxl8.key_down "q")
(set angle-z (- angle-z (* dt 2.0))))
(when (pxl8.key_down "e")
(set angle-z (+ angle-z (* dt 2.0))))
(when (pxl8.key_pressed " ")
(set wireframe (not wireframe)))
2025-10-05 16:25:17 -05:00
(when (pxl8.key_pressed "f")
(set affine (not affine)))
2025-10-04 04:13:48 -05:00
(when (pxl8.key_pressed "p")
(set orthographic (not orthographic)))
2025-10-05 16:25:17 -05:00
(when (pxl8.key_pressed "r")
(set auto-rotate (not auto-rotate)))
(when (pxl8.key_pressed "t")
(set use-texture (not use-texture))
(when use-texture
(init-texture)))
2025-10-04 04:13:48 -05:00
(when (pxl8.key_down "=")
(set zoom (- zoom (* dt 2.0))))
(when (pxl8.key_down "-")
(set zoom (+ zoom (* dt 2.0))))
(set zoom (math.max 1.0 (math.min zoom 20.0)))
(when auto-rotate
(set angle-x (+ angle-x (* dt 0.7)))
(set angle-y (+ angle-y (* dt 0.5)))
(set angle-z (+ angle-z (* dt 0.3)))))
(fn cube-frame []
(pxl8.clr 0)
(pxl8.clear_zbuffer)
2025-10-05 16:25:17 -05:00
(pxl8.set_affine_textures affine)
2025-10-04 04:13:48 -05:00
(pxl8.set_backface_culling true)
2025-10-05 16:25:17 -05:00
(pxl8.set_wireframe wireframe)
2025-10-04 04:13:48 -05:00
(if orthographic
(let [size (* 2.5 (/ zoom 5.0))
aspect (/ (pxl8.get_width) (pxl8.get_height))
w (* size aspect)
h size]
(pxl8.set_projection (pxl8.mat4_ortho (- w) w (- h) h 1.0 50.0)))
(let [aspect (/ (pxl8.get_width) (pxl8.get_height))
fov (/ 3.14159 (+ 2.0 (/ zoom 5.0)))]
(pxl8.set_projection (pxl8.mat4_perspective fov aspect 1.0 50.0))))
(pxl8.set_view (pxl8.mat4_lookat [0 0 zoom] [0 0 0] [0 1 0]))
(let [model (-> (pxl8.mat4_identity)
(pxl8.mat4_multiply (pxl8.mat4_rotate_x angle-x))
(pxl8.mat4_multiply (pxl8.mat4_rotate_y angle-y))
(pxl8.mat4_multiply (pxl8.mat4_rotate_z angle-z)))]
(pxl8.set_model model))
2025-10-05 16:25:17 -05:00
(let [vertices (make-cube-vertices)]
(if (and use-texture texture-id)
(let [faces (make-cube-faces-with-uvs)]
(each [i face-data (ipairs faces)]
(let [tri-indices face-data.tri
tri-uvs face-data.uvs
v0 (. vertices (+ 1 (. tri-indices 1)))
v1 (. vertices (+ 1 (. tri-indices 2)))
v2 (. vertices (+ 1 (. tri-indices 3)))
uv0 (. tri-uvs 1)
uv1 (. tri-uvs 2)
uv2 (. tri-uvs 3)]
(pxl8.draw_triangle_3d_textured
v0 v1 v2
uv0 uv1 uv2
texture-id))))
(let [faces (make-cube-faces)]
(each [i face (ipairs faces)]
(let [[i0 i1 i2] face
v0 (. vertices (+ 1 i0))
v1 (. vertices (+ 1 i1))
v2 (. vertices (+ 1 i2))
color (get-face-color (math.floor (/ (- i 1) 2)))]
(pxl8.draw_triangle_3d v0 v1 v2 color))))))
(pxl8.text "WASD/QE: Rotate | +/-: Zoom | Space: Wire | R: Auto | P: Proj" 5 5 15)
(pxl8.text (.. "T: Texture | F: Affine | Mode: "
(if wireframe "Wire" "Fill")
" | Texture: " (if use-texture "On" "Off")
" | Mapping: " (if affine "Affine" "Persp")) 5 15 15))
2025-10-04 04:13:48 -05:00
{:update cube-update
:frame cube-frame}