From 279f17ac0e1b3d019c2b294098e834d249376686 Mon Sep 17 00:00:00 2001
From: David Thompson Time units in the agenda are in no way connected to real time. It’s
up to the programmer to decide what agenda time means. A simple and
-effective approach is to map each call of the update hook
+effective approach is to map each call of the update procedure
(see Kernel) to 1 unit of agenda time, like so:
It is important to call after
comes in handy:
(add-hook! update-hook (lambda (dt) (update-agenda 1)))
+
(define (update dt)
+ (update-agenda 1))
update-agenda
periodically, otherwise
@@ -147,19 +150,19 @@ scoped and can be changed using the with-agenda
special form:
Advance the current agenda by dt.
Schedule thunk, a procedure of zero arguments, to be run at time.
Schedule thunk, a procedure of zero arguments, to be run after delay.
Schedule thunk, a procedure of zero arguments, to be run every interval amount of time. Repeat this n times, or indefinitely if not specified.
Schedule body to be evaluated at time.
Schedule body to be evaluated after delay.
Schedule body to be evaluated every interval amount of time. Repeat this n times, or indefinitely if not specified.
An essential constant for all trigonometry. π
is the ratio
-of a circle’s circumferences to its diameter. Since π
is an
-irrational number, the pi in Chickadee is a mere floating point
+
An essential constant for all trigonometry. Pi is the ratio of a +circle’s circumferences to its diameter. Since pi is an irrational +number, the pi in Chickadee is a mere floating point approximation that is “good enough.”
Return the cotangent of z.
Return a new Bezier curve object whose starting point is p0, ending point is p3, and control points are p1 and p2. All points are 2D vectors.
Return #t
if obj is a Bezier curve.
Return the starting point of bezier.
Return the first control point of bezier.
Return the second control point of bezier.
Return the end point of bezier.
Return a list of connected bezier curves defined by control-points. The first curve is defined by the first 4 arguments and every additional curve thereafter requires 3 additional @@ -150,14 +152,14 @@ arguments.
Return the coordinates for bezier at t (a value in the range [0, 1] representing how far from the start of the curve to check) as a 2D vector.
Modify the 2D vector dest in-place to contain the coordinates for bezier at t.
+Next: Framebuffers, Previous: Particles, Up: Graphics [Contents][Index]
+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: +
+replace
+Use the latest color, ignoring all others.
+
+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.
+
+add
+Add all pixel color values together. The more colors blended
+together, the more white the final color becomes.
+
+subtract
+Subtract all pixel color values. The more colors blended together,
+the more black the final color becomes.
+
+multiply
+
+darken
+
+lighten
+
+screen
+
++Next: Shaders, Previous: Rendering Engine, Up: Graphics [Contents][Index]
+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: +
+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. +
Return #t
if obj is a GPU buffer.
+
Return #t
if buffer is an index buffer.
+
Represents the absence of a buffer. +
Return the name of buffer. +
Return the length of buffer. +
Return the amount of space, in bytes, between each element in +buffer. +
Return the the intended usage of buffer, either vertex
or
+index
.
+
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.
+
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
.
+
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. +
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.
+
Return #t
if obj is a buffer view.
+
Return the buffer that buffer-view is using. +
Return the name of buffer-view. +
Return the byte offset of buffer-view. +
Return the data type of buffer-view. +
Return the component data type of buffer-view +
Return the instance divisor for buffer-view. +
Evaluate body in the context of buffer-view having its
+data synced from GPU memory to RAM. See with-mapped-buffer
for
+more information.
+
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
+Represents the absence of a vertex array. +
Return #t
if obj is a vertex array.
+
Return the buffer view containing index data for vertex-array. +
Return the attribute index -> buffer view mapping of vertex attribute +data for vertex-array. +
Return the primitive rendering mode for vertex-array. +
+Next: Shaders, Previous: Rendering Engine, Up: Graphics [Contents][Index]
+Return #t
if obj is a channel.
Retrieve a value from channel. The current script suspends until a value is available.
Send data to channel. The current script suspends until another script is available to retrieve the value.
A low-level API also exists for using channels outside of a script via +callback procedures: +
+Asynchronously retrieve a value from channel and call proc +with that value. +
Asynchronously send data to channel and call thunk +after it has been received. +
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
+tween
procedure (see Tweening). Experiment with them to
+figure out which function makes an animation look the best.
+
Pro tip: smoothstep
provides nice results most of the time and
+creates smoother animation than using linear
.
+
Effects like smoke, fire, sparks, etc. are often achieved by animating
+lots of little, short-lived sprites known as “particles”. In fact,
+all of these effects, and more, can be accomplished by turning a few
+configuration knobs in a “particle system”. A particle system takes
+care of managing the many miniscule moving morsels so the developer
+can quickly produce an effect and move on with their life. The
+(chickadee render particles)
module provides an API for
+manipulating particle systems.
+
Below is an example of a very simple particle system that utilizes +nearly all of the default configuration settings: +
+(use-modules (chickadee render particles)) +(define texture (load-image "particle.png")) +(define particles (make-particles 2000 #:texture texture)) +
In order to put particles into a particle system, a particle +“emitter” is needed. Emitters know where to spawn new particles, +how many of them to spawn, and for how long they should do it. +
+Below is an example of an emitter that spawns 16 particles per frame
+at the coordinates (320, 240)
:
+
(use-modules (chickadee math vector)) +(define emitter (make-particle-emitter (vec2 320.0 240.0) 16)) +(add-particle-emitter particles emitter) +
To see all of the tweakable knobs and switches, read on! +
+alpha
] [#:color white] [#:end-color transparent] [#:texture] [#:animation-rows 1] [#:animation-columns 1] [#:width] [#:height] [#:speed-range (vec2 0.1 1.0)] [#:acceleration-range (vec2 0.0 0.1)] [#:direction-range (vec2 0 (* 2 pi))] [#:lifetime 30] [#:sort]Return a new particle system that may contain up to capacity +particles. Achieving the desired particle effect involves tweaking +the following keyword arguments as needed: +
+- blend-mode: Pixel blending mode. alpha
by default.
+(see Blending for more about blend modes).
+
- start-color: The tint color of the particle at the beginning of its +life. White by default. +
+- end-color: The tint color of the particle at the end of of its +life. Completely transparent by default for a fade-out effect. The +color in the middle of a particle’s life will be an interpolation of +start-color and end-color. +
+- texture: The texture applied to the particles. The texture +may be subdivided into many animation frames. +
+- animation-rows: How many animation frame rows there are in the +texture. Default is 1. +
+- animation-columns: How many animation frame columns there are +in the texture. Default is 1. +
+- width: The width of each particle. By default, the width of +an animation frame (in pixels) is used. +
+- height: The height of each particle. By default, the height +of an animation frame (in pixels) is used. +
+- speed-range: A 2D vector containing the min and max particle +speed. Each particle will have a speed chosen at random from this +range. By default, speed ranges from 0.1 to 1.0. +
+- acceleration-range: A 2D vector containing the min and max +particle acceleration. Each particle will have an acceleration chosen +at random from this range. By default, acceleration ranges from 0.0 +to 0.1. +
+- direction-range: A 2D vector containing the min and max +particle direction as an angle in radians. Each particle will have a +direction chosen at random from this range. By default, the range +covers all possible angles. +
+- lifetime: How long each particle lives, measured in +updates. 30 by default. +
+- sort: youngest
if youngest particle should be drawn
+last or oldest
for the reverse. By default, no sorting is
+applied at all.
+
Return #t
if obj is a particle system.
+
Advance the simulation of particles. +
Render particles. +
Render particles with matrix applied. +
Return a new particle emitter that spawns rate particles per +frame within spawn-area (a rectangle or 2D vector) for +duration frames. If duration is not specified, the +emitter will spawn particles indefinitely. +
Return #t
if obj is a particle emitter.
+
Return the spawn area for emitter. +
Return the number of particles that emitter will spawn per +frame. +
Return the number of frames remaining in emitter’s lifespan. +
Return #t
if emitter has finished spawning particlces.
+
Add emitter to particles. +
Remove emitter to particles +
Return #t
if obj is a path finder.
Return a list of nodes forming a path from start to goal using path-finder to hold state. neighbors is a procedure diff --git a/manuals/chickadee/Quaternions.html b/manuals/chickadee/Quaternions.html index de4c8e4..ebda6e9 100644 --- a/manuals/chickadee/Quaternions.html +++ b/manuals/chickadee/Quaternions.html @@ -1,6 +1,6 @@ - @@ -104,33 +106,33 @@ smooth transition from one rotation to another, whereas interpolating two matrices would yield garbage.
Return a new quaternion with values x, y, z, and w.
Return #t
if obj is a quaternion.
Return the W component of the quaternion q.
Return the X component of the quaternion q.
Return the Y component of the quaternion q.
Return the Z component of the quaternion q.
Create a new rectangle that is width by height in size and whose bottom-left corner is located at (x, y).
Return #t
if obj is a rectangle.
Return #t
if rect2 is completely within rect1.
Return #t
if rect2 overlaps rect1.
Return #t
if the coordinates (x, y) are within
rect.
Return #t
if the 2D vector v is within the bounds of
rect.
Return the X coordinate of the lower-left corner of rect.
Return the Y coordinate of the lower-left corner of rect.
Return the left-most X coordinate of rect.
Return the right-most X coordinate of rect.
Return the bottom-most Y coordinate of rect.
Return the top-most Y coordinate of rect.
Return the X coordinate of the center of rect.
Return the Y coordinate of the center of rect.
Return the width of rect.
Return the height of rect.
Return the surface area covered by rect.
Restrict x to the portion of the X axis covered by rect.
Restrict y to the portion of the Y axis covered by rect.
Return a new rect that adjusts the location of rect1 so that it is completely within rect2. An exception is thrown in the case that rect1 cannot fit completely within rect2.
Return a new rectangle based on rect but moved to the coordinates (x, y).
Return a new rectangle based on rect but moved to the coordinates in the 2D vector v.
Return a new rectangle based on rect but moved by (x, y) units relative to its current location.
Return a new rectangle based on rect but moved by the 2D vector v relative to its current location.
Return a new rectangle based on rect, but expanded by width units on the X axis and height units on the Y axis, while keeping the rectangle centered on the same point.
Return a new rectangle that completely covers the area of rect1 and rect2.
Return a new rectangle that is the overlapping region of rect1 and rect2. If the two rectangles do not overlap, a rectangle of 0 width and 0 height is returned.
Set the left X coordinate of rect to x.
Set the bottom Y coordinate of rect to y.
Set the width of rect to width.
Set the height of rect to height.
Move rect to (x, y) in-place.
Move rect to the 2D vector v in-place.
Move rect by (x, y) in-place.
Move rect by the 2D vector v in-place.
Expand rect by width and height in-place.
Modify rect1 in-place to completely cover the area of both rect1 and rect2.
Modify rect1 in-place to be the overlapping region of rect1 and rect2.
Adjust the location of rect1 in-place so that its bounds are completely within rect2. An exception is thrown in the case that rect1 cannot fit completely within rect2.
Restrict the coordinates of the 2D vector v so that they are within the bounds of rect. v is modified in-place.