update upstream sources
[clinton/guile-figl.git] / figl / gl.scm
CommitLineData
be421aed
AW
1;;; figl
2;;; Copyright (C) 2013 Andy Wingo <wingo@pobox.com>
1547f980 3;;; Copyright (C) 2013 Daniel Hartwig <mandyke@gmail.com>
be421aed
AW
4;;;
5;;; Figl is free software: you can redistribute it and/or modify it
6;;; under the terms of the GNU Lesser General Public License as
7;;; published by the Free Software Foundation, either version 3 of the
8;;; License, or (at your option) any later version.
9;;;
10;;; Figl is distributed in the hope that it will be useful, but WITHOUT
11;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12;;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13;;; Public License for more details.
14;;;
15;;; You should have received a copy of the GNU Lesser General Public
16;;; License along with this program. If not, see
17;;; <http://www.gnu.org/licenses/>.
18
19;;; Commentary:
20;;
21;; OpenGL binding.
22;;
23;;; Code:
24
25(define-module (figl gl)
26 #:use-module (figl runtime)
ea80f801 27 #:use-module (figl gl types)
1547f980 28 #:use-module (figl gl enums)
ea80f801 29 #:use-module ((figl gl low-level) #:renamer (symbol-prefix-proc '%))
0dbdf0cb 30 #:use-module (rnrs bytevectors)
ea80f801 31 #:use-module (system foreign))
be421aed 32
1547f980
DH
33;; Notice there is no #:export clause. Exports are done inline to
34;; facilitate re-exporting low-level bindings (and changing that
35;; choice), and identifying gaps in the API.
36;;
37;; There are two sets of exports for each section. The first is for
38;; bindings defined in the specification, exported in order. The
39;; second is for additional procedures not defined by the spec. but
40;; relevant to the section, for example with-gl-begin.
41;;
42;; At least keep this format until the bindings are fairly complete.
43
44(module-use! (module-public-interface (current-module))
45 (resolve-interface '(figl gl enums)))
46
47;;;
48;;; 2.6 Begin/End Paradigm
49;;;
50
fd9caf2f 51;; emacs: (put 'gl-begin 'scheme-indent-function 1)
276f55f7
DH
52(define-syntax gl-begin
53 (syntax-rules ()
54 ((_ mode body1 body2 ...)
55 (call-with-values
56 (lambda ()
57 (%glBegin mode)
58 body1 body2 ...)
59 (lambda vals
60 (%glEnd)
61 (apply values vals))))))
62
1547f980
DH
63(define (gl-edge-flag flag)
64 (%glEdgeFlag (if flag (boolean true) (boolean false))))
65
276f55f7 66(export-syntax gl-begin)
1547f980
DH
67
68(export gl-edge-flag)
69
1547f980
DH
70;;;
71;;; 2.7 Vertex Specification
72;;;
73
74;; Note that these are float variants only. This has implications for
75;; some functions whose integer variants normalize their arguments.
76;; The corresponding float variants expect normalized input, usually
77;; in the range [0, 1]. Refer to the OpenGL specification for
78;; details.
79;;
80;; For access to non-float variants please use the appropriate
81;; low-level binding.
82
31e76884 83;; TODO: Maybe re-export packed variants here. Unpacked byte
1547f980
DH
84;; variants?
85
86(define* (gl-vertex x y #:optional (z 0.0) (w 1.0))
87 (%glVertex4f x y z w))
88
9b67cdf2 89(define* (gl-texture-coordinates s #:optional (t 0.0) (r 0.0) (q 1.0))
1547f980
DH
90 (%glTexCoord4f s t r q))
91
9b67cdf2 92(define* (gl-multi-texture-coordinates texture s #:optional (t 0.0) (r 0.0) (q 1.0))
1547f980
DH
93 (%glMultiTexCoord4f texture s t r q))
94
95(define* (gl-color red green blue #:optional (alpha 1.0))
96 (%glColor4f red green blue alpha))
97
ea80f801 98(define* (gl-vertex-attribute index x #:optional (y 0.0) (z 0.0) (w 1.0))
1547f980
DH
99 (%glVertexAttrib4f index x y z w))
100
101(export gl-vertex
9b67cdf2
DH
102 gl-texture-coordinates
103 gl-multi-texture-coordinates
ea80f801
DH
104 gl-color
105 gl-vertex-attribute)
1547f980 106
8c6d5fbb 107(re-export (%glNormal3f . gl-normal)
ea80f801 108 (%glFogCoordf . gl-fog-coordinate)
8c6d5fbb
DH
109 (%glSecondaryColor3f . gl-secondary-color)
110 (%glIndexi . gl-index))
1547f980 111
f5128312
AW
112;;;
113;;; 2.8 Vertex Arrays
114;;;
115
116
117(define (->pointer bv-or-pointer offset)
0dbdf0cb
AW
118 (cond
119 ((zero? offset)
120 bv-or-pointer)
121 ((not bv-or-pointer)
122 (make-pointer offset))
123 (else
124 (bytevector->pointer bv-or-pointer offset))))
f5128312
AW
125
126(define-syntax define-gl-array-setter
127 (syntax-rules ()
128 ((_ set-gl-foo-array glFooPointer default-size)
129 (define* (set-gl-foo-array type bv-or-pointer
130 #:optional (size default-size)
131 #:key (stride 0) (offset 0))
132 (glFooPointer size type stride
133 (->pointer bv-or-pointer offset))))))
134
135(define-syntax define-gl-array-setters
136 (syntax-rules ()
137 ((_ (name binding default-size) ...)
138 (begin
139 (define-gl-array-setter name binding default-size)
140 ...))))
141
142(define-gl-array-setters
143 (set-gl-vertex-array %glVertexPointer 3)
144 (set-gl-color-array %glColorPointer 3)
145 (set-gl-secondary-color-array %glSecondaryColorPointer 3)
146 (set-gl-texture-coordinates-array %glTexCoordPointer 2))
147
148(define* (set-gl-normal-array type bv-or-pointer
149 #:key (stride 0) (offset 0))
150 (%glNormalPointer type stride
151 (->pointer bv-or-pointer offset)))
152
153(define* (set-gl-fog-coordinate-array type bv-or-pointer #:optional
154 (stride 0) (offset 0))
155 (%glFogCoordPointer type stride
156 (->pointer bv-or-pointer offset)))
157
158(define* (set-gl-index-array type bv-or-pointer
159 #:key (stride 0) (offset 0))
160 (%glIndexPointer type stride
161 (->pointer bv-or-pointer offset)))
162
163(define* (set-gl-vertex-attribute-array index type normalized? bv-or-pointer
164 #:optional (size 4)
165 #:key (stride 0) (offset 0))
166 (%glVertexAttribPointer index size type normalized? stride
167 (->pointer bv-or-pointer offset)))
168
169(export set-gl-vertex-array
170 set-gl-normal-array
171 set-gl-color-array
172 set-gl-secondary-color-array
173 set-gl-index-array
174 ;; set-gl-edge-flag-array
175 set-gl-fog-coordinate-array
176 set-gl-texture-coordinates-array
177 set-gl-vertex-attribute-array
178 )
179
180(re-export (%glEnableClientState . gl-enable-client-state)
181 (%glDisableClientState . gl-disable-client-state)
182 (%glEnableVertexAttribArray . gl-enable-vertex-attribute-array)
183 (%glDisableVertexAttribArray . gl-disable-vertex-attribute-array)
184 (%glClientActiveTexture . set-gl-client-active-texture))
185
186(re-export (%glArrayElement . gl-array-element)
187 (%glDrawArrays . gl-draw-arrays))
188
189;; TODO: Rest of 2.8 procedures (interleaved-arrays, etc.).
190
0dbdf0cb
AW
191;;;
192;;; 2.9 Buffer Objects
193;;;
194
195(define (gl-generate-buffer)
196 (let ((bv (u32vector 0)))
197 (%glGenBuffers 1 bv)
198 (u32vector-ref bv 0)))
199
200(define (gl-delete-buffer n)
201 (let ((bv (u32vector n)))
202 (%glDeleteBuffers 1 bv)))
203
204(define* (set-gl-buffer-data target data usage
205 #:optional (size (bytevector-length data)))
206 (%glBufferData target size data usage))
207
208(define* (update-gl-buffer-data target data
209 #:optional (size (bytevector-length data))
210 #:key (offset 0))
211 (%glBufferSubData target offset size data))
212
213(re-export (%glBindBuffer . gl-bind-buffer))
214
215(export gl-generate-buffer
216 gl-delete-buffer
217 set-gl-buffer-data
218 update-gl-buffer-data)
219
220;;; TODO: complete
221
1547f980
DH
222;;;
223;;; 2.10 Rectangles
224;;;
225
8c6d5fbb 226(re-export (%glRectf . gl-rectangle))
96e10a21
DH
227
228\f
229;;;
230;;; 2.11 Coordinate Transformation
231;;;
232
233;;;
234;;; 2.11.1 Controlling the Viewport
235;;;
236
8c6d5fbb
DH
237(re-export (%glDepthRange . gl-depth-range)
238 (%glViewport . gl-viewport))
96e10a21
DH
239
240;;;
241;;; 2.11.2 Matrices
242;;;
243
244;; OpengGL matrices are stored in column-major order. This is
245;; different to the usual row-major order used in 2-dimensional
246;; arrays, which will have to be transposed as they loaded.
247
248(define* (gl-load-matrix m #:key (transpose #f))
249 ((if transpose
250 %glLoadTransposeMatrixf
251 %glLoadMatrixf)
252 (array-contents m)))
253
254(define* (gl-multiply-matrix m #:key (transpose #f))
255 ((if transpose
256 %glMultTransposeMatrixf
257 %glMultMatrixf)
258 (array-contents m)))
259
260(export gl-load-matrix
261 gl-multiply-matrix)
262
fd9caf2f 263(re-export (%glMatrixMode . set-gl-matrix-mode)
8c6d5fbb
DH
264 (%glLoadIdentity . gl-load-identity)
265 (%glRotatef . gl-rotate)
266 (%glTranslatef . gl-translate)
267 (%glScalef . gl-scale)
268 (%glFrustum . gl-frustum)
269 (%glOrtho . gl-ortho)
bfac2618 270 (%glActiveTexture . set-gl-active-texture))
96e10a21 271
fd9caf2f 272;; emacs: (put 'with-gl-push-matrix 'scheme-indent-function 0)
96e10a21
DH
273(define-syntax with-gl-push-matrix
274 (syntax-rules ()
275 ((_ body ...)
a53c9512
DH
276 (call-with-values
277 (lambda ()
278 (%glPushmatrix)
279 body ...)
280 (lambda vals
281 (%glPopMatrix)
282 (apply values vals))))))
96e10a21
DH
283
284(export-syntax with-gl-push-matrix)
285
286;;;
287;;; 2.11.3 Normal Transformations
288;;;
289
8c6d5fbb
DH
290(re-export (%glEnable . gl-enable)
291 (%glDisable . gl-disable))
ea80f801 292
fd9caf2f
AW
293;;;
294;;; 2.14 Colors and Coloring
295;;;
296
297(re-export (%glShadeModel . set-gl-shade-model))
298
ea80f801
DH
299\f
300;;;
301;;; 4.1 Per-Fragment Operations
302;;;
303
304(define* (set-gl-stencil-function stencil-function k #:key
305 (mask #xFFFFFFFF) ; 32-bit mask
306 face)
307 (if face
308 (%glStencilFuncSeparate face stencil-function k mask)
309 (%glStencilFunc stencil-function k mask)))
310
311(define* (set-gl-stencil-operation stencil-fail depth-fail depth-pass #:key
312 face)
313 (if face
314 (%glStencilOpSeparate face stencil-fail depth-fail depth-pass)
315 (%glStencilOp stencil-fail depth-fail depth-pass)))
316
317;; TODO: 4.1.7 Occlusion Queries
318
319(define* (set-gl-blend-equation mode-rgb #:optional (mode-alpha mode-rgb))
320 (%glBlendEquationSeparate mode-rgb mode-alpha))
321
322(define* (set-gl-blend-function src-rgb dest-rgb #:optional
323 (src-alpha src-rgb)
324 (dest-alpha dest-rgb))
325 (%glBlendFuncSeparate src-rgb dest-rgb src-alpha dest-alpha))
326
327(export set-gl-stencil-function
328 set-gl-stencil-operation
329 set-gl-blend-equation
330 set-gl-blend-function
331 )
332
333(re-export (%glScissor . set-gl-scissor)
334 (%glSampleCoverage . set-gl-sample-coverage)
335 (%glAlphaFunc . set-gl-alpha-function)
336 (%glDepthFunc . set-gl-depth-function)
337 (%glBlendColor . set-gl-blend-color)
338 (%glLogicOp . set-gl-logic-operation)
339 )
340
341;;;
342;;; 4.2 Whole Framebuffer Operations
343;;;
344
345(define (set-gl-draw-buffers buffers)
346 (let* ((n (length buffers))
347 (buffers (make-c-struct (make-list n (GLenum))
348 buffers)))
349 (%glDrawBuffers n buffers)))
350
351(define* (set-gl-stencil-mask mask #:key face)
352 (if face
353 (%glStencilMaskSeparate face mask)
354 (%glStencilMask mask)))
355
356(export set-gl-draw-buffers
357 set-gl-stencil-mask)
358
359(re-export (%glDrawBuffer . set-gl-draw-buffer)
360 (%glIndexMask . set-gl-index-mask)
361 (%glColorMask . set-gl-color-mask)
362 (%glDepthMask . set-gl-depth-mask)
363 (%glClear . gl-clear)
364 (%glClearColor . set-gl-clear-color)
365 (%glClearIndex . set-gl-clear-index)
366 (%glClearDepth . set-gl-clear-depth)
367 (%glClearStencil . set-gl-clear-stencil-value)
368 (%glClearAccum . set-gl-clear-accumulation-color)
369 (%glAccum . set-gl-accumulation-buffer-operation))
370
371;;;
372;;; 4.3 Drawing, Reading, and Copying Pixels
373;;;
374
375;; TODO: read-pixels
376
377(re-export (%glReadBuffer . set-gl-read-buffer)
378 (%glCopyPixels . gl-copy-pixels))
fd9caf2f
AW
379
380;;;
381;;; 6.1 Querying GL State
382;;;
383
384;; emacs: (put 'with-gl-push-attrib 'scheme-indent-function 1)
385(define-syntax-rule (with-gl-push-attrib bits body ...)
a53c9512
DH
386 (call-with-values
387 (lambda ()
388 (%glPushAttrib bits)
389 body ...)
390 (lambda vals
391 (%glPopAttrib)
392 (apply values vals))))
fd9caf2f
AW
393
394(export with-gl-push-attrib)