summaryrefslogtreecommitdiff
path: root/bonnie-bee/background.scm
blob: 943499368fc3529a97dfe872e52af8938f0b29e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
(define-module (bonnie-bee background)
  #:use-module (bonnie-bee assets)
  #:use-module (bonnie-bee common)
  #:use-module (chickadee graphics buffer)
  #:use-module (chickadee graphics engine)
  #:use-module (chickadee graphics shader)
  #:use-module (chickadee graphics texture)
  #:use-module (chickadee math)
  #:use-module (chickadee math matrix)
  #:use-module (chickadee math vector)
  #:use-module (chickadee scripting)
  #:use-module (chickadee utils)
  #:use-module (oop goops)
  #:use-module (catbird node)
  #:use-module (catbird node-2d)
  #:export (<background>
            scroll-y))

(define (make-background-shader)
  (strings->shader
   "
#ifdef GLSL330
layout (location = 0) in vec2 position;
layout (location = 1) in vec2 tex;
#elif defined(GLSL130)
in vec2 position;
in vec2 tex;
#elif defined(GLSL120)
attribute vec2 position;
attribute vec2 tex;
#endif
#ifdef GLSL120
varying vec2 fragTex;
#else
out vec2 fragTex;
#endif
uniform mat4 mvp;

void main(void) {
    fragTex = tex;
    gl_Position = mvp * vec4(position.xy, 0.0, 1.0);
}
"
   "
#ifdef GLSL120
varying vec2 fragTex;
#else
in vec2 fragTex;
#endif
#ifdef GLSL330
out vec4 fragColor;
#else
#define fragColor gl_FragColor
#endif
uniform sampler2D image;
uniform float scrollY;

void main (void) {
    vec2 uv = vec2(fragTex.x, fragTex.y + scrollY);
    fragColor = texture(image, uv);
}
"))

(define-geometry-type <background-vertex>
  background-vertex-ref
  background-vertex-set!
  background-vertex-append!
  (position vec2)
  (texture vec2))

(define (make-background-geometry)
  (let* ((g (make-geometry <background-vertex> 4 #:index-capacity 6))
         (x1 0.0)
         (y1 0.0)
         (x2 (exact->inexact %game-width))
         (y2 (exact->inexact %game-height))
         (s1 0.0)
         (t1 0.0)
         (s2 1.0)
         (t2 1.0))
    (with-geometry g
      (background-vertex-append! g
                                 (x1 y1 s1 t1)
                                 (x2 y1 s2 t1)
                                 (x2 y2 s2 t2)
                                 (x1 y2 s1 t2))
      (geometry-index-append! g 0 3 2 0 2 1))
    g))

(define-class <background> (<node-2d>)
  (scroll-y #:accessor scroll-y #:init-value 0.0)
  (texture #:accessor texture #:init-keyword #:texture #:asset? #t)
  (shader #:getter shader #:init-thunk make-background-shader)
  (geometry #:getter geometry #:init-thunk make-background-geometry)
  (mvp-matrix #:getter mvp-matrix #:init-thunk make-identity-matrix4))

(define-method (default-width (background <background>))
  (texture-width (texture background)))

(define-method (default-height (background <background>))
  (texture-height (texture background)))

(define-method (render (background <background>) alpha)
  (let ((mvp (mvp-matrix background))
        (t (texture background)))
    (matrix4-mult! mvp (world-matrix background) (current-projection))
    (with-graphics-state ((g:texture-0 t))
      (shader-apply (shader background)
                    (geometry-vertex-array (geometry background))
                    #:scroll-y (/ (scroll-y background) (texture-height t))
                    #:mvp mvp))))