From 279f17ac0e1b3d019c2b294098e834d249376686 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Tue, 4 Jun 2019 20:49:16 -0400 Subject: Update chickadee manual. --- manuals/chickadee/Buffers.html | 473 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 473 insertions(+) create mode 100644 manuals/chickadee/Buffers.html (limited to 'manuals/chickadee/Buffers.html') 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 @@ + + + + + + +Buffers (The Chickadee Game Toolkit) + + + + + + + + + + + + + + + + + + + + +
+

+Next: , Previous: , Up: Graphics   [Contents][Index]

+
+
+ +

2.3.11 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 (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: +

+
+
(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
+
+ +

This data represents a textured 16x16 square centered on the +origin. To send this data to the GPU, the make-buffer procedure +is needed: +

+
+
(define buffer (make-buffer data #:stride 16))
+
+ +

The #: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 +make-buffer-view procedure is needed: +

+
+
(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))
+
+ +

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. +

+
+
(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))
+
+ +

Note the use of the #: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 buffer views 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 buffer view +with an attribute index on the GPU. The indices that are chosen must +correspond with the indices that the shader (see Shaders) expects +for each attribute. +

+
+
(define vertex-array
+  (make-vertex-array #:indices indices
+                     #:attributes `((0 . ,vertices)
+                                    (1 . ,texcoords))))
+
+ +

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 Shaders section and the gpu-apply procedure in +Rendering Engine 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. +

+

Without further ado, the API reference: +

+
+
Procedure: make-buffer data [#:name "anonymous"] [#:length] [#:offset 0] [#:stride 0] [#:target vertex] [#:usage static]
+
+

Upload data, a bytevector, to the GPU. By default, the entire +bytevector is uploaded. A subset of the data may be uploaded by +specifying the offset, the index of the first byte to be +uploaded, and length, the number of bytes to upload. +

+

If data is #f, allocate length bytes of fresh GPU +memory instead. +

+

target and usage are hints that tell the GPU how the +buffer is intended to be used. +

+

target may be: +

+
    +
  • vertex +Vertex attribute data. + +
  • index +Index buffer data. + +
+ +

usage may be: +

+
    +
  • static +The buffer data will not be modified after creation. + +
  • stream +The buffer data will be modified frequently. + +
+ +

name is simply an arbitrary string for debugging purposes that +is never sent to the GPU. +

+ +
+
Procedure: buffer? obj
+

Return #t if obj is a GPU buffer. +

+ +
+
Procedure: index-buffer? buffer
+

Return #t if buffer is an index buffer. +

+ +
+
Variable: null-buffer
+

Represents the absence of a buffer. +

+ +
+
Procedure: buffer-name buffer
+

Return the name of buffer. +

+ +
+
Procedure: buffer-length buffer
+

Return the length of buffer. +

+ +
+
Procedure: buffer-stride buffer
+

Return the amount of space, in bytes, between each element in +buffer. +

+ +
+
Procedure: buffer-target buffer
+

Return the the intended usage of buffer, either vertex or +index. +

+ +
+
Procedure: buffer-usage buffer
+

Return the intended usage of buffer, either static for +buffer data that will not change once sent to the GPU, or +stream for buffer data that will be frequently updated from the +client-side. +

+ +
+
Procedure: buffer-data buffer
+

Return a bytevector containing all the data within buffer. If +buffer has not been mapped (see with-mapped-buffer) then +this procedure will return #f. +

+ +
+
Syntax: with-mapped-buffer buffer body …
+

Evaluate body in the context of buffer having its data +synced from GPU memory to RAM. In this context, buffer-data +will return a bytevector of all the data stored in 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. +

+ +
+
Procedure: make-buffer-view #:buffer #:type #:component-type #:length [#:offset 0] [#:divisor 1] [#:name "anonymous"]
+
+

Return a new buffer view for buffer starting at byte index +offset of length elements, where each element is of +type and composed of component-type values. +

+

Valid values for type are: +

+
    +
  • scalar +single number + +
  • vec2 +2D vector + +
  • vec3 +3D vector + +
  • vec4 +4D vector + +
  • mat2 +2x2 matrix + +
  • mat3 +3x3 matrix + +
  • mat4 +4x4 matrix +
+ +

Valid values for component-type are: +

+
    +
  • byte +
  • unsigned-byte +
  • short +
  • unsigned-short +
  • int +
  • unsigned-int +
  • float +
  • double + +
+ +

divisor is only needed for instanced rendering applications (see +gpu-apply/instanced in 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. +

+ +
+
Procedure: buffer-view? obj
+

Return #t if obj is a buffer view. +

+ +
+
Procedure: buffer-view->buffer buffer-view
+

Return the buffer that buffer-view is using. +

+ +
+
Procedure: buffer-view-name buffer-view
+

Return the name of buffer-view. +

+ +
+
Procedure: buffer-view-offset buffer-view
+

Return the byte offset of buffer-view. +

+ +
+
Procedure: buffer-view-type buffer-view
+

Return the data type of buffer-view. +

+ +
+
Procedure: buffer-view-component-type buffer-view
+

Return the component data type of buffer-view +

+ +
+
Procedure: buffer-view-divisor buffer-view
+

Return the instance divisor for buffer-view. +

+ +
+
Syntax: with-mapped-buffer-view buffer-view body …
+
+

Evaluate body in the context of buffer-view having its +data synced from GPU memory to RAM. See with-mapped-buffer for +more information. +

+ +
+
Procedure: make-vertex-array #:indices #:attributes [#:mode triangles]
+
+

Return a new vertex array using the index data within the buffer view +indices and the vertex attribute data within attributes. +

+

attributes is an alist mapping shader attribute indices to typed +buffers containing vertex data: +

+
+
`((1 . ,buffer-view-a)
+  (2 . ,buffer-view-b)
+  …)
+
+ +

By default, the vertex array is interpreted as containing a series of +triangles. If another primtive type is desired, the mode +keyword argument may be overridden. The following values are +supported: +

+
    +
  • points +
  • lines +
  • line-loop +
  • line-strip +
  • triangles +
  • triangle-strip +
  • triangle-fan +
+ +
+ +
+
Variable: null-vertex-array
+

Represents the absence of a vertex array. +

+ +
+
Procedure: vertex-array? obj
+

Return #t if obj is a vertex array. +

+ +
+
Procedure: vertex-array-indices vertex-array
+

Return the buffer view containing index data for vertex-array. +

+ +
+
Procedure: vertex-array-attributes vertex-array
+

Return the attribute index -> buffer view mapping of vertex attribute +data for vertex-array. +

+ +
+
Procedure: vertex-array-mode vertex-array
+

Return the primitive rendering mode for vertex-array. +

+ +
+
+

+Next: , Previous: , Up: Graphics   [Contents][Index]

+
+ + + + + -- cgit v1.2.3