floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.63k stars 472 forks source link

Rendering to different default gl framebuffers - sokol_gfx.h #892

Closed danielchasehooper closed 10 months ago

danielchasehooper commented 10 months ago

In the OpenGL build of our app, each document window has its own CAOpenGLLayer. I've looked into using sg_contexts in order make sg_begin_default_pass render to the correct CAOpenGLLayer framebuffer[^1]. Unfortunately sg_contexts affect resource pooling, which I do not want. All documents share the same glyph buffer and other resources for common visual elements, and I don't want those resources to be destroyed when one document is closed[^2]. I do not want changing the default pass's framebuffer to affect anything to do with resource lifetimes.

I propose adding:

typedef struct sg_gl_context_desc {
    const GLuint (*default_framebuffer_cb)(void);
    const GLuint (*default_framebuffer_userdata_cb)(void*);
    void* user_data;
} sg_gl_context_desc;

typedef struct sg_context_desc {
    ...
    sg_gl_context_desc gl;
} sg_context_desc;

That way you can return the desired framebuffer via that callback, and would match the apis of the other graphics backends[^3].

Related to #885

[^1]: Also I haven't seen any documentation guaranteeing that the framebuffer that is bound in drawInCGLContext:pixelFormat:forLayerTime:displayTime:/CGLSetCurrentContext is always the same. So even if resources weren't a concern with sg_context, it seems possible that the framebuffer bound during sg_setup_context might later not be the same framebuffer when sg_begin_default_pass is called

[^2]: I have all CAOpenGLLayers use the same CGLContextObj for this reason.

[^3]:I don't love callbacks since they're harder to read than straight-line code. I think there could be a nicer API along the lines of sg_begin_pass(sg_default_pass(&(sg_default_pass_desc){ .gl.framebuffer = fbo, .width = width, .height = height }), &pass_action) This would allow writing functions that accept a pass as a parameter and that pass could target either an offscreen buffer or the framebuffer; all without affecting the receiving function's implementation. This would also improve #885.