Comments (5)
Yes you can spread vertex components over up to 4 input vertex buffers (I guess I should add a sample for that)... The instancing sample is pretty close (https://github.com/floooh/sokol-samples/blob/master/glfw/instancing-glfw.c), but instead of creating one immutable and one dynamic vertex buffer you would create 2 (or more) immutable vertex buffers.
PS: the example at the end is closer to your GL code, since it keeps the vertex components in the same buffer...
The steps are basically:
- create 2 vertex buffers, and fill them with the vertex data (the number of vertices in each buffer must be identical of course)
- in the pipeline object, you need to at least provide the buffer index (0..3) where the vertex component is coming from, e.g.:
draw_state.pipeline = sg_make_pipeline(&(sg_pipeline_desc){
.layout = {
.attrs = {
/* position from vertex buffer in slot 0*/
[0] = { .name="pos", .format=SG_VERTEXFORMAT_FLOAT3, .buffer_index=0 },
/* normals from vertex buffer in slot 1 */
[1] = { .name="norm", .format=SG_VERTEXFORMAT_FLOAT3, .buffer_index=1 }
}
},
...
(if there are gaps between vertex components, you also need to provide per-buffer-strides in the sg_pipeline_desc.layout.buffers array, like here: https://github.com/floooh/sokol-samples/blob/bc05b045d29977708b03a9d5ad78534c690b3fb1/glfw/instancing-glfw.c#L119)
- finally, in the
sg_draw_state
, put the 2 buffers into the resource binding slots used in the vertex layout description in sg_pipeline_desc above
sg_draw_state ds = {
.vertex_buffers = {
[0] = pos_buffer,
[1] = normals_buffer,
},
.index_buffer = ...
};
...and that should be it! (again, the instancing sample has all the needed stuff, if I missed anything here).
Since a few days ago, you can also put the vertex component data in chunks into the same buffer (e.g. first all position components, followed by all normals)... You would then put the same buffer into the resource binding slots, but use offsets to tell sokol where the input data starts, e.g.:
sg_draw_state ds = {
.vertex_buffers = {
/* put the same buffer into both input slots... */
[0] = vertex_buffer,
[1] = vertex_buffer,
},
.vertex_buffer_offsets = {
[0] = 0, /* positions come first */
[1] = normals_offset, /* byte offset to start of normal components */
},
.index_buffer = ...
};
from sokol.
Alright, here's a new sample which demonstrates this: https://github.com/floooh/sokol-samples/blob/master/glfw/noninterleaved-glfw.c, this is for GL+GLFW. The other platforms are coming right up. D3D11 only next week though because I don't have access to a PC over the weekend :)
from sokol.
The reason for 4 bind slots is that I was not thinking of non-interleaved vertex layout, but more for cases like instanced rendering, or mixing static and dynamic vertex data. In those situations the number of slots usually doesn't have to be so high. With non-interleaved vertex components in mind the max number of bind slots should probably be 16 (that's the max number of vertex attributes in many GL implementations), but it would mean lots of 'dead weight' in the sg_draw_state struct for typical use cases. I guess I'll bump the number of slots to 8 or so for now, and see if this is sufficient for most use cases...
I've been thinking about controlling this with a define, but there's another problem with this... currently all configuration defines only affect the implementation part, so that those configuration defines are only set in the one place where SOKOL_IMPL is defined (and that's how it should be).
But for the sg_draw_state struct the define would need to be set everywhere where sokol_gfx.h is included, not only in the one place where SOKOL_IMPL is defined... or the define would need to be provided as compiler command line arg, so that the configuration would leak into the build system. Both cases are pretty bad :)
What would work is to change the define right in your own copy of the sokol_gfx.h header for your needs, maybe that's the best option...
from sokol.
This is excellent, thank you so much! .buffer index was the parameter I was missing - did not expect to find it in the instancing sample, should've checked that.
Since the issue is already open - would you mind elaborating on why there's limitation on having 4 separate buffers? Is that just something that could be controlled by a #define?
from sokol.
Thanks for the exhaustive reply! The cases I was considering was exactly the mixing of dynamic and immutable vertex data, and I guess I was lazy to just keep >4 separate vertex attrib arrays in some of my code. Thanks again, this was quite educational :)
from sokol.
Related Issues (20)
- sokol_audio.h: capture input HOT 2
- [sokol_app] Alt-tabbing issues on windows in a FPS game on a multi-monitor setup HOT 2
- D3D11 storage buffers do not compile on wine HOT 1
- Seems .c file not generated in bindgen, producing errors HOT 2
- test
- Sokol Fetch Http response 200 is reported as an error HOT 7
- [sokol_gfx d3d11] update_image is wrong for 3d textures HOT 10
- Offscreen with alpha background. Is it possible? HOT 4
- [webgpu] Bindgroups cache breaks down with init/uninit pattern.
- macOS huge memory usage when window minimized HOT 1
- Questions regarding default GL version HOT 5
- App Window Size on Android HOT 3
- Default value _sg_gl_uniform_t::gl_loc when uniform_desc's name isn't given in sokol_gfx HOT 1
- sokol_gfx.h: wrong define in log related to SOKOL_TRACE_HOOKS HOT 1
- WebGPU TextureView validation error HOT 6
- sokol_fetch on Android
- partial updates to buffers/textures (e.g. offset and size args to glBufferSubData, glTexSubImage) HOT 1
- Right shift is recognized as "invalid key" on Windows. HOT 9
- SAPP_EVENT_CHAR for Space is fired when Ctrl+Space is pressed. HOT 2
- Key events on Linux always use the **first** keyboard layout in the system's keyboard layout list. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sokol.