Closed Ashe closed 1 year ago
Hi, uniform data and 'resource bindings' are different things. Basically, everything that's a buffer, image or sampler needs to be set via sg_apply_bindings()
, and only "uniform data" (simple float or integer values which can be efficiently updated for each draw call) must be set with sg_apply_uniforms()
.
Don't worry too much about calling sg_apply_bindings()
too often and with mostly similar bindings (as long as you don't do this for each individual sprite if you need to render hundreds or thousands of them, see below for 'batching').
For instance if you have 4 different textures, and only want to change those (but use the same pipeline and uniform data) you'd do something like this:
sg_bindings bnd = {
.vertex_buffers[0] = ...,
.index_buffer = ...,
.fs.samplers[0] = ...,
};
sg_image img0 = sg_make_image(...);
sg_image img1 = sg_make_image(...);
sg_image img2 = sg_make_image(...);
sg_image img3 = sg_make_image(...);
sg_apply_pipeline(...);
sg_apply_uniforms(...);
bnd.fs.images[0] = img0;
sg_apply_bindings(&bnd);
sg_draw(...)
bnd.fs.images[0] = img1;
sg_apply_bindings(&bnd);
sg_draw(...)
bnd.fs.images[0] = img2;
sg_apply_bindings(&bnd);
sg_draw(...)
bnd.fs.images[0] = img3;
sg_apply_bindings(&bnd);
sg_draw(...)
...for a small number of draws this is completely fine, but if it would become hundreds or thousands of draw calls you should still try to implement some sort of batching to minimizes texture changes and draw calls (e.g. don't call sg_draw() for each single sprite, only when the texture needs to change, and don't keep each individual sprite in its own texture, instead merge many sprite images into a single "texture atlas" image).
For sprite rendering I would actually recommend starting with sokol_gl.h, this has a simple form of batching implemented already (e.g. see https://github.com/floooh/sokol/blob/47d92ff86298fc96b3b84d93d0ee8c8533d3a2d2/util/sokol_gl.h#L571-L591)
PS: edited this comment with lots of typo fixes.
Thank you for clearing this up! Not that hard to implement either. Great advice as usual :)
Hello, sorry for the beginnery question.
I'm trying to make a simple sprite pipeline; from your samples it's been trivial so far to get something rendered on screen, but I'm struggling to deviate from the way the samples are set up.
From [the loadpng sample])https://github.com/floooh/sokol-samples/blob/578d71daed073dbeb2e5e3d74a3485cf46733cd7/sapp/loadpng-sapp.c#L176)
when the image is loaded, you directly load it into the bindings struct. I'm not sure though how you'd do this if for example you wanted to render multiple images that all use the same vertex buffers. In my mind you'd either have to:
sg_apply_bindings
, orsg_apply_uniforms
and handle uniforms like you do withvs_params
.I can't seem to work out which the best way forward is; I'd rather not have to mutate my bindings constantly, when I try this
I get
and so I'm not quite sure where I'm going wrong and what steps are needed for me to be able to have one set of vertices/indices, one shader, but multiple images.
Sorry if the answer is fairly obvious! I also wasn't sure where to ask questions like this so I hope issues is okay? Thank you for sokol!