From b9bccc3de3827f7066060a1e238f871f74ecd00c Mon Sep 17 00:00:00 2001 From: David Thompson Date: Wed, 8 Apr 2020 17:05:58 -0400 Subject: doc: Add "User-Defined Shader Types" section. --- doc/api.texi | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file 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 + 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 constructor predicate @ + (field-type field-name [field-getter] [field-setter]) @dots{} + +Define a new shader data type called @var{}. + +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{} 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 -- cgit v1.2.3