summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2020-04-08 17:05:58 -0400
committerDavid Thompson <dthompson2@worcester.edu>2020-04-08 17:07:38 -0400
commitb9bccc3de3827f7066060a1e238f871f74ecd00c (patch)
treed188dfa39f9ebcac507ffd5df675a12d7d9b73a6
parent0ecfb6926894c99ae99b1fbd2e90aee685fc3d0a (diff)
doc: Add "User-Defined Shader Types" section.
-rw-r--r--doc/api.texi153
1 files changed, 140 insertions, 13 deletions
diff --git a/doc/api.texi b/doc/api.texi
index 99e225d..9cfa26a 100644
--- a/doc/api.texi
+++ b/doc/api.texi
@@ -3234,6 +3234,29 @@ Return a hash table of uniforms for @var{shader}.
Return a hash table of attributes for @var{shader}.
@end deffn
+@deffn {Procedure} shader-uniform-set! shader uniform value
+@end deffn
+
+@subsubsection Attributes
+
+@deffn {Procedure} attribute? obj
+Return @code{#t} if @var{obj} is an attribute.
+@end deffn
+
+@deffn {Procedure} attribute-name attribute
+Return the variable name of @var{attribute}.
+@end deffn
+
+@deffn {Procedure} attribute-location attribute
+Return the binding location of @var{attribute}.
+@end deffn
+
+@deffn {Procedure} attribute-type attribute
+Return the data type of @var{attribute}.
+@end deffn
+
+@subsubsection Uniforms
+
@deffn {Procedure} uniform? obj
Return @code{#t} if @var{obj} is a uniform.
@end deffn
@@ -3250,24 +3273,128 @@ Return the data type of @var{uniform}.
Return the current value of @var{uniform}.
@end deffn
-@deffn {Procedure} uniform-default-value uniform
-Return the default value of @var{uniform}.
-@end deffn
+@subsubsection User-Defined Shader Types
-@deffn {Procedure} attribute? obj
-Return @code{#t} if @var{obj} is an attribute.
-@end deffn
+The shader examples in this manual thus far have only shown uniforms
+defined using primitive types. However, GLSL shaders support
+user-defined compound structs, such as this one:
-@deffn {Procedure} attribute-name attribute
-Return the variable name of @var{attribute}.
-@end deffn
+@example
+@verbatim
+struct DirectionalLight {
+ vec3 direction;
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+};
+
+uniform DirectionalLight light;
+@end verbatim
+@end example
+
+While @code{light} is declared as a single uniform in the shader code,
+OpenGL translates this into @emph{four} uniforms in this case: One
+uniform each member of the @code{DirectionalLight} struct. This poses
+a problem for sending Scheme data to the GPU. How can compound Scheme
+data translate into compound uniform data on the GPU? The answer is
+with shader types. Shader types are a special kind of Guile struct
+that provide a one-to-one mapping between a Scheme data structure and
+a shader struct.
+
+Some example code will explain this concept best. Here is the Scheme
+equivalent of the @code{DirectionalLight} struct:
+
+@example
+(define-shader-type <directional-light>
+ make-directional-light
+ directional-light?
+ (float-vec3 direction directional-light-direction)
+ (float-vec3 ambient directional-light-ambient)
+ (float-vec3 diffuse directional-light-diffuse)
+ (float-vec3 specular directional-light-specular)
+ (float shininess directional-light-shininess))
+@end example
+
+The macro @code{define-shader-type} closely resembles the familiar
+@code{define-record-type} from SRFI-9, but with one notable
+difference: Each struct field contains type information. The type
+must be one of several primitive types (documented below) or another
+shader type in the case of a nested structure.
+
+It is important to note that the names of the shader type fields
+@emph{must} match the names of the struct members in the GLSL code,
+otherwise Chickadee will be unable to perform the proper translation.
+
+As of this writing, this interface is new and experimental. It
+remains to be seen if this model is robust enough for all use-cases.
+
+Primitive data types:
+
+@defvar bool
+Either @code{#t} or @code{#f}.
+@end defvar
+
+@defvar int
+An integer.
+@end defvar
+
+@defvar unsigned-int
+An unsigned integer.
+@end defvar
+
+@defvar float
+A floating point number.
+@end defvar
+
+@defvar float-vec2
+A 2D vector (@pxref{Vectors}.)
+@end defvar
+
+@defvar float-vec3
+A 3D vector (@pxref{Vectors}.)
+@end defvar
+
+@defvar float-vec4
+A color.
+@end defvar
+
+@defvar mat4
+A matrix (@pxref{Matrices}.)
+@end defvar
+
+@defvar sampler-2d
+A texture (@pxref{Textures}.)
+@end defvar
+
+@defvar local-field
+A special type that means that the data is for the client-side
+(Scheme-side) only and should not be sent to the GPU. Any object may
+be stored in a local field.
+@end defvar
+
+@deffn {Syntax} define-shader-type <name> constructor predicate @
+ (field-type field-name [field-getter] [field-setter]) @dots{}
+
+Define a new shader data type called @var{<name>}.
+
+Instances of this data type are created by calling the
+@var{constructor} procedure. This procedure maps each field to a
+keyword argument. A shader data type with the fields @code{foo},
+@code{bar}, and @code{baz} would have a constructor that accepts the
+keyword arguments @code{#:foo}, @code{#:bar}, and @code{#:baz}.
+
+A procedure named @var{predicate} will test if an object is a
+@var{<name>} shader data type.
+
+Fields follow the format @code{(field-type field-name [field-getter]
+[field-setter])}. @var{field-type} and @var{field-name} are required
+for each field, but @var{field-getter} and @var{field-setter} are
+optional.
-@deffn {Procedure} attribute-location attribute
-Return the binding location of @var{attribute}.
@end deffn
-@deffn {Procedure} attribute-type attribute
-Return the data type of @var{attribute}.
+@deffn {Procedure} shader-data-type? obj
+Return @code{#t} if @var{obj} is a shader data type object.
@end deffn
@node Audio