render: font: Export a default-font procedure.
[chickadee.git] / chickadee / render / framebuffer.scm
CommitLineData
d89629e4
DT
1;;; Chickadee Game Toolkit
2;;; Copyright © 2017 David Thompson <davet@gnu.org>
3;;;
4;;; Chickadee is free software: you can redistribute it and/or modify
5;;; it under the terms of the GNU General Public License as published
6;;; by the Free Software Foundation, either version 3 of the License,
7;;; or (at your option) any later version.
8;;;
9;;; Chickadee is distributed in the hope that it will be useful, but
10;;; WITHOUT ANY WARRANTY; without even the implied warranty of
11;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12;;; General Public License for more details.
13;;;
14;;; You should have received a copy of the GNU General Public License
15;;; along with this program. If not, see
16;;; <http://www.gnu.org/licenses/>.
17
18;;; Commentary:
19;;
20;; Render to texture.
21;;
22;;; Code:
23
24(define-module (chickadee render framebuffer)
25 #:use-module (oop goops)
26 #:use-module (ice-9 match)
27 #:use-module (srfi srfi-9)
28 #:use-module (system foreign)
29 #:use-module (gl)
30 #:use-module (gl enums)
a9fab8b7 31 #:use-module (chickadee math matrix)
d89629e4
DT
32 #:use-module (chickadee render gl)
33 #:use-module (chickadee render gpu)
34 #:use-module ((chickadee render texture) #:select (make-texture null-texture))
6a913492 35 #:use-module (chickadee render viewport)
d89629e4
DT
36 #:export (make-framebuffer
37 framebuffer?
38 framebuffer-texture
6a913492 39 framebuffer-viewport
a9fab8b7 40 framebuffer-projection
d89629e4
DT
41 null-framebuffer
42 apply-framebuffer
43 *framebuffer-state*))
44
45(define (generate-framebuffer)
46 "Generate a new OpenGL framebuffer object."
47 (let ((bv (u32vector 1)))
48 (gl-gen-framebuffers 1 (bytevector->pointer bv))
49 (u32vector-ref bv 0)))
50
51(define (generate-renderbuffer)
52 "Generate a new OpenGL renderbuffer object."
53 (let ((bv (u32vector 1)))
54 (gl-gen-renderbuffers 1 (bytevector->pointer bv))
55 (u32vector-ref bv 0)))
56
57(define-record-type <framebuffer>
a9fab8b7 58 (%make-framebuffer id renderbuffer-id texture viewport projection)
d89629e4
DT
59 framebuffer?
60 (id framebuffer-id)
61 (renderbuffer-id framebuffer-renderbuffer-id)
6a913492 62 (texture framebuffer-texture)
a9fab8b7
DT
63 (viewport framebuffer-viewport)
64 (projection framebuffer-projection))
d89629e4
DT
65
66(define null-framebuffer
a9fab8b7 67 (%make-framebuffer 0 0 null-texture null-viewport (make-identity-matrix4)))
d89629e4
DT
68
69(define <<framebuffer>> (class-of null-framebuffer))
70
71(define (free-framebuffer framebuffer)
72 (gl-delete-renderbuffers 1
73 (bytevector->pointer
74 (u32vector
75 (framebuffer-renderbuffer-id framebuffer))))
76 (gl-delete-framebuffers 1
77 (bytevector->pointer
78 (u32vector
79 (framebuffer-id framebuffer)))))
80
81(define-method (gpu-finalize (framebuffer <<framebuffer>>))
82 (free-framebuffer framebuffer))
83
84(define (apply-framebuffer framebuffer)
85 (gl-bind-framebuffer (version-3-0 framebuffer)
86 (framebuffer-id framebuffer)))
87
88(define *framebuffer-state*
89 (make-gpu-state apply-framebuffer null-framebuffer))
90
91(define make-framebuffer
92 (let ((draw-buffers (u32vector (version-3-0 color-attachment0))))
93 (lambda* (width height #:key (min-filter 'linear) (mag-filter 'linear)
94 (wrap-s 'repeat) (wrap-t 'repeat))
95 "Create a new framebuffer that renders to a texture with
96dimensions WIDTH x HEIGHT."
97 (let* ((framebuffer-id (generate-framebuffer))
98 (renderbuffer-id (generate-renderbuffer))
99 (texture (make-texture #f width height
1a344160 100 #:flip? #t
d89629e4
DT
101 #:min-filter min-filter
102 #:mag-filter mag-filter
103 #:wrap-s wrap-s
104 #:wrap-t wrap-t))
a9fab8b7
DT
105 ;; It is convenient to make a default viewport and
106 ;; projection matrix for the framebuffer so that the
107 ;; rendering engine can set it whenever it changes to
108 ;; this framebuffer, saving users the trouble of having
109 ;; to this tedious task themselves.
6a913492 110 (viewport (make-viewport 0 0 width height))
a9fab8b7 111 (projection (orthographic-projection 0 width height 0 0 1))
d89629e4
DT
112 (framebuffer (%make-framebuffer framebuffer-id
113 renderbuffer-id
6a913492 114 texture
a9fab8b7
DT
115 viewport
116 projection)))
d89629e4
DT
117 (gpu-state-set! *framebuffer-state* framebuffer)
118 ;; Setup depth buffer.
119 (gl-bind-renderbuffer (version-3-0 renderbuffer)
120 renderbuffer-id)
121 (gl-renderbuffer-storage (version-3-0 renderbuffer)
122 (pixel-format depth-component)
123 width
124 height)
125 (gl-framebuffer-renderbuffer (version-3-0 framebuffer)
126 (arb-framebuffer-object depth-attachment)
127 (version-3-0 renderbuffer)
128 renderbuffer-id)
129 ;; Setup framebuffer.
130 (gl-framebuffer-texture-2d (version-3-0 framebuffer)
131 (version-3-0 color-attachment0)
132 (texture-target texture-2d)
133 ((@@ (chickadee render texture) texture-id)
134 texture)
135 0)
136 (gl-draw-buffers 1 (bytevector->pointer draw-buffers))
137 ;; Check for errors.
138 (unless (= (gl-check-framebuffer-status (version-3-0 framebuffer))
139 (version-3-0 framebuffer-complete))
140 (error "Framebuffer cannot be created"))
141 framebuffer))))