;; note that xtlang mmmul is pre-multiplied! (not post as GLSL)
(bind-func xtm_project
(lambda (pt_in:float* pt_out:float* model view projection)
(let ((x (pref pt_in 0))
(y (pref pt_in 1))
(z (pref pt_in 2))
(vp_x (i32tof xtm_render_x)) ;; viewport x
(vp_y (i32tof xtm_render_y)) ;; viewport y
(vp_w (i32tof xtm_render_w))
(vp_h (i32tof xtm_render_h))
(vp_n xtm_render_near)
(vp_f xtm_render_far)
(mvp:float* (salloc 16))
(tmp:float* (salloc 16))
(vec:float* (salloc 4)))
(mmmul model view tmp)
(mmmul tmp projection mvp)
(mmmul pt_in 1 4 mvp 4 4 vec)
(if (<> (pref vec 3) 0.0)
(vsmul vec (/ 1.0 (pref vec 3)) 4 pt_out)) ;; normalize W!
(pset! pt_out 0 (* (+ 1.0 (pref pt_out 0)) 0.5 vp_w))
(pset! pt_out 1 (* (+ 1.0 (pref pt_out 1)) 0.5 vp_h))
(pset! pt_out 2 (+ (* (pref pt_out 2) (- vp_f vp_n)) vp_n))
void)))