Closed roig closed 7 months ago
Currently I'm using a big VBO where I append the primitives data after batching and ordering by Z. The VBO is cleared when flush is called. Do you think this approach is correct?
API looks good, but I would suggest accumulating all vertices for one frame in an intermediate memory buffer (instead of appending directly to a sokol-gfx vertex buffer) and then copy this in one go using a single sg_update_buffer()
, and do this every frame.
sg_append_buffer()
unfortunately has known performance problems in the GL backend and is not really recommended for this use case.
The following headers use that approach, and it's the most efficient across all platforms
...where sokol_gl.h is probably the closest to your use case.
The vertex buffer is created here (note SG_USAGE_STREAM):
...and various regular memory buffers are allocated here (for vertices, uniforms and 'render commands':
...all sokol_gl.h functions except sgl_draw()
will only write to those memory buffers and can be called outside sokol-gfx render passes.
Then in sgl_draw()
(which must be called once per frame inside a sokol-gfx render pass):
First all the accumulated vertices for this frame are copied into the vertex buffer in one go:
...and then the accumulated draw commands are "processed":
A feature I want to add is to render the entity_id to another texture in order to have pixel perfect picking, is it possible to have 2 outputs in that default shader, one for the fragment color and one for the entity_id encoded? In order to avoid switching uniforms, the entity id would be in the vertex data casted from u32 -> f32: Vertex layout: []f32 : x, y, r, g, b, a, u, v, entity_id
...hmm, I never implemented such a picking mechanism, but if you need to multiple fragement shader outputs, you would use "multiple-render-targets" rendering, here's a sample:
https://floooh.github.io/sokol-html5/mrt-pixelformats-sapp.html
This creates a render pass for offscreen rendering with 3 color attachment images:
...and the fragment shader has 3 outputs:
PS: the pipeline object also needs to know about those 3 render targets:
Hope this helps!
PS: before investigating too much work in your picking code please be aware that you cannot read back information from a sokol-gfx texture to the CPU side currently. If you need this, you'll need to inject a backend-specific texture object yourself and mix sokol-gfx and native backend-API calls.
So far I tried to avoid pixel picking and used geometry picking on the CPU instead (point-in-triangle-tests on preprocessed triangle data, for instance here: https://floooh.github.io/visual6502remix/)
Wow thank you for all the feedback and instructions!
I implemented the picking part following your instructions and using a pool of PBOs (to minimize gpu stall) to retrieve the pixel image data and it's working!! And as I'm only querying the pixel where the mouse is, seems really fast.
Now I want to organize everything in order to use "commands" internally.
Thank you for your help and this awesome library.
Hello, first of all thank you for making this library, it's awesome!
I'm porting a codebase to sokol and adding some features while doing it. The 2d renderer looks like this:
Very simple I know. But I have some question about the internals of this.
Currently I'm using a big VBO where I append the primitives data after batching and ordering by Z. The VBO is cleared when flush is called. Do you think this approach is correct?
I'm using a default shader like this:
For my primitives that are drawn without a texture, like lines, I just have a 1x1 texture with a white pixel and bind it before drawing these. This way I don't have to change the pipeline, only apply a different sg_bindings. Do you think this is ok?
A feature I want to add is to render the entity_id to another texture in order to have pixel perfect picking, is it possible to have 2 outputs in that default shader, one for the fragment color and one for the entity_id encoded? In order to avoid switching uniforms, the entity id would be in the vertex data casted from u32 -> f32: Vertex layout: []f32 :
x, y, r, g, b, a, u, v, entity_id
Thank you!