summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chickadee/graphics/particles.scm132
1 files changed, 49 insertions, 83 deletions
diff --git a/chickadee/graphics/particles.scm b/chickadee/graphics/particles.scm
index 167f5c7..8048ba1 100644
--- a/chickadee/graphics/particles.scm
+++ b/chickadee/graphics/particles.scm
@@ -77,7 +77,7 @@ indefinitely."
(and life (<= life 0))))
(define-record-type <particles>
- (%make-particles capacity size bv buffer shader vertex-array
+ (%make-particles capacity size bv shader geometry
texture animation-rows animation-columns
speed-range acceleration-range direction-range
blend-mode start-color end-color lifetime
@@ -86,9 +86,8 @@ indefinitely."
(capacity particles-capacity)
(size particles-size set-particles-size!)
(bv particles-bv)
- (buffer particles-buffer)
(shader particles-shader)
- (vertex-array particles-vertex-array)
+ (geometry particles-geometry)
(texture particles-texture set-particles-texture!)
(animation-rows particles-animation-rows)
(animation-columns particles-animation-columns)
@@ -120,16 +119,22 @@ indefinitely."
layout (location = 0) in vec2 position;
layout (location = 1) in vec2 tex;
layout (location = 2) in vec2 offset;
-layout (location = 3) in float life;
+layout (location = 3) in vec2 velocity;
+layout (location = 4) in vec2 acceleration;
+layout (location = 5) in float life;
#elif defined(GLSL130)
in vec2 position;
in vec2 tex;
in vec2 offset;
+in vec2 velocity;
+in vec2 acceleration;
in float life;
#elif defined(GLSL120)
attribute vec2 position;
attribute vec2 tex;
attribute vec2 offset;
+attribute vec2 velocity;
+attribute vec2 acceleration;
attribute float life;
#endif
#ifdef GLSL120
@@ -180,55 +185,21 @@ void main (void) {
}
"))
-(define (make-particles-vertex-array capacity width height texture buffer)
- (let* ((indices (make-buffer-view #:type 'scalar
- #:component-type 'unsigned-int
- #:divisor 0
- #:buffer (make-buffer
- (u32vector 0 3 2 0 2 1)
- #:target 'index)))
- (verts (make-buffer-view #:type 'vec2
- #:component-type 'float
- #:divisor 0
- #:buffer (make-buffer
- ;; TODO: use the texture
- ;; size in pixels.
- (let ((hw (/ width 2.0))
- (hh (/ height 2.0)))
- (f32vector (- hw) (- hh)
- hw (- hh)
- hw hh
- (- hw) hh))
- #:target 'vertex)))
- (tex (make-buffer-view #:type 'vec2
- #:component-type 'float
- #:divisor 0
- #:buffer (make-buffer
- (let ((tex (texture-gl-tex-rect
- texture)))
- (f32vector 0 0
- 1 0
- 1 1
- 0 1))
- #:target 'vertex)))
- (pos (make-buffer-view #:name "particle position buffer"
- #:buffer buffer
- #:type 'vec2
- #:component-type 'float
- #:length capacity
- #:divisor 1))
- (life (make-buffer-view #:name "particle life remaining buffer"
- #:buffer buffer
- #:type 'scalar
- #:component-type 'int
- #:offset 24
- #:length capacity
- #:divisor 1)))
- (make-vertex-array #:indices indices
- #:attributes `((0 . ,verts)
- (1 . ,tex)
- (2 . ,pos)
- (3 . ,life)))))
+(define-geometry-type <quad-vertex>
+ quad-vertex-ref
+ quad-vertex-set!
+ quad-vertex-append!
+ (position vec2)
+ (texture vec2))
+
+(define-geometry-type <particle-vertex>
+ particle-vertex-ref
+ particle-vertex-set!
+ particle-vertex-append!
+ (position vec2)
+ (velocity vec2)
+ (acceleration vec2)
+ (life int))
(define* (make-particles capacity #:key
(blend-mode 'alpha)
@@ -302,29 +273,27 @@ default.
- SORT: 'youngest' if youngest particle should be drawn last or
'oldest' for the reverse. By default, no sorting is applied at all."
- (let* ((stride (+ (* 4 2) ; position - 2x f32
- (* 4 2) ; velocity - 2x f32
- (* 4 2) ; acceleration - 2x f32
- 4)) ; life remaining - 1x s32
- (buffer (make-buffer #f
- #:name "packed particle data"
- ;; One extra element to use as
- ;; swap space for sorting
- ;; particles.
- #:length (* stride capacity)
- #:stride stride
- #:usage 'stream)))
+ (let ((geometry (make-geometry (list (list <quad-vertex> #:capacity 4)
+ (list <particle-vertex> #:divisor 1))
+ capacity
+ #:index-capacity 6)))
+ (with-geometry* geometry (<quad-vertex> 'index)
+ (let ((hw (/ width 2.0))
+ (hh (/ height 2.0)))
+ (quad-vertex-append! geometry
+ ((- hw) (- hh) 0.0 0.0)
+ (hw (- hh) 1.0 0.0)
+ (hw hh 1.0 1.0)
+ ((- hw) hh 0.0 1.0)))
+ (geometry-index-append! geometry 0 3 2 0 2 1))
(%make-particles capacity
0
;; 1 extra element as swap space for sorting.
- (make-bytevector (* (+ capacity 1) stride))
- buffer
+ (make-bytevector (* (+ capacity 1)
+ (geometry-type-stride
+ <particle-vertex>)))
(make-particles-shader)
- (make-particles-vertex-array capacity
- width
- height
- texture
- buffer)
+ geometry
texture
animation-rows
animation-columns
@@ -340,10 +309,7 @@ default.
(define (update-particles particles)
"Advance the simulation of PARTICLES."
- (let* ((buffer (particles-buffer particles))
- (va (particles-vertex-array particles))
- (pos (assq-ref (vertex-array-attributes va) 2))
- (speed-range (particles-speed-range particles))
+ (let* ((speed-range (particles-speed-range particles))
(acceleration-range (particles-acceleration-range particles))
(direction-range (particles-direction-range particles))
(sort (particles-sort particles))
@@ -359,7 +325,7 @@ default.
(ddy-offset 20)
(life-offset 24))
(let* ((bv (particles-bv particles))
- (stride (buffer-stride buffer))
+ (stride (geometry-type-stride <particle-vertex>))
(capacity (particles-capacity particles)))
;; Update existing particles, removing dead ones.
(let loop ((i 0)
@@ -457,20 +423,20 @@ default.
(inner (- j stride))))
(outer (+ i stride)))))
(sort 0 (* (particles-size particles) stride))))
- (with-mapped-buffer buffer
- (bytevector-copy! bv 0 (buffer-data buffer) 0 (* (particles-size particles) stride))))))
+ (with-geometry* (particles-geometry particles) (<particle-vertex>)
+ (geometry-import! (particles-geometry particles) <particle-vertex> bv 0
+ (particles-size particles))))))
(define draw-particles*
(let ((mvp (make-null-matrix4)))
(lambda (particles matrix)
"Render PARTICLES with MATRIX applied."
- (let ((size (particles-size particles))
- (va (particles-vertex-array particles)))
+ (let ((geometry (particles-geometry particles)))
(with-blend-mode (particles-blend-mode particles)
(with-texture 0 (particles-texture particles)
(gpu-apply/instanced (particles-shader particles)
- va
- size
+ (geometry-vertex-array geometry)
+ (particles-size particles)
#:mvp (if matrix
(begin
(matrix4-mult! mvp matrix