diff options
-rw-r--r-- | chickadee/graphics/particles.scm | 199 |
1 files changed, 120 insertions, 79 deletions
diff --git a/chickadee/graphics/particles.scm b/chickadee/graphics/particles.scm index d8bd1b2..6801c39 100644 --- a/chickadee/graphics/particles.scm +++ b/chickadee/graphics/particles.scm @@ -29,6 +29,7 @@ #:use-module (chickadee graphics color) #:use-module (chickadee graphics engine) #:use-module (chickadee graphics shader) + #:use-module (chickadee graphics seagull) #:use-module (chickadee graphics texture) #:export (make-particle-emitter particle-emitter? @@ -87,82 +88,121 @@ indefinitely." particle-vertex-set! particle-vertex-append! (position vec2) + (life int) (velocity vec2) - (acceleration vec2) - (life int)) + (acceleration vec2)) + +(define-vertex-shader particles-vertex + ((in vec2 position) + (in vec2 tex) + (in vec2 offset) + (in float life) + (out vec2 frag-tex) + (out float frag-t) + (uniform mat4 mvp) + (uniform int lifetime) + (uniform int animation-rows) + (uniform int animation-columns)) + (let* ((p (+ position offset)) + (t (/ life lifetime)) + (num-tiles (* animation-rows animation-columns)) + (tile (float->int (* num-tiles (- 1.0 t)))) + (tx (/ (mod tile animation-columns) + animation-columns)) + (ty (/ (int->float (/ tile animation-columns)) + animation-columns)) + (tw (/ 1.0 animation-columns)) + (th (/ 1.0 animation-rows))) + (outputs + (vertex:position (* mvp (vec4 (-> p x) (-> p y) 0.0 1.0))) + (frag-tex (+ (vec2 tx ty) (* tex (vec2 tw th)))) + (frag-t t)))) + +(define-fragment-shader particles-fragment + ((in vec2 frag-tex) + (in float frag-t) + (out vec4 frag-color) + (uniform sampler-2d color-texture) + (uniform vec4 start-color) + (uniform vec4 end-color)) + (outputs + (frag-color (* (mix end-color start-color frag-t) + (texture-2d color-texture frag-tex))))) (define-graphics-variable particles-shader - (strings->shader - " -#ifdef GLSL330 -layout (location = 0) in vec2 position; -layout (location = 1) in vec2 tex; -layout (location = 2) in vec2 offset; -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 -varying vec2 fragTex; -varying float t; -#else -out vec2 fragTex; -out float t; -#endif -uniform mat4 mvp; -uniform int lifetime; -uniform int animationRows; -uniform int animationColumns; - -void main(void) { - t = life / lifetime; - int numTiles = animationRows * animationColumns; - int tile = int(numTiles * (1.0 - t)); - float tx = float(mod(tile, animationColumns)) / animationColumns; - float ty = float(tile / animationColumns) / animationRows; - float tw = 1.0 / animationColumns; - float th = 1.0 / animationRows; - fragTex = vec2(tx, ty) + tex * vec2(tw, th); - gl_Position = mvp * vec4(position.xy + offset, 0.0, 1.0); -} -" - " -#ifdef GLSL120 -varying vec2 fragTex; -varying float t; -#else -in vec2 fragTex; -in float t; -#endif -#ifdef GLSL330 -out vec4 fragColor; -#endif -uniform sampler2D color_texture; -uniform vec4 startColor; -uniform vec4 endColor; - -void main (void) { -#ifdef GLSL330 - fragColor = mix(endColor, startColor, t) * texture(color_texture, fragTex); -#else - gl_FragColor = mix(endColor, startColor, t) * texture2D(color_texture, fragTex); -#endif -} -")) + (compile-shader particles-vertex particles-fragment) +;; (strings->shader +;; " +;; #ifdef GLSL330 +;; layout (location = 0) in vec2 position; +;; layout (location = 1) in vec2 tex; +;; layout (location = 2) in vec2 offset; +;; 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 +;; varying vec2 fragTex; +;; varying float t; +;; #else +;; out vec2 fragTex; +;; out float t; +;; #endif +;; uniform mat4 mvp; +;; uniform int lifetime; +;; uniform int animationRows; +;; uniform int animationColumns; + +;; void main(void) { +;; t = life / lifetime; +;; int numTiles = animationRows * animationColumns; +;; int tile = int(numTiles * (1.0 - t)); +;; float tx = float(mod(tile, animationColumns)) / animationColumns; +;; float ty = float(tile / animationColumns) / animationRows; +;; float tw = 1.0 / animationColumns; +;; float th = 1.0 / animationRows; +;; fragTex = vec2(tx, ty) + tex * vec2(tw, th); +;; gl_Position = mvp * vec4(position.xy + offset, 0.0, 1.0); +;; } +;; " +;; " +;; #ifdef GLSL120 +;; varying vec2 fragTex; +;; varying float t; +;; #else +;; in vec2 fragTex; +;; in float t; +;; #endif +;; #ifdef GLSL330 +;; out vec4 fragColor; +;; #endif +;; uniform sampler2D color_texture; +;; uniform vec4 startColor; +;; uniform vec4 endColor; + +;; void main (void) { +;; #ifdef GLSL330 +;; fragColor = mix(endColor, startColor, t) * texture(color_texture, fragTex); +;; #else +;; gl_FragColor = mix(endColor, startColor, t) * texture2D(color_texture, fragTex); +;; #endif +;; } +;; ") + ) (define-graphics-variable mvp-matrix (make-null-matrix4)) @@ -317,12 +357,13 @@ default. (float-set! bytevector-ieee-single-native-set!) (int-ref bytevector-s32-native-ref) (int-set! bytevector-s32-native-set!) + (x-offset 0) (y-offset 4) - (dx-offset 8) - (dy-offset 12) - (ddx-offset 16) - (ddy-offset 20) - (life-offset 24)) + (life-offset 8) + (dx-offset 12) + (dy-offset 16) + (ddx-offset 20) + (ddy-offset 24)) (let* ((bv (particles-bv particles)) (stride (geometry-type-stride <particle-vertex>)) (capacity (particles-capacity particles))) @@ -336,7 +377,7 @@ default. (let ((new-size (- size 1))) (bytevector-copy! bv (* new-size stride) bv offset stride) (loop i new-size)) - (let ((x (float-ref bv offset)) + (let ((x (float-ref bv (+ offset x-offset))) (y (float-ref bv (+ offset y-offset))) (dx (float-ref bv (+ offset dx-offset))) (dy (float-ref bv (+ offset dy-offset))) |