pxl8/demo/mod/cube3d.fnl

252 lines
8.6 KiB
Text
Raw Normal View History

2025-10-06 18:14:07 -05:00
(local pxl8 (require :pxl8))
(local debug-ui (require :mod.debug_ui))
(var angle-x 0)
(var angle-y 0)
(var angle-z 0)
2025-11-15 08:30:51 -06:00
(var auto-rotate? true)
2025-11-19 22:18:08 -06:00
(var orthographic? false)
2025-11-15 08:30:51 -06:00
(var wireframe? true)
2025-10-06 18:14:07 -05:00
(var time 0)
(var zoom 5.0)
(var texture-id nil)
2025-11-15 08:30:51 -06:00
(var use-texture? false)
(var affine? false)
2025-10-06 18:14:07 -05:00
(var cam-x 0)
(var cam-y 2)
(var cam-z 12)
(var cam-yaw 0)
(var cam-pitch -0.2)
2025-11-15 08:30:51 -06:00
(var show-debug-ui? false)
2025-10-06 18:14:07 -05:00
(var fps 0)
(var fps-accumulator 0)
(var fps-frame-count 0)
2025-11-01 15:31:05 -05:00
(fn init []
(set angle-x 0)
(set angle-y 0)
(set angle-z 0)
2025-11-15 08:30:51 -06:00
(set auto-rotate? true)
2025-11-19 22:18:08 -06:00
(set orthographic? false)
2025-11-15 08:30:51 -06:00
(set wireframe? true)
2025-11-01 15:31:05 -05:00
(set time 0)
(set zoom 5.0)
2025-11-15 08:30:51 -06:00
(set use-texture? false)
(set affine? false)
2025-11-01 15:31:05 -05:00
(set cam-x 0)
(set cam-y 2)
(set cam-z 12)
(set cam-yaw 0)
(set cam-pitch -0.2)
2025-11-15 08:30:51 -06:00
(set show-debug-ui? false)
2025-11-01 15:31:05 -05:00
(set fps 0)
(set fps-accumulator 0)
(set fps-frame-count 0)
(set texture-id (pxl8.load_sprite "res/sprites/pxl8_logo.ase"))
(pxl8.upload_atlas))
2025-10-06 18:14:07 -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]])
(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]]}])
(fn get-face-color [face-idx]
(let [colors [12 22 30 16 28 20]]
(. colors (+ 1 (% face-idx 6)))))
(fn update [dt]
(set time (+ time dt))
(set fps-accumulator (+ fps-accumulator dt))
(set fps-frame-count (+ fps-frame-count 1))
(when (>= fps-accumulator 0.25)
(set fps (/ fps-frame-count fps-accumulator))
(set fps-accumulator 0)
(set fps-frame-count 0))
2025-10-06 19:00:03 -05:00
(let [wheel-y (pxl8.mouse_wheel_y)]
(when (and (not= wheel-y 0) (not (pxl8.ui_has_mouse_focus)))
2025-11-15 08:30:51 -06:00
(if orthographic?
2025-10-06 19:00:03 -05:00
(set zoom (math.max 0.5 (math.min (- zoom (* wheel-y 0.2)) 10.0)))
(let [zoom-speed 0.5
forward-x (* (math.sin cam-yaw) wheel-y zoom-speed)
forward-z (* (math.cos cam-yaw) wheel-y zoom-speed)]
(set cam-x (+ cam-x forward-x))
(set cam-z (- cam-z forward-z))))))
2025-10-06 18:14:07 -05:00
(let [move-speed 5.0
rot-speed 2.0
2025-10-06 19:00:03 -05:00
zoom-speed 2.0
2025-10-06 18:14:07 -05:00
forward-x (* (math.sin cam-yaw) move-speed dt)
forward-z (* (math.cos cam-yaw) move-speed dt)
right-x (* (math.cos cam-yaw) move-speed dt)
right-z (* (- (math.sin cam-yaw)) move-speed dt)]
2025-11-15 08:30:51 -06:00
(if orthographic?
2025-10-06 19:00:03 -05:00
(do
(when (pxl8.key_down "w")
(set zoom (math.max 0.5 (- zoom (* zoom-speed dt)))))
(when (pxl8.key_down "s")
(set zoom (math.min 10.0 (+ zoom (* zoom-speed dt)))))
(when (pxl8.key_down "a")
(set cam-x (- cam-x right-x))
(set cam-z (- cam-z right-z)))
(when (pxl8.key_down "d")
(set cam-x (+ cam-x right-x))
(set cam-z (+ cam-z right-z)))
(when (pxl8.key_down "q")
(set cam-y (- cam-y (* move-speed dt))))
(when (pxl8.key_down "e")
(set cam-y (+ cam-y (* move-speed dt)))))
(do
(when (pxl8.key_down "w")
(set cam-x (+ cam-x forward-x))
(set cam-z (- cam-z forward-z)))
(when (pxl8.key_down "s")
(set cam-x (- cam-x forward-x))
(set cam-z (+ cam-z forward-z)))
(when (pxl8.key_down "a")
(set cam-x (- cam-x right-x))
(set cam-z (- cam-z right-z)))
(when (pxl8.key_down "d")
(set cam-x (+ cam-x right-x))
(set cam-z (+ cam-z right-z)))
(when (pxl8.key_down "q")
(set cam-y (- cam-y (* move-speed dt))))
(when (pxl8.key_down "e")
(set cam-y (+ cam-y (* move-speed dt))))))
2025-10-06 18:14:07 -05:00
(when (pxl8.key_down "left")
(set cam-yaw (- cam-yaw (* rot-speed dt))))
(when (pxl8.key_down "right")
(set cam-yaw (+ cam-yaw (* rot-speed dt))))
(when (pxl8.key_down "up")
(set cam-pitch (+ cam-pitch (* rot-speed dt))))
(when (pxl8.key_down "down")
(set cam-pitch (- cam-pitch (* rot-speed dt))))
(set cam-pitch (math.max -1.5 (math.min cam-pitch 1.5))))
(when (pxl8.key_pressed " ")
2025-11-15 08:30:51 -06:00
(set wireframe? (not wireframe?)))
2025-10-06 18:14:07 -05:00
(when (pxl8.key_pressed "f")
2025-11-15 08:30:51 -06:00
(set affine? (not affine?)))
2025-10-06 18:14:07 -05:00
(when (pxl8.key_pressed "p")
2025-11-15 08:30:51 -06:00
(set orthographic? (not orthographic?)))
2025-10-06 18:14:07 -05:00
(when (pxl8.key_pressed "r")
2025-11-15 08:30:51 -06:00
(set auto-rotate? (not auto-rotate?)))
2025-10-06 18:14:07 -05:00
(when (pxl8.key_pressed "t")
2025-11-15 08:30:51 -06:00
(set use-texture? (not use-texture?)))
2025-10-06 18:14:07 -05:00
(when (pxl8.key_pressed "F8")
2025-11-15 08:30:51 -06:00
(set show-debug-ui? (not show-debug-ui?))
(pxl8.ui_window_set_open "Debug Menu (F8)" show-debug-ui?))
2025-10-06 18:14:07 -05:00
2025-11-15 08:30:51 -06:00
(when auto-rotate?
2025-10-06 18:14:07 -05:00
(set angle-x (+ angle-x (* dt 0.7)))
(set angle-y (+ angle-y (* dt 0.5)))
(set angle-z (+ angle-z (* dt 0.3)))))
2025-11-01 15:31:05 -05:00
(fn draw-cube [pos scale rotation-offset]
(let [[x y z] pos
2025-11-19 22:18:08 -06:00
model (-> (pxl8.mat4_translate x y z)
2025-11-01 15:31:05 -05:00
(pxl8.mat4_multiply (pxl8.mat4_rotate_z (+ angle-z (* rotation-offset 0.7))))
2025-11-19 22:18:08 -06:00
(pxl8.mat4_multiply (pxl8.mat4_rotate_y (+ angle-y (* rotation-offset 1.3))))
(pxl8.mat4_multiply (pxl8.mat4_rotate_x (+ angle-x rotation-offset)))
(pxl8.mat4_multiply (pxl8.mat4_scale scale scale scale)))]
2025-11-01 15:31:05 -05:00
(pxl8.set_model model))
(let [vertices (make-cube-vertices)]
2025-11-15 08:30:51 -06:00
(if (and use-texture? texture-id)
2025-11-01 15:31:05 -05:00
(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)))))))
2025-10-06 18:14:07 -05:00
(fn frame []
2025-11-15 11:55:00 -06:00
(pxl8.clear 0)
2025-10-06 18:14:07 -05:00
(pxl8.clear_zbuffer)
2025-11-15 08:30:51 -06:00
(pxl8.set_affine_textures affine?)
2025-10-06 18:14:07 -05:00
(pxl8.set_backface_culling true)
2025-11-15 08:30:51 -06:00
(pxl8.set_wireframe wireframe?)
2025-10-06 18:14:07 -05:00
2025-11-15 08:30:51 -06:00
(if orthographic?
2025-10-06 19:00:03 -05:00
(let [size zoom
2025-10-06 18:14:07 -05:00
aspect (/ (pxl8.get_width) (pxl8.get_height))
w (* size aspect)
h size]
(pxl8.set_projection (pxl8.mat4_ortho (- w) w (- h) h 1.0 100.0)))
(let [aspect (/ (pxl8.get_width) (pxl8.get_height))
fov (* (/ 60.0 180.0) 3.14159)]
(pxl8.set_projection (pxl8.mat4_perspective fov aspect 0.1 100.0))))
(let [target-x (* (math.sin cam-yaw) (math.cos cam-pitch))
2025-10-07 10:32:48 -05:00
target-y (math.sin cam-pitch)
2025-10-06 18:14:07 -05:00
target-z (* (- (math.cos cam-yaw)) (math.cos cam-pitch))
look-x (+ cam-x target-x)
look-y (+ cam-y target-y)
look-z (+ cam-z target-z)]
(pxl8.set_view (pxl8.mat4_lookat [cam-x cam-y cam-z] [look-x look-y look-z] [0 1 0])))
2025-11-01 15:31:05 -05:00
(draw-cube [0 0 0] 1.0 0)
(draw-cube [-3 0 -4] 0.8 0.5)
(draw-cube [3 1 -7] 0.9 1.2)
(draw-cube [0 -2 -10] 1.1 -0.7)
2025-10-06 18:14:07 -05:00
2025-11-15 08:30:51 -06:00
(let [new-state (debug-ui.render {:show-debug-ui show-debug-ui?
2025-10-07 10:32:48 -05:00
:fps fps
2025-11-15 08:30:51 -06:00
:wireframe wireframe?
:auto-rotate auto-rotate?
:orthographic orthographic?
:use-texture use-texture?
:affine affine?})]
(when (not= new-state.show-debug-ui nil) (set show-debug-ui? new-state.show-debug-ui))
(when (not= new-state.wireframe nil) (set wireframe? new-state.wireframe))
(when (not= new-state.auto-rotate nil) (set auto-rotate? new-state.auto-rotate))
(when (not= new-state.orthographic nil) (set orthographic? new-state.orthographic))
(when (not= new-state.use-texture nil) (set use-texture? new-state.use-texture))
(when (not= new-state.affine nil) (set affine? new-state.affine))))
2025-10-06 18:14:07 -05:00
2025-11-01 15:31:05 -05:00
{:init init
:update update
2025-10-07 10:32:48 -05:00
:frame frame}