;;;; ;;; Particle Effect Examples (NeHe Lesson #19) (in-package :xlui) (use-package :iter) (defparameter *max-particles* 1000) (defparameter *rainbow-colors* '((1.0 0.5 0.5) (1.0 0.75 0.5) (1.0 1.0 0.5) (0.75 1.0 0.5) (0.5 1.0 0.5) (0.5 1.0 0.75) (0.5 1.0 1.0) (0.5 0.75 1.0) (0.5 0.5 1.0) (0.75 0.5 1.0) (1.0 0.5 1.0) (1.0 0.5 0.75))) (defclass particle-view (agent-3d-view) ((rainbow-p :accessor rainbow-p :initarg :rainbow :initform nil))) (defmethod init ((view particle-view)) (glShadeModel GL_SMOOTH) (glClearDepth 1.0d0) (glDisable GL_DEPTH_TEST) (glEnable gl_blend) (glBlendFunc GL_SRC_ALPHA GL_ONE) (glHint GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST) (glHint GL_POINT_SMOOTH_HINT GL_NICEST) (glEnable GL_TEXTURE_2D)) (defstruct gl-particle active life fade ;; Life and fade control how long particle is displayed and how brightly it appears. r g b x y z ;; position xi yi zi ;; direction xg yg zg) ;; Gravity (defclass particle-effect (agent-3d) ((particles :accessor particles :initarg :particles :initform nil) (max-particles :accessor max-particles :initarg :max-particles :initform 1000))) (defmethod initialize-instance :after ((self particle-effect) &rest initargs) (declare (ignore initargs)) (with-slots (particles max-particles) self (setf particles (make-array max-particles)) (dotimes (i max-particles) (setf (svref particles i) (make-gl-particle :active t :life 1.0 :fade (+ (/ (random 100) 1000.0) 0.003) :r (first (nth (floor (* i (/ 12 max-particles))) *rainbow-colors*)) :g (second (nth (floor (* i (/ 12 max-particles))) *rainbow-colors*)) :b (third (nth (floor (* i (/ 12 max-particles))) *rainbow-colors*)) :x 0.0 :y 0.0 :z 0.0 :xi (* (- (random 50) 26.0) 10.0) :yi (* (- (random 50) 25.0) 10.0) :zi (* (- (random 50) 25.0) 10.0) :xg 0.0 :yg -0.8 :zg 0.0))))) (defmethod draw ((self particle-effect)) (with-slots (particles) self (iter (for particle in-vector particles) (when (gl-particle-active particle) (let ((x (gl-particle-x particle)) (y (gl-particle-y particle)) (z (gl-particle-z particle))) (glColor4f (gl-particle-r particle) (gl-particle-g particle) (gl-particle-b particle) (gl-particle-life particle)) (gl:with-gl GL_TRIANGLE_STRIP (glTexCoord2f 1.0 1.0) (glVertex3f (+ x 0.5) (+ y 0.5) z) (glTexCoord2f 0.0 1.0) (glVertex3f (- x 0.5) (+ y 0.5) z) (glTexCoord2f 1.0 0.0) (glVertex3f (+ x 0.5) (- y 0.5) z) (glTexCoord2f 0.0 0.0) (glVertex3f (- x 0.5) (- y 0.5) z)) (incf (gl-particle-x particle) (/ (gl-particle-xi particle) 2000.0)) (incf (gl-particle-y particle) (/ (gl-particle-yi particle) 2000.0)) (incf (gl-particle-z particle) (/ (gl-particle-zi particle) 2000.0)) (incf (gl-particle-xi particle) (gl-particle-xg particle)) (incf (gl-particle-yi particle) (gl-particle-yg particle)) (incf (gl-particle-zi particle) (gl-particle-zg particle)) (decf (gl-particle-life particle) (gl-particle-fade particle)) (when (< (gl-particle-life particle) 0.0) (setf (gl-particle-life particle) 1.0 (gl-particle-fade particle) (+ (/ (random 100) 1000.0) 0.003) (gl-particle-x particle) 0.0 (gl-particle-y particle) 0.0 (gl-particle-z particle) 0.0 (gl-particle-xi particle) (- (random 60) 30.0) (gl-particle-yi particle) (- (random 60) 30.0) (gl-particle-zi particle) (- (random 60) 30.0)))))))) (defun nehe-lesson-19 () (slui (:application-window :title "NeHe Lesson #19 - Particle Effects" (:particle-view :name "ParticleView" (:particle-effect)))))