Coder Social home page Coder Social logo

Non-interleaved vertex data about sokol HOT 5 CLOSED

floooh avatar floooh commented on July 22, 2024
Non-interleaved vertex data

from sokol.

Comments (5)

floooh avatar floooh commented on July 22, 2024 1

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.

floooh avatar floooh commented on July 22, 2024 1

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.

floooh avatar floooh commented on July 22, 2024 1

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.

mhalber avatar mhalber commented on July 22, 2024

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.

mhalber avatar mhalber commented on July 22, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.