source: project/wiki/eggref/5/glls @ 37382

Last change on this file since 37382 was 37382, checked in by Kooda, 19 months ago

Document glls for CHICKEN 5

File size: 30.2 KB
Line 
1
2== glls
3[[toc:]]
4glls (GL Lisp Shaders) lets you write [[https://www.opengl.org/documentation/glsl/|GLSL]] (OpenGL Shader Language) shaders in a convenient pseudo-scheme language in Chicken Scheme. The compilation into GLSL happens at compile-time for zero run-time cost. Run-time compilation and dynamic recompilation is also supported. To those that want to dynamically construct shaders: I salute you.
5
6In addition to the eponymous module, glls also provides the {{glls-render}} module. {{glls-render}} enhances glls to create automatic rendering functions for each pipeline. When compiled, these rendering functions are created in efficient C, although dynamic functions are also provided. See the section [[#automatic-render-functions|Automatic render functions]] for details.
7
8The idea for glls was hugely inspired by [[https://github.com/cbaggers/varjo|Varjo]]. Before learning about Varjo, I had never considered the possibility of writing shaders in anything but the GLSL. Seeing them being written in Lisp was a major, "Of course!" moment.
9
10That said, while this library bears some superficial resemblance to Varjo, the approach is quite different. While Varjo does a lot of work to validate the the lispy-glls expressions (including type checking), glls only performs cursory syntactic checking. The result of this is that one could probably write shaders in Varjo without knowing the GLSL and could be reasonably sure that those shaders would always compile to something that would mostly work. glls makes no such promises, so it is entirely possible to generate GLSL that won’t compile. Being able to understand GLSL code is therefore a prerequisite for successful shader debugging. The GLSL code output by glls is beautifully formatted, thanks to Alex Shinn’s amazing [[http://synthcode.com/scheme/fmt/|fmt]] library. fmt is responsible for far more than just the GLSL formatting, since it is basically a compiler of its own. The compilation portion of glsl is more or less a thin layer on top of fmt.
11
12glls should work on Linux, Mac OS X and Windows. Support for OpenGL ES is not yet in an usable state.
13
14
15=== Requirements
16* fmt
17* matchable
18* miscmacros
19* epoxy
20* gl-utils
21* srfi-1
22* srfi-42
23* srfi-69
24
25
26=== Documentation
27glls contains three modules: glls-render, glls, and glls-compiler. glls-render rexports glls and glls-compiler and is used when you want the functionality of glls plus the addition of [[#automatic-render-functions|automatically generated render functions]]. glls is the primary module, providing the main interface to shaders and pipelines, which also rexports glls-compiler. glls-compiler provides the functions used to compile shaders.
28
29<parameter> glsl-version</parameter>
30
31The default GLSL version used by shaders. Defaults to {{120}} on GL ES platforms, {{330}} otherwise. Can also be a list, see {{<version>}} under [[#shader-syntax|Shader syntax]]. When compiling a file with a shader, modifying this parameter will only take effect if you change it before the compilation phase. E.g.:
32
33<enscript highlight="scheme">    
34(import-for-syntax glls)
35(begin-for-syntax (glsl-version 300))
36</enscript>
37
38
39==== Shaders
40<record> (shader TYPE SOURCE INPUTS OUTPUTS UNIFORMS PROGRAM)</record>
41
42Used to represent shaders. Returned by {{define-shader}} and {{create-shader}}. It should not typically be necessary to access the slots of this record.
43
44<macro> (define-shader SHADER-NAME GLLS-SHADER)</macro>
45
46Defines a new {{shader}} named {{NAME}}. The (unquoted) form {{GLLS-SHADER}} should conform to language defined in the section [[#the-glls-shader-language|The glls shader language]]. Before shaders are used, they must be compiled by OpenGL with {{compile-shader}}.
47
48<procedure> (create-shader GLLS-SHADER )</procedure>
49
50Creates (at run-time) a new {{shader}}. The form {{GLLS-SHADER}} should conform to language defined in the section [[#the-glls-shader-language|The glls shader language]]. Before shaders are used, they must be compiled by OpenGL with {{compile-shader}}.
51
52<procedure> (compile-glls GLLS-SHADER)</procedure>
53
54Returns the source string for a shader. The form {{GLLS-SHADER}} should conform to language defined in the section [[#the-glls-shader-language|The glls shader language]].
55
56<procedure> (compile-shader SHADER)</procedure>
57
58Compile (in OpenGL) {{SHADER}}. Nothing is done if the shader has already been compiled. This typically does not need to be called, since {{compile-pipeline}} does so. Must be called while there is an active OpenGL context.
59
60
61==== Pipelines
62''Pipelines'' are the term that glsl uses to describe a collection of shaders that will be linked together. This is equivalent to a GL ''program'', just less ambiguously named.
63
64<record> (pipeline SHADERS ATTRIBUTES UNIFORMS PROGRAM)</record>
65
66Created with {{define-pipeline}} or {{create-pipeline}}, contains the data needed for a pipeline. {{SHADERS}} is the list of shader records. {{ATTRIBUTES}} and {{UNIFORMS}} are lists of the attributes and uniforms of the shader, specified as {{(name . type)}} pairs before compilation (with {{compile-pipeline}} or {{compile-pipelines}}) and {{(name location type)}} lists after compilation. {{PROGRAM}} is the GL ID of the program (always 0 before compilation).
67
68<macro> (define-pipeline PIPELINE-NAME . SHADERS)</macro>
69
70Defines a new {{pipeline}} named {{NAME}}. The {{SHADERS}} should either be forms conforming to language defined in the section [[#the-glls-shader-language|The glls shader language]], {{shader}}s defined by {{define-shader}}, or a mix of the two. Pipelines must have at least one vertex and one fragment shader to be able to compile. Before pipelines are used, they must be compiled by OpenGL with {{compile-pipeline}} or {{compile-pipelines}}.
71
72{{define-pipeline}} behaves differently when it is being evaluated ''and'' when a given pipeline is being redefined. In this case, the new pipeline inherits the GL program ID of the old one. Additionally, the pipeline is compiled by OpenGL right away (and as a consequence, so are any pipelines that are pending compilation). This is done so that pipelines can be edited and reevaluated in a REPL session and one’s scene will be updated as expected. See the [[https://www.upyum.com/cgit.cgi/glls/tree/examples/interactive.scm|interactive example]] for an example of how this can be accomplished.
73
74{{define-pipeline}} has additional effects when used with the {{glls-render}} module (see [[#automatic-render-functions|Automatic render functions]]).
75
76<procedure> (create-pipeline . SHADERS)</procedure>
77
78Creates (at run-time) a new {{pipeline}}. The {{SHADERS}} should either be forms conforming to language defined in the section [[#the-glls-shader-language|The glls shader language]], {{shader}}s, or a mix of the two. Pipelines must have at least one vertex and one fragment shader to be able to compile. Before pipelines are used, they must be compiled by OpenGL with {{compile-pipeline}} or {{compile-pipelines}}.
79
80<procedure> (compile-pipeline PIPELINE)</procedure>
81
82Compile (in OpenGL) the {{PIPELINE}} and sets its {{PROGRAM}} slot to the OpenGL program ID. If the pipeline’s {{PROGRAM}} slot is already set to a non-zero value, this ID will be reused for the new program. Compiles all of the pipeline’s shaders with {{compile-shader}}. Must be called while there is an active OpenGL context.
83
84<procedure> (compile-pipelines)</procedure>
85
86Compile (as per {{compile-pipeline}}) all the pipelines defined by {{define-pipeline}} and {{create-pipeline}}. Must be called while there is an active OpenGL context.
87
88<procedure> (pipeline-uniform UNIFORM PIPELINE)</procedure>
89
90Return the location of {{UNIFORM}}. The {{PIPELINE}} must be compiled before this function can be used.
91
92<procedure> (pipeline-attribute ATTRIBUTE PIPELINE)</procedure>
93
94Return the location of {{ATTRIBUTE}}. The {{PIPELINE}} must be compiled before this function can be used.
95
96<procedure> (pipeline-mesh-attributes PIPELINE)</procedure>
97
98Return a list of {{(ATTRIBUTE-NAME . LOCATION)}} pairs, suitable for passing to [[https://wiki.call-cc.org/egg/gl-utils|gl-utils’]] {{mesh-make-vao!}}.
99
100
101==== The glls shader language
102
103===== Shader syntax
104The shaders of glls – the forms that {{define-shader}}, {{define-pipeline}}, etc. expect – have the following syntax:
105
106    (<type> [input: <inputs>] [uniform: <uniforms>] [output: <outputs>]
107            [version: <version>] [use: <imports>] [export: <exports])
108    <body> ...
109
110{{type}} is the keyword type of the shader. It must be one of {{#:vertex}}, {{#:fragment}}, {{#:geometry}}, {{#:tess-control}}, {{#:tess-evaluation}}, or {{#:compute}}.
111
112{{inputs}} is a list of the input variables for the shader. These are given in {{(name type)}} lists.
113
114{{uniforms}} is a list of the uniform variables for the shader. These are given in {{(name type)}} lists.
115
116{{outputs}} is a list of the output variables from the shader. These are given in {{(name type)}} lists.
117
118{{version}} is the integer version number of the shader, i.e. the number you would write at the top of the shader source (e.g. {{#version 410}}). Defaults to the {{glsl-version}} parameter. This can also be a list of the form {{'(<version> <specifiers> ...)}} where the specifiers will be appended to the {{#version}} line when compiled to glsl. For example, {{'(300 es)}} becomes {{#version 300 es}}.
119
120{{imports}} is the list of shaders that the current shader depends on. See the section [[#shaders-that-export|Shaders that export]] for more details. Defaults to {{()}}
121
122{{exports}} is the list of symbols that the current shader exports. See the section [[#shaders-that-export|Shaders that export]] for more details. Defaults to {{()}}
123
124{{body}} is the form representing the code of the shader. See the section [[#shader-lisp|Shader Lisp]] for an explanation of the kind of code that is expected.
125
126
127===== Shader Lisp
128For the most part, the Lisp used to define glls shaders looks like Scheme with one notable difference: types must be specified whenever a variable or function is defined. Under the hood, forms are being passed to [[https://wiki.call-cc.org/egg/fmt#c-as-s-expressions|fmt]], so everything that you can do there will work in glls. Details of the Lisp used for shaders is provided in the following sections.
129
130It should be possible to do almost anything in glls that you would want to do with the GLSL. Known exceptions to this is are: layout qualifiers (which I don’t feel are terribly relevant in the context of Scheme, at least not until uniform locations become prevalent), do-while loops (which have no Scheme analog), and uniform blocks, {{#line}}, {{#undef}}, and struct uniforms all for no good reason. Let me know if there are any features that you find lacking.
131
132Keep in mind that glls cannot do anything that the GLSL can’t, such as making anonymous or recursive functions.
133
134
135====== Variables and naming
136Symbols in glls are transformed from a Scheme style into the C style used in the GLSL. Letters after dashes are uppercased (i.e., symbols become camelCased). Symbols prefixed by {{gl:}} in glls become prefixed by {{gl_}} in GLSL. {{#f}} and {{#t}} may be used instead of {{false}} and {{true}}.
137
138For programmer-defined variables this has little consequence. The importance of learning the renaming conventions comes when you want to call GLSL functions or variables. Examples of mappings between glls and GLSL names are: {{gl:position}} → {{gl_Position}}, {{float-bits-to-uint}} → {{floatBitsToUint}}, {{shadow-2d-proj-lod}} → {{shadow2DProjLod}}, and {{sampler-2d-ms-array}} → {{sampler2DMSArray}}. Two special cases are {{emit-vertex}} and {{end-primitive}} which are translated into the functions {{EmitVertex}} and {{EndPrimitive}} respectively (which, for some reason, go against the usual GLSL naming conventions).
139
140
141====== Types
142When defining variables or functions in glls, types must be supplied. Basic types (e.g. {{int}}, {{mat2x2}}) are given either as a symbol or keyword (e.g. {{int}}, {{#:mat2x2}}), whichever is preferred. Types with qualifiers (e.g. {{lowp float}}, {{out mediump vec2}}) are given as lists (e.g. {{(lowp float)}}, {{(out mediump vec2)}}).
143
144Arrays are specified as lists beginning with the keyword {{#:array}}. The next element in the list is the type, while the optional third element is the size. E.g. {{(#:array int 5)}}. When used with qualifiers, the array takes the place of the type, e.g. {{(highp (#:array float))}}.
145
146
147====== Functions
148GLSL functions and operators are all called like normal Lisp functions. In almost all cases the GLSL symbol (taking into account the renaming described in [[#variables-and-naming|Variables and naming]] can be used, while many operators can be called with their Scheme counterpart. The only operators that may not be used directly are {{|}}, {{||}}, {{|=}}, {{.}}, {{=}}, and array reference which must be called with their counterparts.
149
150The following is a mapping between glls aliases for GLSL functions and operators:
151
152* {{modulo}}: {{%}}
153* {{expt}}: {{pow}}
154* {{equal?}}, {{eqv?}}, {{eq}}, {{=}}: {{==}}
155* {{set!}}: {{=}}
156* {{and}}: {{&&}}
157* {{or}}: {{||}}
158* {{not}}: {{!}}
159* {{bitwise-and}}: {{&}}
160* {{bitwise-ior}}: {{|}}
161* {{bitwise-xor}}: {{^}}
162* {{bitwise-not}}: {{~}}
163* {{arithmetic-shift}}: {{<<}}
164* {{bitwise-and=}}: {{&=}}
165* {{bitwise-ior=}}: {{|=}}
166* {{bitwise-xor=}}: {{^=}}
167* {{arithmetic-shift=}}: {{<<=}}
168* {{++/post}}: Postfix {{++}}
169* {{--/post}}: Postfix {{--}}
170* {{field}}, {{..}}: {{.}} (struct field reference, e.g. {{(field point x)}} → {{point.x}})
171* {{swizzle}}, {{~~}}: {{.}} (vector swizzling, e.g. {{(swizzle color r g)}} → {{color.rg}})
172* {{array-ref}}, {{vector-ref}}: {{[]}} (array reference, e.g. {{(array-ref a 4)}} → {{a[4]}})
173* {{array-set!}}, {{vector-set!}}: {{[] =}} (array setting, e.g. {{(array-set! a 4 x)}} → {{a[4] = x}})
174* {{length}}: {{.length()}} (vector length, e.g. {{(length vec)}} → {{vec.length()}})
175
176
177====== Definition
178Variables, functions, and records (structs) are defined much like they are in Scheme, with the additional requirement of including types.
179
180    (define <name> <type> [<value>])
181
182Defines the variable {{name}}. When {{type}} is an array, a vector literal (eg. {{#(1 2 3)}}) may be used as the initial {{value}}.
183
184    (define (<name> [(<parameter> <type>) ...]) <return-type> <body> ...)
185
186Defines the function {{name}}. The last expression in the body of a non-void function is automatically returned. If {{body}} is omitted, a function prototype is created.
187
188    (let ((<name> <type> [<value>]) ...) <body> ...)
189
190Defines the supplied variables. When {{type}} is an array, a vector literal (eg. {{#(1 2 3)}}) may be used as the initial {{value}}. Note that, unlike Scheme, the variables created will continue to exist outside of the {{let}} (until the extent of whatever lexical scope the {{let}} exists within). In other words, {{let}} does not introduce scope. Note also that variables defined in {{let}} are within the scope of variables that are subsequently defined in the same {{let}} (i.e. {{let}} functions like {{let*}} in Scheme, and in fact {{let*}} may be used if preferred).
191
192    (define-record <name> (<type> <field>) ...)
193
194Defines the struct {{name}}.
195
196
197====== Control
198The following can be used with identical syntax to scheme:
199
200    (if <test> <true> [<false>])
201   
202    (cond (<test> <result> ...) ... (else <result>))
203   
204    (begin <body> ...)
205
206Keep in mind that they may only be used in the same place as their corresponding GLSL statements, with the exception of {{begin}}, which can only be used where it is possible to have multiple expressions.
207
208Additionally, the following forms can be used for switch/case statements in the GLSL fashion:
209
210    (c-switch <clause> ...)
211   
212    (c-case <values> <body> ...)
213   
214    (c-case/fallthrough <values> <body> ...)
215   
216    (c-default <body> ...)
217
218
219====== Iteration
220    (for <init> <condition> <update> <body> ...)
221
222GLSL style {{for}} loop.
223
224    (do-times (<var> [<start>] <end>) <body> ...)
225
226Equivalent to {{(for (define <var> #:int <start>) (< <var> <end>) (++ <var>) <body> ...)}}. {{start}} defaults to 0.
227
228    (while <condition> <body> ...)
229
230GLSL style {{while}} loop.
231
232
233====== Jumps
234All GLSL jumps ({{continue}}, {{break}}, {{return}}, {{discard}}) can be called like functions. Return may accept one argument. Keep in mind that the last expression in a non void function is automatically returned.
235
236
237====== Pre-processor
238The following forms can be used to add pre-processor directives:
239
240    (%define <name> [<value>])
241   
242    (%if <test> <true> [<false>])
243   
244    (%ifdef <value> <true> [<false>])
245   
246    (%ifndef <value> <true> [<false>])
247   
248    (%elif <value> <true> [<false>])
249   
250    (%else <fallback>)
251   
252    (%error <value> ...)
253   
254    (%pragma [#:stdgl] <name> <behaviour>)
255
256The optional {{#:stdgl}} keyword is used when a {{STDGL}} pragma is desired. {{<name>}} and {{<behaviour>}} will be formatted without modification as {{<name>(<behaviour>)}}.
257
258    (%extension <name> <behaviour>)
259
260{{<name>}} and {{<behaviour>}} will be formatted without modification as {{<name> : <behaviour>}}.
261
262
263==== Shaders that export
264It is often desirable to have shaders that contain generic, reusable functions. These shaders are linked into the pipeline (or program, in GLSL parlance) so that they can be accessed by other shaders. In order for another shader to reuse a function, it first has to (as in C) include a function prototype. glsl automates this process.
265
266glls lets you define shaders that export symbols through the use of the [[#shader-syntax|{{export}} keyword]]. These shaders can then be imported by others (through the [[#shader-syntax|{{use}} keyword]]). Prototypes are automatically generated for top-level functions or variables whose names match the symbols in the {{export}} keyword list. These prototypes are then inserted into shaders that {{use}} the exporting shader. Shaders that are {{use}}d by another are automatically linked into the resulting pipeline.
267
268Shaders that export should not have any inputs or outputs.
269
270See the example [[https://www.upyum.com/cgit.cgi/glls/tree/examples/exports.scm|exports.scm]] to see this in action.
271
272
273==== Automatic render functions
274By using the {{glls-render}} module, you can have glls automatically generate functions that will render an object with your glls pipeline. {{glls-render}} wraps {{define-pipeline}} so that it also defines a set of functions used for rendering and managing the ''renderable'' objects that are specific to that pipeline: one to create them, several to render them, and others to manipulate them. {{glls-render}} should not be used with the {{glls}} module: It reexports everything that you need from {{glls}}.
275
276Recalling {{define-pipeline}}:
277
278    (define-pipeline PIPELINE-NAME . SHADERS)
279
280There is one difference with {{glls-render}}’s {{define-pipeline}}: All shaders must include a list of the shader’s uniforms since the uniforms are the important information needed to derive rendering functions. This means that if you previously define some shaders (for example: {{my-vertex-shader}} and {{my-fragment-shader}}) and you wish to combine them in a pipeline, you ''must'' include the uniforms in the pipeline definition. This is done with a list that takes the form {{(SHADER uniform: [UNIFORM] ...)}}. This list must be present even if the shader does not use any uniforms. For example:
281
282    (define-pipeline my-pipeline
283      (my-vertex-shader uniform: mvp-matrix inverse-transpose-matrix)
284      (my-fragment-shader uniform:))
285
286Of course, if you are defining the shaders in the pipeline, then a separate list of uniforms is not necessary.
287
288
289===== Renderables
290{{glls-render}}’s {{define-piplelines}} defines a function for creating renderable objects:
291
292    (make-PIPELINE-NAME-renderable [vao: VAO] [mode: MODE] [n-elements: N-ELEMENTS] [element-type: ELEMENT-TYPE] [mesh: MESH] [offset: OFFSET] [data: DATA] + PIPELINE-SPECIFIC-KEYWORDS)
293
294Where {{PIPELINE-NAME}} is the name of the pipeline who’s renderables are being created.
295
296* {{VAO}} – A VAO such as those returned by [[https://wiki.call-cc.org/egg/epoxy|epoxy’s]] {{make-vao}}. I.e.: A VAO that binds an array of attributes – for each element in the pipeline – as well as an element array.
297* {{MODE}} – The drawing mode to use when drawing the elements of the VAO. Must be mode that is accepted by (gl-utils’) [[https://api.call-cc.org/5/doc/gl-utils/mode-%3Egl|mode->gl]]. Defaults to {{#:triangles}}.
298* {{N-ELEMENTS}} – The number of elements (vertices) to draw.
299* {{ELEMENT-TYPE}} – The type of the values in the VAO’s element array. Must be one of {{#:unsigned-byte}}, {{#:unsigned-short}}, or {{#:unsigned-int}}. Not required if the VAO has no element array (i.e. {{render-arrays-PIPELINE-NAME}} is being used to render).
300* {{MESH}} – A [[http://wiki.call-cc.org/eggref/4/gl-utils|gl-utils]] mesh, provided in place of {{VAO}}, {{MODE}}, {{N-ELEMENTS}}, and {{ELEMENT-TYPE}}.
301* {{OFFSET}} – A byte offset to the location of the desired indices to draw.
302* {{DATA}} – An optional pointer to an appropriate glls renderable object. If not provided, a fresh renderable object will be created. [[https://www.upyum.com/cgit.cgi/glls/tree/gllsRender.h|gllsRender.h]] defines the structs used for renderables. Which struct is used for a given pipeline is chosen based on the number of uniforms present in the pipeline.
303
304See the [[https://www.opengl.org/sdk/docs/man/html/glDrawElements.xhtml|{{glDrawElements}} documentation]] for more information about these expected arguments.
305
306{{make-PIPELINE-NAME-renderable}} also expects one keyword argument for each uniform in the pipeline. These arguments should either be an f32vector, an s32vector, a u32vector, a pointer to the uniform data, or – in the case of a texture – a fixnum. Even if the uniform is a single value (e.g. a float), it must still be passed as a vector (or a pointer). This lets the value of the uniform be updated independently of the renderable.
307
308Additionally, there are a number of renderable setters for each of the keyword arguments accepted by {{make-PIPELINE-NAME-renderable}}:
309
310<procedure> (set-renderable-vao! RENDERABLE VAO)</procedure>
311<procedure> (set-renderable-n-elements! RENDERABLE N-ELEMENTS)</procedure>
312<procedure> (set-renderable-element-type! RENDERABLE TYPE)</procedure>
313<procedure> (set-renderable-mode! RENDERABLE MODE)</procedure>
314<procedure> (set-renderable-offset! RENDERABLE OFFSET)</procedure>
315   
316    (set-PIPELINE-NAME-renderable-UNIFORM-NAME! RENDERABLE UNIFORM-VALUE)
317
318These setters accept two arguments: a renderable and a value. The values correspond to those that {{make-PIPELINE-NAME-renderable}} accepts. For each uniform in the pipeline, a function named {{set-PIPELINE-NAME-renderable-UNIFORM-NAME!}} is created.
319
320<procedure> (renderable-size PIPELINE)</procedure>
321
322Returns the size, in bytes, of the memory needed for a renderable belonging to {{PIPELINE}}.
323
324
325===== Rendering renderables
326    (render-PIPELINE-NAME RENDERABLE)
327    (render-arrays-PIPELINE-NAME RENDERABLE)
328
329Where {{PIPELINE-NAME}} is the name of the pipeline who’s renderables are being rendered. {{render-PIPELINE-NAME}} and {{render-arrays-PIPELINE-NAME}} both render the given renderable.
330
331These render functions work differently depending on whether the {{define-pipeline}} has been compiled or interpreted (although the end results should look the same). When {{define-pipeline}} is compiled, the resulting render functions are compiled directly to efficient (non-branching) C. When {{define-pipeline}} is interpreted, the render functions call a generic rendering function that is not nearly as fast.
332
333The {{render-PIPELINE-NAME}} function draws the renderable using {{draw-elements}}. While this is typically the most efficient way to render a set of vertices, sometimes {{draw-arrays}} is preferable. {{render-arrays-PIPELINE-NAME}} functions identically except for calling {{draw-arrays}} instead of {{draw-elements}}.
334
335
336====== Fast render functions
337When compiled, the render function defined by {{define-pipeline}} is actually a combination of three “fast” render functions: a ''begin-render'' function, a ''render'' function, and an ''end-render'' function. The array rendering function is a similar combination: the ''begin-render'' function, an ''array-render'' function and the ''end-render'' function. This is done so that, if desired, all of the renderables that belong to the same pipeline may be rendered at the same time, without needing to perform expensive calls like program changes or texture binding more than once. To use these functions, call the ''begin-render'' function with the first renderable, then call the ''render'' (or ''array-render'') function on all renderables (including the first), finally calling the ''end-render'' function (with no arguments) to clean up.
338
339    (PIPELINE-NAME-fast-render-functions)
340
341{{define-pipeline}} does not define all of the render functions separately, but instead defines a single function with which to access them: {{PIPELINE-NAME-fast-render-functions}}, where {{PIPELINE-NAME}} is the name of the pipeline. This function returns eight values: the ''begin-render'' function, the ''render'' function, the ''end-render'' function, the ''array-render'' function, and pointers to those same C functions in that order.
342
343<parameter> unique-textures?</parameter>
344
345This parameter, defaulting to {{#t}}, controls where textures are bound in the fast render functions. When {{unique-textures?}} is {{#t}}, textures are bound in the main render function. When {{unique-textures?}} is {{#f}}, textures are bound in the begin render function. In other words: when {{unique-textures?}} is {{#f}}, it is assumed that that all of the renderables belonging to the same pipeline share a common “sprite sheet” (or other shared texture type). This parameter must be set for syntax (i.e. in a {{begin-for-syntax}} form) in order to have an effect.
346
347
348===== Utilities
349<macro> (export-pipeline . PIPELINES)</macro>
350
351Since glls-render causes {{define-pipeline}} to define multiple functions, this macro exports everything related to each pipeline in {{PIPELINES}}, except for the {{set-PIPELINE-NAME-renderable-UNIFORM!}} setters. These must be exported individually.
352
353
354=== Examples
355These examples depends on the [[https://wiki.call-cc.org/egg/glfw3|glfw3]] egg for window and context creation. The examples presented here illustrate only very basic shader definition and loading. For more complete examples, see the [[https://www.upyum.com/cgit.cgi/glls/tree/examples|examples directory]] of the source.
356
357Aside from knowing how to write glls shaders, only one macro, one function, and one record is necessary to use glls: {{define-pipeline}}, {{compile-pipelines}}, and the record {{pipeline}}. This example illustrates this minimal pipeline creation
358
359<enscript highlight="scheme">    
360(import scheme glls (prefix glfw3 glfw:) (prefix epoxy gl:))
361
362(define-pipeline foo
363  ((#:vertex input: ((vertex #:vec2) (color #:vec3))
364             uniform: ((mvp #:mat4))
365             output: ((c #:vec3)))
366   (define (main) #:void
367     (set! gl:position (* mvp (vec4 vertex 0.0 1.0)))
368     (set! c color)))
369  ((#:fragment input: ((c #:vec3))
370               output: ((frag-color #:vec4)))
371   (define (main) #:void
372     (set! frag-color (vec4 c 1.0)))))
373
374(glfw:with-window (640 480 "Example" resizable: #f)
375   (compile-pipelines)
376   (print foo)
377   (gl:use-program (pipeline-program foo)))
378</enscript>
379
380This example is similar to the first, but also illustrates the ability to define pipelines in different ways.
381
382<enscript highlight="scheme">    
383(import scheme glls (prefix glfw3 glfw:) (prefix epoxy gl:))
384
385(define-pipeline foo
386  ((#:vertex input: ((vertex #:vec2) (color #:vec3))
387                             uniform: ((mvp #:mat4))
388                             output: ((c #:vec3)))
389   (define (main) #:void
390     (set! gl:position (* mvp (vec4 vertex 0.0 1.0)))
391     (set! c color)))
392  ((#:fragment input: ((c #:vec3))
393               output: ((frag-color #:vec4)))
394   (define (main) #:void
395     (set! frag-color (vec4 c 1.0)))))
396
397(define-shader bar (#:vertex input: ((vertex #:vec2) (color #:vec3))
398                             uniform: ((mvp #:mat4))
399                             output: ((c #:vec3)))
400  (define (main) #:void
401    (set! gl:position (* mvp (vec4 vertex 0.0 1.0)))
402    (set! c color)))
403
404(define-pipeline baz
405  bar
406  (cadr (pipeline-shaders foo)))
407
408(glfw:with-window (640 480 "Example" resizable: #f)
409   (compile-pipelines)
410   (print foo)
411   (print baz))
412</enscript>
413
414
415=== Version history
416
417==== Version 0.12.0
41816 March 2019
419
420* Maintenance given to [[/users/kooda|Kooda]]
421* Port to CHICKEN 5
422
423
424==== Version 0.11.0
42523 January 2014
426
427* Overhaul compiler so new syntax can be introduced, and so existing syntax more closely maps to GLSL
428* Add array initialization
429* Move {{pragma}} and {{extension}} from keywords to forms
430
431
432==== Version 0.10.0
43325 December 2014
434
435* Export {{set-renderable-*!}} functions
436
437
438==== Version 0.9.0
43924 December 2014
440
441* Add {{unique-textures?}} parameter
442* {{export-pipeline}} exports primary setters
443* Better renderable setter error values
444
445
446==== Version 0.8.0
4478 December 2014
448
449* Add {{draw-array}} render functions
450* Support OpenGL ES
451* Bug fixes
452
453
454==== Version 0.7.0
45520 October 2014
456
457* Renderable element-type and mode setters take keywords instead of integers
458
459
460==== Version 0.6.0
46110 September 2014
462
463* Integrate with gl-utils’ meshes
464* Remove obsolete {{load-ply-renderable}}
465
466
467==== Version 0.5.2
46824 August 2014
469
470* Update to new gl-utils
471
472'''Version 0.5.1'''
473
474* Allow {{#t}}, {{#f}}
475* Fix swizzle
476
477'''Version 0.5.0'''
478
47914 August 2014
480
481* New shader syntax
482
483
484==== Version 0.4.1
48512 August 2014
486
487* Fix export name matching
488
489'''Version 0.4.0'''
490
49111 August 2014
492
493* Add shader exports
494* Add function prototyping
495* Add {{export-pipeline}}
496* Add aliases to {{field}}, {{swizzle}} ({{..}}, {{~~}})
497* Export {{renderable-size}} rather than {{allocate-renderable}}
498* Improve error messages
499* Bug fixes
500
501
502==== Version 0.3.3
5034 June 2014
504
505* Bug fixes relating to dynamic reevaluated pipelines
506
507'''Version 0.3.2'''
508
5093 June 2014
510
511* Update examples for GC safety
512
513'''Version 0.3.1'''
514
5152 June 2014
516
517* Fix {{load-ply-renderable}}
518* Fix gllsRender.h
519
520'''Version 0.3.0'''
521
52230 May 2014
523
524* Support dynamic reevaluation of pipelines
525
526
527==== Version 0.2.2
52829 May 2014
529
530* Add make as a dependency
531
532'''Version 0.2.1'''
533
534* Fix bug affecting dynamic use of glls-render
535
536'''Version 0.2.0'''
537
53828 May 2014
539
540* Automatic render function generation
541* Removed {{eval}} from {{defpipeline}} (which broke some things when used in modules)
542* Renamed {{defpipeline}}, {{defshader}}
543
544
545==== Version 0.1.0
546* Initial release
547
548
549=== Source repository
550Source available [[https://www.upyum.com/cgit.cgi/glls/|here]].
551
552Bug reports and patches welcome! Bugs can be reported to kooda@upyum.com
553
554
555=== Authors
556Alex Charlton
557
558Adrien (Kooda) Ramos
559
560
561=== Licence
562BSD
563
Note: See TracBrowser for help on using the repository browser.