floooh / sokol-zig

Zig bindings for the sokol headers (https://github.com/floooh/sokol)
zlib License
375 stars 48 forks source link

Allow extensions to load additional GL functions via SG_GL_FUNCS_EXT #55

Closed kcbanner closed 9 months ago

kcbanner commented 9 months ago

For example, I use this in my project to do this:

sokol_gfx_extensions_funcs.h

#ifndef SOKOL_GFX_EXT_FUNCS_INCLUDED
#define SOKOL_GFX_EXT_FUNCS_INCLUDED

#define SG_GL_FUNCS_EXT \
    _SG_XMACRO(glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* data))

#endif

sokol_gfx_extensions.h

// sokol_gfx_extensions.h - extensions for sokol_gfx
// Extended from: https://github.com/edubart/sokol_gp/blob/beedb873724c53eb56fe3539882218e7a92aac80/sokol_gfx_ext.h

#if defined(SOKOL_IMPL) && !defined(SOKOL_GFX_EXT_IMPL)
#define SOKOL_GFX_EXT_IMPL
#endif

#ifndef SOKOL_GFX_EXT_INCLUDED
#define SOKOL_GFX_EXT_INCLUDED

#ifndef SOKOL_GFX_INCLUDED
#error "Please include sokol_gfx.h before sokol_gfx_extensions.h"
#endif

/* #include <stdbool.h> */
/* #include <stdint.h> */

#ifdef __cplusplus
extern "C" {
#endif

SOKOL_GFX_API_DECL void sg_query_pixels(int x, int y, int w, int h, bool origin_top_left, void *pixels, int size);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // SOKOL_GFX_EXT_INCLUDED

#ifdef SOKOL_GFX_EXT_IMPL
#ifndef SOKOL_GFX_EXT_IMPL_INCLUDED
#define SOKOL_GFX_EXT_IMPL_INCLUDED

#ifndef SOKOL_GFX_IMPL_INCLUDED
#error "Please include sokol_gfx.h implementation before sokol_gfx_extensions.h implementation"
#endif

#if defined(_SOKOL_ANY_GL)

#define GL_VIEWPORT 0x0BA2

static void _sg_gl_query_pixels(int x, int y, int w, int h, bool origin_top_left, void *pixels) {
    SOKOL_ASSERT(pixels);
    GLuint gl_fb;
    GLint dims[4];
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&gl_fb);
    _SG_GL_CHECK_ERROR();
    glGetIntegerv(GL_VIEWPORT, dims);
    int cur_height = dims[3];
    y = origin_top_left ? (cur_height - (y+h)) : y;
    _SG_GL_CHECK_ERROR();
#if defined(SOKOL_GLES2) // use NV extension instead
    glReadBufferNV(gl_fb == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0);
#else
    glReadBuffer(gl_fb == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0);
#endif
    _SG_GL_CHECK_ERROR();
    glReadPixels(x, y, w, h, GL_RED_INTEGER, GL_UNSIGNED_INT, pixels);
    _SG_GL_CHECK_ERROR();
}

#endif

void sg_query_pixels(int x, int y, int w, int h, bool origin_top_left, void *pixels, int size) {
    SOKOL_ASSERT(pixels);
    SOKOL_ASSERT(size >= w*h);
    _SOKOL_UNUSED(size);
#if defined(_SOKOL_ANY_GL)
    _sg_gl_query_pixels(x, y, w, h, origin_top_left, pixels);
#endif
}

#endif // SOKOL_GFX_EXT_IMPL_INCLUDED
#endif // SOKOL_GFX_EXT_IMPL
floooh commented 9 months ago

Clever :) I actually could have needed a similar thing just a couple of days ago, but instead ended up disabling the GL loader completely and used flextGL. But this way of extending the integrated GL loader is pretty nice.

Merging this PR in sokol-zig doesn't make sense btw, because the next automatic bindings-generation would overwrite sokol_gfx.h.

Can you create a similar PR for the sokol main repository to fix the original sokol_gfx.h instead? Thanks!

kcbanner commented 9 months ago

Ah, right I'll move it over there, forgot what repo I was in :) https://github.com/floooh/sokol/pull/993