summaryrefslogtreecommitdiff
path: root/manuals/chickadee/Buffers.html
diff options
context:
space:
mode:
Diffstat (limited to 'manuals/chickadee/Buffers.html')
-rw-r--r--manuals/chickadee/Buffers.html473
1 files changed, 473 insertions, 0 deletions
diff --git a/manuals/chickadee/Buffers.html b/manuals/chickadee/Buffers.html
new file mode 100644
index 0000000..00e3cfe
--- /dev/null
+++ b/manuals/chickadee/Buffers.html
@@ -0,0 +1,473 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!-- Copyright (C) 2017, 2018, 2019 David Thompson davet@gnu.org
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+A copy of the license is included in the section entitled "GNU
+Free Documentation License".
+
+A copy of the license is also available from the Free Software
+Foundation Web site at http://www.gnu.org/licenses/fdl.html.
+
+
+* Chickadee: (chickadee). Game programming toolkit for Guile.
+
+The document was typeset with
+http://www.texinfo.org/ (GNU Texinfo).
+ -->
+<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>Buffers (The Chickadee Game Toolkit)</title>
+
+<meta name="description" content="Buffers (The Chickadee Game Toolkit)">
+<meta name="keywords" content="Buffers (The Chickadee Game Toolkit)">
+<meta name="resource-type" content="document">
+<meta name="distribution" content="global">
+<meta name="Generator" content="makeinfo">
+<link href="index.html#Top" rel="start" title="Top">
+<link href="Index.html#Index" rel="index" title="Index">
+<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
+<link href="Graphics.html#Graphics" rel="up" title="Graphics">
+<link href="Shaders.html#Shaders" rel="next" title="Shaders">
+<link href="Rendering-Engine.html#Rendering-Engine" rel="prev" title="Rendering Engine">
+<style type="text/css">
+<!--
+a.summary-letter {text-decoration: none}
+blockquote.indentedblock {margin-right: 0em}
+blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
+blockquote.smallquotation {font-size: smaller}
+div.display {margin-left: 3.2em}
+div.example {margin-left: 3.2em}
+div.lisp {margin-left: 3.2em}
+div.smalldisplay {margin-left: 3.2em}
+div.smallexample {margin-left: 3.2em}
+div.smalllisp {margin-left: 3.2em}
+kbd {font-style: oblique}
+pre.display {font-family: inherit}
+pre.format {font-family: inherit}
+pre.menu-comment {font-family: serif}
+pre.menu-preformatted {font-family: serif}
+pre.smalldisplay {font-family: inherit; font-size: smaller}
+pre.smallexample {font-size: smaller}
+pre.smallformat {font-family: inherit; font-size: smaller}
+pre.smalllisp {font-size: smaller}
+span.nolinebreak {white-space: nowrap}
+span.roman {font-family: initial; font-weight: normal}
+span.sansserif {font-family: sans-serif; font-weight: normal}
+ul.no-bullet {list-style: none}
+@media (min-width: 1140px) {
+ body {
+ margin-left: 14rem;
+ margin-right: 4rem;
+ max-width: 52rem;
+ }
+}
+
+@media (min-width: 800px) and (max-width: 1140px) {
+ body {
+ margin-left: 6rem;
+ margin-right: 4rem;
+ max-width: 52rem;
+ }
+}
+
+@media (max-width: 800px) {
+ body {
+ margin: 1rem;
+ }
+}
+
+-->
+</style>
+<link rel="stylesheet" type="text/css" href="https://dthompson.us/css/dthompson.css">
+
+
+</head>
+
+<body lang="en">
+<a name="Buffers"></a>
+<div class="header">
+<p>
+Next: <a href="Shaders.html#Shaders" accesskey="n" rel="next">Shaders</a>, Previous: <a href="Rendering-Engine.html#Rendering-Engine" accesskey="p" rel="prev">Rendering Engine</a>, Up: <a href="Graphics.html#Graphics" accesskey="u" rel="up">Graphics</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Index.html#Index" title="Index" rel="index">Index</a>]</p>
+</div>
+<hr>
+<a name="Buffers-1"></a>
+<h4 class="subsection">2.3.11 Buffers</h4>
+
+<p>Alright, let&rsquo;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</code>) module provides an
+API for manipulating GPU buffers.
+</p>
+<p>In OpenGL terminology, a chunk of data allocated on the GPU is a
+&ldquo;vertex buffer object&rdquo; or VBO. For example, here is a bytevector
+that could be transformed into a GPU buffer that packs together vertex
+position and texture coordinates:
+</p>
+<div class="example">
+<pre class="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
+</pre></div>
+
+<p>This data represents a textured 16x16 square centered on the
+origin. To send this data to the GPU, the <code>make-buffer</code> procedure
+is needed:
+</p>
+<div class="example">
+<pre class="example">(define buffer (make-buffer data #:stride 16))
+</pre></div>
+
+<p>The <code>#:stride</code> 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&rsquo;s stride is 16.
+</p>
+<p>Within a VBO, one or more &ldquo;attributes&rdquo;, 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-buffer-view</code> procedure is needed:
+</p>
+<div class="example">
+<pre class="example">(define vertices
+ (make-buffer-view #:buffer buffer
+ #:type 'vec2
+ #:component-type 'float
+ #:length 4))
+(define texcoords
+ (make-buffer-view #:buffer buffer
+ #:type 'vec2
+ #:component-type 'float
+ #:length 4
+ #:offset 8))
+</pre></div>
+
+<p>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 &ldquo;index buffer&rdquo; must be
+created.
+</p>
+<div class="example">
+<pre class="example">(define index-buffer
+ (make-buffer (u32vector 0 3 2 0 2 1)
+ #:target 'index)
+(define indices
+ (make-buffer-view #:type 'scalar
+ #:component-type 'unsigned-int
+ #:buffer index-buffer))
+</pre></div>
+
+<p>Note the use of the <code>#:target</code> keyword argument. It is required
+because the GPU treats index data in a special way and must be told
+which data is index data.
+</p>
+<p>Now that the buffer views representing each attribute have been
+created, all that&rsquo;s left is to bind them all together in a &ldquo;vertex
+array object&rdquo;, or VAO. Vertex arrays associate each buffer view
+with an attribute index on the GPU. The indices that are chosen must
+correspond with the indices that the shader (see <a href="Shaders.html#Shaders">Shaders</a>) expects
+for each attribute.
+</p>
+<div class="example">
+<pre class="example">(define vertex-array
+ (make-vertex-array #:indices indices
+ #:attributes `((0 . ,vertices)
+ (1 . ,texcoords))))
+</pre></div>
+
+<p>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 <a href="Shaders.html#Shaders">Shaders</a> section and the <code>gpu-apply</code> procedure in
+<a href="Rendering-Engine.html#Rendering-Engine">Rendering Engine</a> for 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.
+</p>
+<p>Without further ado, the API reference:
+</p>
+<dl>
+<dt><a name="index-make_002dbuffer"></a>Procedure: <strong>make-buffer</strong> <em>data [#:name &quot;anonymous&quot;] [#:length] [#:offset 0] [#:stride 0] [#:target <code>vertex</code>] [#:usage <code>static</code>]</em></dt>
+<dd>
+<p>Upload <var>data</var>, 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</var>, the index of the first byte to be
+uploaded, and <var>length</var>, the number of bytes to upload.
+</p>
+<p>If <var>data</var> is <code>#f</code>, allocate <var>length</var> bytes of fresh GPU
+memory instead.
+</p>
+<p><var>target</var> and <var>usage</var> are hints that tell the GPU how the
+buffer is intended to be used.
+</p>
+<p><var>target</var> may be:
+</p>
+<ul>
+<li> <code>vertex</code>
+Vertex attribute data.
+
+</li><li> <code>index</code>
+Index buffer data.
+
+</li></ul>
+
+<p><var>usage</var> may be:
+</p>
+<ul>
+<li> <code>static</code>
+The buffer data will not be modified after creation.
+
+</li><li> <code>stream</code>
+The buffer data will be modified frequently.
+
+</li></ul>
+
+<p><var>name</var> is simply an arbitrary string for debugging purposes that
+is never sent to the GPU.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_003f"></a>Procedure: <strong>buffer?</strong> <em>obj</em></dt>
+<dd><p>Return <code>#t</code> if <var>obj</var> is a GPU buffer.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-index_002dbuffer_003f"></a>Procedure: <strong>index-buffer?</strong> <em>buffer</em></dt>
+<dd><p>Return <code>#t</code> if <var>buffer</var> is an index buffer.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-null_002dbuffer"></a>Variable: <strong>null-buffer</strong></dt>
+<dd><p>Represents the absence of a buffer.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dname"></a>Procedure: <strong>buffer-name</strong> <em>buffer</em></dt>
+<dd><p>Return the name of <var>buffer</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dlength"></a>Procedure: <strong>buffer-length</strong> <em>buffer</em></dt>
+<dd><p>Return the length of <var>buffer</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dstride"></a>Procedure: <strong>buffer-stride</strong> <em>buffer</em></dt>
+<dd><p>Return the amount of space, in bytes, between each element in
+<var>buffer</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dtarget"></a>Procedure: <strong>buffer-target</strong> <em>buffer</em></dt>
+<dd><p>Return the the intended usage of <var>buffer</var>, either <code>vertex</code> or
+<code>index</code>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dusage"></a>Procedure: <strong>buffer-usage</strong> <em>buffer</em></dt>
+<dd><p>Return the intended usage of <var>buffer</var>, either <code>static</code> for
+buffer data that will not change once sent to the GPU, or
+<code>stream</code> for buffer data that will be frequently updated from the
+client-side.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002ddata"></a>Procedure: <strong>buffer-data</strong> <em>buffer</em></dt>
+<dd><p>Return a bytevector containing all the data within <var>buffer</var>. If
+<var>buffer</var> has not been mapped (see <code>with-mapped-buffer</code>) then
+this procedure will return <code>#f</code>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-with_002dmapped_002dbuffer"></a>Syntax: <strong>with-mapped-buffer</strong> <em>buffer body &hellip;</em></dt>
+<dd><p>Evaluate <var>body</var> in the context of <var>buffer</var> having its data
+synced from GPU memory to RAM. In this context, <code>buffer-data</code>
+will return a bytevector of all the data stored in <var>buffer</var>. When
+program execution exits this form, the data (including any
+modifications) is synced back to the GPU.
+</p>
+<p>This form is useful for streaming buffers that need to update their
+contents dynamically, such as a sprite batch.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-make_002dbuffer_002dview"></a>Procedure: <strong>make-buffer-view</strong> <em>#:buffer #:type #:component-type #:length [#:offset <code>0</code>] [#:divisor <code>1</code>] [#:name <code>&quot;anonymous&quot;</code>]</em></dt>
+<dd>
+<p>Return a new buffer view for <var>buffer</var> starting at byte index
+<var>offset</var> of <var>length</var> elements, where each element is of
+<var>type</var> and composed of <var>component-type</var> values.
+</p>
+<p>Valid values for <var>type</var> are:
+</p>
+<ul>
+<li> <code>scalar</code>
+single number
+
+</li><li> <code>vec2</code>
+2D vector
+
+</li><li> <code>vec3</code>
+3D vector
+
+</li><li> <code>vec4</code>
+4D vector
+
+</li><li> <code>mat2</code>
+2x2 matrix
+
+</li><li> <code>mat3</code>
+3x3 matrix
+
+</li><li> <code>mat4</code>
+4x4 matrix
+</li></ul>
+
+<p>Valid values for <var>component-type</var> are:
+</p>
+<ul>
+<li> <code>byte</code>
+</li><li> <code>unsigned-byte</code>
+</li><li> <code>short</code>
+</li><li> <code>unsigned-short</code>
+</li><li> <code>int</code>
+</li><li> <code>unsigned-int</code>
+</li><li> <code>float</code>
+</li><li> <code>double</code>
+
+</li></ul>
+
+<p><var>divisor</var> is only needed for instanced rendering applications (see
+<code>gpu-apply/instanced</code> in <a href="Rendering-Engine.html#Rendering-Engine">Rendering Engine</a>) 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.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_003f"></a>Procedure: <strong>buffer-view?</strong> <em>obj</em></dt>
+<dd><p>Return <code>#t</code> if <var>obj</var> is a buffer view.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_002d_003ebuffer"></a>Procedure: <strong>buffer-view-&gt;buffer</strong> <em>buffer-view</em></dt>
+<dd><p>Return the buffer that <var>buffer-view</var> is using.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_002dname"></a>Procedure: <strong>buffer-view-name</strong> <em>buffer-view</em></dt>
+<dd><p>Return the name of <var>buffer-view</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_002doffset"></a>Procedure: <strong>buffer-view-offset</strong> <em>buffer-view</em></dt>
+<dd><p>Return the byte offset of <var>buffer-view</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_002dtype"></a>Procedure: <strong>buffer-view-type</strong> <em>buffer-view</em></dt>
+<dd><p>Return the data type of <var>buffer-view</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_002dcomponent_002dtype"></a>Procedure: <strong>buffer-view-component-type</strong> <em>buffer-view</em></dt>
+<dd><p>Return the component data type of <var>buffer-view</var>
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-buffer_002dview_002ddivisor"></a>Procedure: <strong>buffer-view-divisor</strong> <em>buffer-view</em></dt>
+<dd><p>Return the instance divisor for <var>buffer-view</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-with_002dmapped_002dbuffer_002dview"></a>Syntax: <strong>with-mapped-buffer-view</strong> <em>buffer-view body &hellip;</em></dt>
+<dd>
+<p>Evaluate <var>body</var> in the context of <var>buffer-view</var> having its
+data synced from GPU memory to RAM. See <code>with-mapped-buffer</code> for
+more information.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-make_002dvertex_002darray"></a>Procedure: <strong>make-vertex-array</strong> <em>#:indices #:attributes [#:mode <code>triangles</code>]</em></dt>
+<dd>
+<p>Return a new vertex array using the index data within the buffer view
+<var>indices</var> and the vertex attribute data within <var>attributes</var>.
+</p>
+<p><var>attributes</var> is an alist mapping shader attribute indices to typed
+buffers containing vertex data:
+</p>
+<div class="example">
+<pre class="example">`((1 . ,buffer-view-a)
+ (2 . ,buffer-view-b)
+ &hellip;)
+</pre></div>
+
+<p>By default, the vertex array is interpreted as containing a series of
+triangles. If another primtive type is desired, the <var>mode</var>
+keyword argument may be overridden. The following values are
+supported:
+</p>
+<ul>
+<li> <code>points</code>
+</li><li> <code>lines</code>
+</li><li> <code>line-loop</code>
+</li><li> <code>line-strip</code>
+</li><li> <code>triangles</code>
+</li><li> <code>triangle-strip</code>
+</li><li> <code>triangle-fan</code>
+</li></ul>
+
+</dd></dl>
+
+<dl>
+<dt><a name="index-null_002dvertex_002darray"></a>Variable: <strong>null-vertex-array</strong></dt>
+<dd><p>Represents the absence of a vertex array.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-vertex_002darray_003f"></a>Procedure: <strong>vertex-array?</strong> <em>obj</em></dt>
+<dd><p>Return <code>#t</code> if <var>obj</var> is a vertex array.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-vertex_002darray_002dindices"></a>Procedure: <strong>vertex-array-indices</strong> <em>vertex-array</em></dt>
+<dd><p>Return the buffer view containing index data for <var>vertex-array</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-vertex_002darray_002dattributes"></a>Procedure: <strong>vertex-array-attributes</strong> <em>vertex-array</em></dt>
+<dd><p>Return the attribute index -&gt; buffer view mapping of vertex attribute
+data for <var>vertex-array</var>.
+</p></dd></dl>
+
+<dl>
+<dt><a name="index-vertex_002darray_002dmode"></a>Procedure: <strong>vertex-array-mode</strong> <em>vertex-array</em></dt>
+<dd><p>Return the primitive rendering mode for <var>vertex-array</var>.
+</p></dd></dl>
+
+<hr>
+<div class="header">
+<p>
+Next: <a href="Shaders.html#Shaders" accesskey="n" rel="next">Shaders</a>, Previous: <a href="Rendering-Engine.html#Rendering-Engine" accesskey="p" rel="prev">Rendering Engine</a>, Up: <a href="Graphics.html#Graphics" accesskey="u" rel="up">Graphics</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Index.html#Index" title="Index" rel="index">Index</a>]</p>
+</div>
+
+
+
+</body>
+</html>