diff options
-rw-r--r-- | chickadee/graphics/9-patch.scm | 112 |
1 files changed, 47 insertions, 65 deletions
diff --git a/chickadee/graphics/9-patch.scm b/chickadee/graphics/9-patch.scm index c023b25..dc14bc7 100644 --- a/chickadee/graphics/9-patch.scm +++ b/chickadee/graphics/9-patch.scm @@ -21,6 +21,7 @@ #:use-module (chickadee graphics blend) #:use-module (chickadee graphics color) #:use-module (chickadee graphics engine) + #:use-module (chickadee graphics seagull) #:use-module (chickadee graphics shader) #:use-module (chickadee graphics texture) #:use-module (chickadee graphics buffer) @@ -39,72 +40,53 @@ (define-graphics-variable 9-patch-model-matrix (make-null-matrix4)) (define-graphics-variable 9-patch-mvp-matrix (make-null-matrix4)) (define-graphics-variable 9-patch-margins (make-null-rect)) +(define-vertex-shader 9-patch-vertex + ((in vec2 position) + (in vec2 distance) + (out vec2 frag-distance) + (uniform mat4 mvp)) + (outputs + (vertex:position (* mvp (vec4 (-> position x) (-> position y) 0.0 1.0))) + (frag-distance distance))) +(define-fragment-shader 9-patch-fragment + ((in vec2 frag-distance) + (out vec4 frag-color) + (uniform vec4 subtexture) + (uniform vec4 margins) + (uniform float width) + (uniform float height) + (uniform sampler-2d color-texture) + (uniform vec4 tint) + (uniform int mode)) + (let ((patch (lambda (d m0 m1 length tex-length) + (cond + ;; Inside the left/bottom margin. + ((<= d m0) + (* d tex-length)) + ;; Inside the right/top margin. + ((>= d (- length m1)) + (- tex-length (* (- length d) tex-length))) + ;; In the middle: stretch mode. + ((= mode 0) + (mix m0 (- tex-length m1) (/ (- d m0) (- length m0 m1)))) + ;; In the middle: tile mode. + (else + (+ m0 (mod (- d m0) (- tex-length m0 m1)))))))) + (let ((texcoord (+ (vec2 (-> subtexture x) (-> subtexture y)) + (vec2 (patch (-> frag-distance x) + (-> margins x) + (-> margins y) + width + (-> subtexture z)) + (patch (-> frag-distance y) + (-> margins z) + (-> margins w) + height + (-> subtexture w)))))) + (outputs + (frag-color (* (texture-2d color-texture texcoord) tint)))))) (define-graphics-variable 9-patch-shader - (strings->shader - " -#ifdef GLSL330 -layout (location = 0) in vec2 position; -layout (location = 1) in vec2 distance; -#elif defined(GLSL130) -in vec2 position; -in vec2 distance; -#elif defined(GLSL120) -attribute vec2 position; -attribute vec2 distance; -#endif -#ifdef GLSL120 -varying vec2 fragDistance; -#else -out vec2 fragDistance; -#endif -uniform mat4 mvp; - -void main(void) { - fragDistance = distance; - gl_Position = mvp * vec4(position.xy, 0.0, 1.0); -} -" - " -#ifdef GLSL120 -varying vec2 fragDistance; -#else -in vec2 fragDistance; -#endif -#ifdef GLSL330 -out vec4 fragColor; -#endif -uniform vec4 subtexture; -uniform vec4 margins; -uniform float width; -uniform float height; -uniform sampler2D colorTexture; -uniform vec4 tint; -uniform int mode; - -float patch(float d, float m0, float m1, float length, float texLength) { - if(d <= m0) { // inside the left/bottom margin. - return d * texLength; - } else if(d >= length - m1) { // inside the right/top margin. - return texLength - ((length - d) * texLength); - } else if(mode == 0) { // in the middle, stretch mode. - return mix(m0, texLength - m1, (d - m0) / (length - m0 - m1)); - } else { // in the middle, tile mode. - return m0 + mod((d - m0), texLength - m0 - m1); - } -} - -void main (void) { - vec2 texcoord = subtexture.xy; - texcoord.x += patch(fragDistance.x, margins.x, margins.y, width, subtexture.z); - texcoord.y += patch(fragDistance.y, margins.z, margins.w, height, subtexture.w); - -#ifdef GLSL330 - fragColor = texture(colorTexture, texcoord) * tint; -#else - gl_FragColor = texture2D(colorTexture, texcoord) * tint; -#endif -} -")) + (compile-shader 9-patch-vertex 9-patch-fragment)) (define* (draw-9-patch* texture rect |