Skip to content

cf_draw3d_set_vs_storage_buffers

Category: draw3d
GitHub: cute_draw3d.h


Binds storage buffers to the vertex stage for subsequent mesh submissions.

void cf_draw3d_set_vs_storage_buffers(CF_StorageBuffer* buffers, int count);
Parameters Description
buffers The buffers, in shader binding order (see cf_apply_vs_storage_buffers
for the declaration contract: set = 0, bindings after any vertex-stage
samplers). Up to 4.
count Number of buffers; 0 clears the set.

Remarks

The whole set replaces at once and is captured per submission like uniforms; identical sets keep coalescing alive. This is the skinning-at-scale tool: put every character's bone palette in ONE buffer, put each submission's palette base index in a spare cf_draw3d_push_mesh_attributes lane, and N animated characters coalesce into a single instanced draw:

// Runtime array tails must be scalars or vectors, so a mat4 palette rides as
// vec4 columns (each matrix is 4 consecutive vec4s, column-major):
layout (std430, set = 0, binding = 0) readonly buffer bones_buffer { vec4 u_bones[]; };
mat4 bone(uint j) { uint i = j * 4u; return mat4(u_bones[i], u_bones[i + 1u], u_bones[i + 2u], u_bones[i + 3u]); }
// ...
uint base = uint(in_mesh_attributes.x);
mat4 skin = bone(base + in_joints.x) * in_weights.x + ...;

Note baked draw lists freeze their captures at record time -- a skinned mesh recorded into a CF_DrawList replays whatever palette buffer contents exist at draw time (the buffer binding is captured, its CONTENTS are not), so animated skinning composes with baked lists exactly when you keep updating the buffer. Works on every backend: GLES3/web emulates read-only storage buffers through texture fetches transparently.

cf_apply_vs_storage_buffers
CF_StorageBuffer
cf_make_storage_buffer
cf_draw3d_push_mesh_attributes