diff options
-rw-r--r-- | doc/api.texi | 794 |
1 files changed, 693 insertions, 101 deletions
diff --git a/doc/api.texi b/doc/api.texi index 490a532..7854b53 100644 --- a/doc/api.texi +++ b/doc/api.texi @@ -1074,6 +1074,15 @@ Return the identity quaternion. @node Easings @subsection Easings +Easing functions are essential for animation. Each easing function +provides a different path to go from an initial value to a final +value. These functions make an excellent companion to the +@code{tween} procedure (@pxref{Tweening}). Experiment with them to +figure out which function makes an animation look the best. + +Pro tip: @code{smoothstep} provides nice results most of the time and +creates smoother animation than using @code{linear}. + @deffn {Procedure} linear @var{t} @end deffn @@ -1271,7 +1280,6 @@ tasks like rendering a sprite while also providing all of the building blocks to implement additional rendering techniques. @menu -* Rendering Engine:: Rendering state management. * Textures:: 2D images. * Sprites:: Draw 2D images. * Tile Maps:: Draw 2D tile maps. @@ -1279,100 +1287,13 @@ blocks to implement additional rendering techniques. * Fonts:: Drawing text. * Particles:: Pretty little flying pieces! * Blending and Depth Testing:: Control how pixels are combined. -* Vertex Arrays:: Create 2D/3D models. -* Shaders:: Create custom GPU programs. * Framebuffers:: Render to texture. -* Viewports:: Restrict rendering to +* Viewports:: Restrict rendering to a particular area. +* Rendering Engine:: Rendering state management. +* GPU Buffers:: Send data to the GPU. +* Shaders:: Create custom GPU programs. @end menu -@node Rendering Engine -@subsection Rendering Engine - -Chickadee defines rendering using a metaphor familiar to Scheme -programmers: procedure application. A shader (@pxref{Shaders}) is -like a procedure for the GPU to apply. Shaders are passed arguments: -A vertex array containing the geometry to render (@pxref{Vertex -Arrays}) and zero or more keyword arguments that the shader -understands. Similar to how Scheme has @code{apply} for calling -procedures, Chickadee provides @code{gpu-apply} for calling shaders. - -Additionally, there is some dynamic state that effects how -@code{gpu-apply} will behave. Things like the current viewport, -framebuffer, and blend mode are stored as dynamic state because it -would be tedious to have to have to specify them each time -@code{gpu-apply} is called. - -The following procedures and syntax can be found in the -@code{(chickadee render)} module. - -@deffn {Syntax} gpu-apply @var{shader} @var{vertex-array} @ - [#:uniform-key @var{uniform-value} ...] -@deffnx {Syntax} gpu-apply* @var{shader} @var{vertex-array} @ - @var{count} [#:uniform-key @var{uniform-value} ...] - -Render @var{vertex-array} using @var{shader} with the uniform values -specified in the following keyword arguments. - -While @code{gpu-apply} will draw every vertex in @var{vertex-array}, -@code{gpu-apply*} will only draw @var{count} vertices. - -@end deffn - -@deffn {Procedure} current-viewport -Return the currently bound viewport (@pxref{Viewports}). -@end deffn - -@deffn {Procedure} current-framebuffer -Return the currently bound framebuffer (@pxref{Framebuffers}). -@end deffn - -@deffn {Procedure} current-blend-mode -Return the currently bound blend mode (@pxref{Blending and Depth -Testing}). -@end deffn - -@deffn {Procedure} current-depth-test -Return @code{#t} if depth testing is currently enabled (@pxref{Blending and Depth Testing}). -@end deffn - -@deffn {Procedure} current-texture -Return the currently bound texture (@pxref{Textures}). -@end deffn - -@deffn {Procedure} current-projection -Return the currently bound projection matrix (@pxref{Matrices}). -@end deffn - -@deffn {Syntax} with-viewport @var{viewport} @var{body} ... -Evaluate @var{body} with the current viewport bound to @var{viewport} (@pxref{Viewports}). -@end deffn - -@deffn {Syntax} with-framebuffer @var{framebuffer} @var{body} ... -Evaluate @var{body} with the current framebuffer bound to -@var{framebuffer} (@pxref{Framebuffers}). -@end deffn - -@deffn {Syntax} with-blend-mode @var{blend-mode} @var{body} ... -Evaluate @var{body} with the current blend mode bound to -@var{blend-mode} (@pxref{Blending and Depth Testing}). -@end deffn - -@deffn {Syntax} with-depth-test @var{depth-test?} @var{body} ... -Evaluate @var{body} with the depth-test disabled if @var{depth-test?} -is @code{#f}, or enabled otherwise (@pxref{Blending and Depth -Testing}). -@end deffn - -@deffn {Syntax} with-texture @var{texture} @var{body} ... -Evaluate @var{body} with the current texture bound to @var{texture} -(@pxref{Textures}). -@end deffn - -@deffn {Syntax} with-projection @var{projection} @var{body} ... -Evaluate @var{body} with the current projection matrix bound to -@var{projection} (@pxref{Matrices}). -@end deffn - @node Textures @subsection Textures @@ -1815,17 +1736,38 @@ Remove @var{emitter} to @var{particles} @node Blending and Depth Testing @subsection Blending and Depth Testing -@node Vertex Arrays -@subsection Vertex Arrays +Rendering a scene often involves drawing layers of objects that +overlap each other. Blending determines how two overlapping pixels +are combined in the final image that is rendered to the screen. +Chickadee provides the following blend modes: -@node Shaders -@subsection Shaders +@itemize + +@item @code{replace} +Use the latest color, ignoring all others. + +@item @code{alpha} +Blend pixels according to the values of their alpha channels. This is +the most commonly used blend mode and thus is Chickadee's default +mode. + +@item @code{add} +Add all pixel color values together. The more colors blended +together, the more white the final color becomes. + +@item @code{subtract} +Subtract all pixel color values. The more colors blended together, +the more black the final color becomes. + +@item @code{multiply} -Shaders are programs for the GPU to evaluate. They are written in the -OpenGL Shading Language, or GLSL. Chickadee does not currently -provide a Scheme-like domain specific language for writing shaders. -Since shaders must be written in GLSL and not Scheme, they are -considered an advanced feature. +@item @code{darken} + +@item @code{lighten} + +@item @code{screen} + +@end itemize @node Framebuffers @subsection Framebuffers @@ -1871,6 +1813,656 @@ The default framebuffer. @node Viewports @subsection Viewports +A viewport represents a subset of the screen (or framebuffer). When +rendering a frame, the resulting image will only appear within that +viewport. These aren't often needed, and Chickadee's default viewport +occupies the entire screen, but there are certain situations where +they are useful. For example, a split-screen multiplayer game may +render to two different viewports, each occupying a different half of +the screen. For information about how to set the current viewport, +see @code{with-viewport} in @ref{Rendering Engine}. + +The @code{(chickadee render viewport)} module provides the following +API: + +@deffn {Procedure} make-viewport @var{x} @var{y} @var{width} @var{height} @ + [#:clear-color] [#:clear-flags] + +Create a viewport that covers an area of the window starting from +coordinates (@var{x}, @var{y}) and spanning @var{width} @code{x} +@var{height} pixels. Fill the viewport with @var{clear-color} when +clearing the screen. Clear the buffers denoted by the list of symbols +in @var{clear-flags}. + +Possible values for @var{clear-flags} are @var{color-buffer}, +@var{depth-buffer}, @var{accum-buffer}, and @var{stencil-buffer}. +@end deffn + +@deffn {Procedure} viewport? @var{obj} +Return @code{#t} if @var{obj} is a viewport. +@end deffn + +@deffn {Procedure} viewport-x @var{viewport} +Return the left edge of @var{viewport}. +@end deffn + +@deffn {Procedure} viewport-y @var{viewport} +Return the bottom edge of @var{viewport}. +@end deffn + +@deffn {Procedure} viewport-width @var{viewport} +Return the width of @var{viewport}. +@end deffn + +@deffn {Procedure} viewport-height @var{viewport} +Return the height of @var{viewport}. +@end deffn + +@deffn {Procedure} viewport-clear-color @var{viewport} +Return the clear color for @var{viewport}. +@end deffn + +@deffn {Procedure} viewport-clear-flags @var{viewport} +Return the list of clear flags for @var{viewport}. +@end deffn + +@node Rendering Engine +@subsection Rendering Engine + +Chickadee defines rendering using a metaphor familiar to Scheme +programmers: procedure application. A shader (@pxref{Shaders}) is +like a procedure for the GPU to apply. Shaders are passed arguments: +A vertex array containing the geometry to render (@pxref{GPU Buffers}) +and zero or more keyword arguments that the shader understands. +Similar to how Scheme has @code{apply} for calling procedures, +Chickadee provides @code{gpu-apply} for calling shaders. + +Additionally, there is some dynamic state that effects how +@code{gpu-apply} will behave. Things like the current viewport, +framebuffer, and blend mode are stored as dynamic state because it +would be tedious to have to have to specify them each time +@code{gpu-apply} is called. + +The following procedures and syntax can be found in the +@code{(chickadee render)} module. + +@deffn {Syntax} gpu-apply @var{shader} @var{vertex-array} @ + [#:uniform-key @var{uniform-value} ...] +@deffnx {Syntax} gpu-apply* @var{shader} @var{vertex-array} @ + @var{count} [#:uniform-key @var{uniform-value} ...] + +Render @var{vertex-array} using @var{shader} with the uniform values +specified in the following keyword arguments. + +While @code{gpu-apply} will draw every vertex in @var{vertex-array}, +@code{gpu-apply*} will only draw @var{count} vertices. +@end deffn + +@deffn {Syntax} gpu-apply/instanced @var{shader} @var{vertex-array} @ + @var{n} [#:uniform-key @var{uniform-value} ...] +@deffnx {Syntax} gpu-apply/instanced @var{shader} @var{vertex-array} @ + @var{count} @var{n} [#:uniform-key @var{uniform-value} ...] + +Render @var{vertex-array} @var{n} times using @var{shader} with the +uniform values specified in the following keyword arguments. + +Instanced rendering is very beneficial for rendering the same object +many times with only small differences for each one. For example, the +particle effects described in @ref{Particles} use instanced rendering. + +While @code{gpu-apply/instanced} will draw every vertex in +@var{vertex-array}, @code{gpu-apply*} will only draw @var{count} +vertices. +@end deffn + +@deffn {Procedure} current-viewport +Return the currently bound viewport (@pxref{Viewports}). +@end deffn + +@deffn {Procedure} current-framebuffer +Return the currently bound framebuffer (@pxref{Framebuffers}). +@end deffn + +@deffn {Procedure} current-blend-mode +Return the currently bound blend mode (@pxref{Blending and Depth +Testing}). +@end deffn + +@deffn {Procedure} current-depth-test +Return @code{#t} if depth testing is currently enabled (@pxref{Blending and Depth Testing}). +@end deffn + +@deffn {Procedure} current-texture +Return the currently bound texture (@pxref{Textures}). +@end deffn + +@deffn {Procedure} current-projection +Return the currently bound projection matrix (@pxref{Matrices}). +@end deffn + +@deffn {Syntax} with-viewport @var{viewport} @var{body} ... +Evaluate @var{body} with the current viewport bound to @var{viewport} (@pxref{Viewports}). +@end deffn + +@deffn {Syntax} with-framebuffer @var{framebuffer} @var{body} ... +Evaluate @var{body} with the current framebuffer bound to +@var{framebuffer} (@pxref{Framebuffers}). +@end deffn + +@deffn {Syntax} with-blend-mode @var{blend-mode} @var{body} ... +Evaluate @var{body} with the current blend mode bound to +@var{blend-mode} (@pxref{Blending and Depth Testing}). +@end deffn + +@deffn {Syntax} with-depth-test @var{depth-test?} @var{body} ... +Evaluate @var{body} with the depth-test disabled if @var{depth-test?} +is @code{#f}, or enabled otherwise (@pxref{Blending and Depth +Testing}). +@end deffn + +@deffn {Syntax} with-texture @var{texture} @var{body} ... +Evaluate @var{body} with the current texture bound to @var{texture} +(@pxref{Textures}). +@end deffn + +@deffn {Syntax} with-projection @var{projection} @var{body} ... +Evaluate @var{body} with the current projection matrix bound to +@var{projection} (@pxref{Matrices}). +@end deffn + +@node GPU Buffers +@subsection GPU Buffers + +Alright, let's brush aside all of those pretty high level abstractions +and discuss what is going on under the hood. The GPU exists as a +discrete piece of hardware separate from the CPU. In order to make it +draw things, we must ship lots of data out of our memory space and +into the GPU. The @code{(chickadee render buffer}) module provides an +API for manipulating GPU buffers. + +In OpenGL terminology, a chunk of data allocated on the GPU is a +``vertex buffer object'' or VBO. For example, here is a bytevector +that could be transformed into a GPU buffer that packs together vertex +position and texture coordinates: + +@example +(use-modules (chickadee render buffer) (srfi srfi-4)) +(define data + (f32vector -8.0 -8.0 ; 2D vertex + 0.0 0.0 ; 2D texture coordinate + 8.0 -8.0 ; 2D vertex + 1.0 0.0 ; 2D texture coordinate + 8.0 8.0 ; 2D vertex + 1.0 1.0 ; 2D texture coordinate + -8.0 8.0 ; 2d vertex + 0.0 1.0)) ; 2D texture coordinate +@end example + +This data represents a textured 16x16 square centered on the +origin. To send this data to the GPU, the @code{make-buffer} procedure +is needed: + +@example +(define buffer (make-buffer data #:stride 16) +@end example + +The @code{#:stride} keyword argument indicates how many bytes make up +each element of the buffer. In this case, there are 4 floats per +element: 2 for the vertex, and 2 for the texture coordinate. A 32-bit +float is 4 bytes in length, so the buffer's stride is 16. + +Within a VBO, one or more ``attributes'', as OpenGL calls them, may be +present. Attributes are subregions within the buffer that have a +particular data type. In this case, there are two attributes packed +into the buffer. To provided a typed view into a buffer, the +@code{make-typed-buffer} is needed: + +@example +(define vertices + (make-typed-buffer #:buffer buffer + #:type 'vec2 + #:component-type 'float + #:length 4)) +(define texcoords + (make-typed-buffer #:buffer buffer + #:type 'vec2 + #:component-type 'float + #:length 4 + #:offset 8)) +@end example + +To render a square, the GPU needs to draw two triangles, which means +we need 6 vertices in total. However, the above buffer only contains +data for 4 vertices. This is becase there are only 4 unique vertices +for a square, but 2 of them must be repeated for each triangle. To +work with deduplicated vertex data, an ``index buffer'' must be +created. + +@example +(define index-buffer + (make-buffer (u32vector 0 3 2 0 2 1) + #:target 'index) +(define indices + (make-typed-buffer #:type 'scalar + #:component-type 'unsigned-int + #:buffer index-buffer)) +@end example + +Note the use of the @code{#:target} keyword argument. It is required +because the GPU treats index data in a special way and must be told +which data is index data. + +Now that the typed buffers representing each attribute have been +created, all that's left is to bind them all together in a ``vertex +array object'', or VAO. Vertex arrays associate each typed buffer +with an attribute index on the GPU. The indices that are chosen must +correspond with the indices that the shader (@pxref{Shaders}) expects +for each attribute. + +@example +(define vertex-array + (make-vertex-array #:indices indices + #:attributes `((0 . ,vertices) + (1 . ,texcoords)))) +@end example + +With the vertex array created, the GPU is now fully aware of how to +interpret the data that it has been given in the original buffer. +Actually rendering this square is left as an exercise to the reader. +See the @ref{Shaders} section and the @code{gpu-apply} procedure in +@ref{Rendering Engine} the remaining pieces of a successful draw call. +Additionally, consider reading the source code for sprites, shapes, or +particles to see GPU buffers in action. + +Without further ado, the API reference: + +@deffn {Procedure} make-buffer @var{data} [#:name "anonymous"] @ + [#:length] [#:offset 0] [#:stride 0] [#:target @code{vertex}] @ + [#:usage @code{static}] + +Upload @var{data}, a bytevector, to the GPU. By default, the entire +bytevector is uploaded. A subset of the data may be uploaded by +specifying the @var{offset}, the index of the first byte to be +uploaded, and @var{length}, the number of bytes to upload. + +If @var{data} is @code{#f}, allocate @var{length} bytes of fresh GPU +memory instead. + +@var{target} and @var{usage} are hints that tell the GPU how the +buffer is intended to be used. + +@var{target} may be: + +@itemize +@item @code{vertex} +Vertex attribute data. + +@item @code{index} +Index buffer data. + +@end itemize + +@var{usage} may be: + +@itemize +@item @code{static} +The buffer data will not be modified after creation. + +@item @code{stream} +The buffer data will be modified frequently. + +@end itemize + +@var{name} is simply an arbitrary string for debugging purposes that +is never sent to the GPU. +@end deffn + +@deffn {Procedure} buffer? @var{obj} +Return @code{#t} if @var{obj} is a GPU buffer. +@end deffn + +@deffn {Procedure} index-buffer? @var{buffer} +Return @code{#t} if @var{buffer} is an index buffer. +@end deffn + +@defvar null-buffer +Represents the absence of a buffer. +@end defvar + +@deffn {Procedure} buffer-name @var{buffer} +Return the name of @var{buffer}. +@end deffn + +@deffn {Procedure} buffer-length @var{buffer} +Return the length of @var{buffer}. +@end deffn + +@deffn {Procedure} buffer-stride @var{buffer} +Return the amount of space, in bytes, between each element in +@var{buffer}. +@end deffn + +@deffn {Procedure} buffer-target @var{buffer} +Return the the intended usage of @var{buffer}, either @code{vertex} or +@code{index}. +@end deffn + +@deffn {Procedure} buffer-usage @var{buffer} +Return the intended usage of @var{buffer}, either @code{static} for +buffer data that will not change once sent to the GPU, or +@code{stream} for buffer data that will be frequently updated from the +client-side. +@end deffn + +@deffn {Procedure} buffer-data @var{buffer} +Return a bytevector containing all the data within @var{buffer}. If +@var{buffer} has not been mapped (see @code{with-mapped-buffer}) then +this procedure will return @code{#f}. +@end deffn + +@deffn {Syntax} with-mapped-buffer @var{buffer} @var{body} @dots{} +Evaluate @var{body} in the context of @var{buffer} having its data +synced from GPU memory to RAM. In this context, @code{buffer-data} +will return a bytevector of all the data stored in @var{buffer}. When +program execution exits this form, the data (including any +modifications) is synced back to the GPU. + +This form is useful for streaming buffers that need to update their +contents dynamically, such as a sprite batch. +@end deffn + +@deffn {Procedure} make-typed-buffer #:buffer #:type @ + #:component-type #:length [#:offset 0] [#:divisor] @ + [#:name "anonymous"] + +Return a new typed buffer view for @var{buffer} starting at byte index +@var{offset} of @var{length} elements, where each element is of +@var{type} and composed of @var{component-type} values. + +Valid values for @var{type} are: + +@itemize +@item @code{scalar} +single number + +@item @code{vec2} +2D vector + +@item @code{vec3} +3D vector + +@item @code{vec4} +4D vector + +@item @code{mat2} +2x2 matrix + +@item @code{mat3} +3x3 matrix + +@item @code{mat4} +4x4 matrix +@end itemize + +Valid values for @var{component-type} are: + +@itemize + +@item @code{byte} +@item @code{unsigned-byte} +@item @code{short} +@item @code{unsigned-short} +@item @code{int} +@item @code{unsigned-int} +@item @code{float} +@item @code{double} + +@end itemize + +@var{divisor} is only needed for instanced rendering applications (see +@code{gpu-apply/instanced} in @ref{Rendering Engine}) and represents +how many instances each vertex element applies to. A divisor of 0 +means that a single element is used for every instance and is used for +the data being instanced. A divisor of 1 means that each element is +used for 1 instance. A divisor of 2 means that each element is used +for 2 instances, and so on. +@end deffn + +@deffn {Procedure} typed-buffer? @var{obj} +Return @code{#t} if @var{obj} is a typed buffer. +@end deffn + +@deffn {Procedure} typed-buffer->buffer @var{typed-buffer} +Return the buffer that @var{typed-buffer} is using. +@end deffn + +@deffn {Procedure} typed-buffer-name @var{typed-buffer} +Return the name of @var{typed-buffer}. +@end deffn + +@deffn {Procedure} typed-buffer-offset @var{typed-buffer} +Return the byte offset of @var{typed-buffer}. +@end deffn + +@deffn {Procedure} typed-buffer-type @var{typed-buffer} +Return the data type of @var{typed-buffer}. +@end deffn + +@deffn {Procedure} typed-buffer-component-type @var{typed-buffer} +Return the component data type of @var{typed-buffer} +@end deffn + +@deffn {Procedure} typed-buffer-divisor @var{typed-buffer} +Return the instance divisor for @var{typed-buffer}. +@end deffn + +@deffn {Syntax} with-mapped-typed-buffer @var{typed-buffer} @var{body} @dots{} + +Evaluate @var{body} in the context of @var{typed-buffer} having its +data synced from GPU memory to RAM. See @code{with-mapped-buffer} for +more information. +@end deffn + +@deffn {Procedure} make-vertex-array #:indices #:attributes @ + [#:mode @code{triangles}] + +Return a new vertex array using the index data within the typed buffer +@var{indices} and the vertex attribute data within @var{attributes}. + +@var{attributes} is an alist mapping shader attribute indices to typed +buffers containing vertex data: + +@example +`((1 . ,typed-buffer-a) + (2 . ,typed-buffer-b) + ...) +@end example + +By default, the vertex array is interpreted as containing a series of +triangles. If another primtive type is desired, the @var{mode} +keyword argument may be overridden. The following values are +supported: + +@itemize +@item @code{points} +@item @code{lines} +@item @code{line-loop} +@item @code{line-strip} +@item @code{triangles} +@item @code{triangle-strip} +@item @code{triangle-fan} +@end itemize + +@end deffn + +@defvar null-vertex-array +Represents the absence of a vertex array. +@end defvar + +@deffn {Procedure} vertex-array? @var{obj} +Return @code{#t} if @var{obj} is a vertex array. +@end deffn + +@deffn {Procedure} vertex-array-indices @var{vertex-array} +Return the typed buffer containing index data for @var{vertex-array}. +@end deffn + +@deffn {Procedure} vertex-array-attributes @var{vertex-array} +Return the attribute index -> typed buffer mapping of vertex attribute +data for @var{vertex-array}. +@end deffn + +@deffn {Procedure} vertex-array-mode @var{vertex-array} +Return the primitive rendering mode for @var{vertex-array}. +@end deffn + +@node Shaders +@subsection Shaders + +Shaders are programs that the GPU can evaluate that allow the +programmer to completely customized the final output of a GPU draw +call. The @code{(chickadee render shader)} module provides an API for +building custom shaders. + +Shaders are written in the OpenGL Shading Language, or GLSL for short. +Chickadee aspires to provide a domain specific language for writing +shaders in Scheme, but we are not there yet. + +Shader programs consist of two components: A vertex shader and a +fragment shader. A vertex shader receives vertex data (position +coordinates, texture coordinates, normals, etc.) and transforms them +as desired, whereas a fragment shader controls the color of each +pixel. + +Sample vertex shader: + +@example +@verbatim +#version 130 + +in vec2 position; +in vec2 tex; +out vec2 fragTex; +uniform mat4 mvp; + +void main(void) { + fragTex = tex; + gl_Position = mvp * vec4(position.xy, 0.0, 1.0); +} +@end verbatim +@end example + +Sample fragment shader: + +@example +@verbatim +#version 130 + +in vec2 fragTex; +uniform sampler2D colorTexture; + +void main (void) { + gl_FragColor = texture2D(colorTexture, fragTex); +} +@end verbatim +@end example + +This manual will not cover GLSL features and syntax as there is lots +of information already available about this topic. + +One way to think about rendering with shaders, and the metaphor +Chickadee uses, is to think about it as a function call: The shader is +a function, and it is applied to some ``attributes'' (positional +arguments), and some ``uniforms'' (keyword arguments). + +@example +(define my-shader (load-shader "vert.glsl" "frag.glsl")) +(define vertices (make-vertex-array ...)) +(gpu-apply my-shader vertices #:color red) +@end example + +@xref{Rendering Engine} for more details about the @code{gpu-apply} +procedure. + +Shaders are incredibly powerful tools, and there's more information +about them than we could ever fit into this manual, so we highly +recommend searching the web for more information and examples. What +we can say, though, is how to use our API: + +@deffn {Procedure} strings->shader @var{vertex-source} @var{fragment-source} +Compile @var{vertex-source}, the GLSL code for the vertex shader, and +@var{fragment-source}, the GLSL code for the fragment shader, into a +GPU shader program. +@end deffn + +@deffn {Procedure} load-shader @var{vertex-source-file} @ + @var{fragment-source-file} + +Compile the GLSL source code within @var{vertex-source-file} and +@var{fragment-source-file} into a GPU shader program. +@end deffn + +@deffn {Procedure} make-shader @var{vertex-port} @var{fragment-port} +Read GLSL source from @var{vertex-port} and @var{fragment-port} and +compile them into a GPU shader program. +@end deffn + +@deffn {Procedure} shader? @var{obj} +Return @code{#t} if @var{obj} is a shader. +@end deffn + +@defvar null-shader +Represents the absence shader program. +@end defvar + +@deffn {Procedure} shader-uniform @var{shader} @var{name} +Return the metadata for the uniform @var{name} in @var{shader}. +@end deffn + +@deffn {Procedure} shader-uniforms @var{shader} +Return a hash table of uniforms for @var{shader}. +@end deffn + +@deffn {Procedure} shader-attributes @var{shader} +Return a hash table of attributes for @var{shader}. +@end deffn + +@deffn {Procedure} uniform? @var{obj} +Return @code{#t} if @var{obj} is a uniform. +@end deffn + +@deffn {Procedure} uniform-name @var{uniform} +Return the variable name of @var{uniform}. +@end deffn + +@deffn {Procedure} uniform-type @var{uniform} +Return the data type of @var{uniform}. +@end deffn + +@deffn {Procedure} uniform-value @var{uniform} +Return the current value of @var{uniform}. +@end deffn + +@deffn {Procedure} uniform-default-value @var{uniform} +Return the default value of @var{uniform}. +@end deffn + +@deffn {Procedure} attribute? @var{obj} +Return @code{#t} if @var{obj} is an attribute. +@end deffn + +@deffn {Procedure} attribute-name @var{attribute} +Return the variable name of @var{attribute}. +@end deffn + +@deffn {Procedure} attribute-location @var{attribute} +Return the binding location of @var{attribute}. +@end deffn + +@deffn {Procedure} attribute-type @var{attribute} +Return the data type of @var{attribute}. +@end deffn + @node Scripting @section Scripting |