;;;; wh-engine/render/shader.lisp ;;;; Lisp class for holding & handling shaders. ;; (in-package wh-engine/render) (defun replace-cross-referenced-vars (forms vars replace-fun) (loop for elt on forms for form = (car elt) if (symbolp form) do (let ((var-entry (find form vars :key #'car))) (when var-entry (rplaca elt (funcall replace-fun var-entry)))) else if (consp form) do (collect-cross-referenced-vars (cdr form)))) (defun transpile-shader (name &key version ((:in vert-inputs)) ((:inter inter-vars)) ((:out frag-outputs)) ((:uniform uniform-vars)) ((:vert vert-body)) ((:frag frag-body))) "Translate Lisp shader code to GLSL." (list (collect-shader-vars vert-body) (collect-shader-vars frag-body))) (defmacro define-shader (name (&key ((:in (&rest vert-inputs)) ()) ((:inter (&rest inter-vars)) ()) ((:out (&rest frag-outputs)) ()) ((:uniform (&rest uniform-vars)) ())) &key ((:vert (&body vert-body))) ((:frag (&body frag-body))) version) "Define a GLSL shader with Lisp code." `(defparameter ,name (transpile-shader ',name :version ,version :in ',vert-inputs :inter ',inter-vars :out ',frag-outputs :uniform ',uniform-vars :vert ',vert-body :frag ',frag-body)))