jdryg / vg-renderer

A vector graphics renderer for bgfx, based on ideas from NanoVG and ImDrawList (Dear ImGUI)
BSD 2-Clause "Simplified" License
504 stars 55 forks source link

Draw bgfx texture directly #7

Closed hugoam closed 6 years ago

hugoam commented 6 years ago

I need the ability to send a draw command using a bgfx::Texture that I own (not one created by vg).

This is, as far as I know, the only way to draw multiple 3D viewports inside of UI widgets. (as in this video, for reference : https://twitter.com/hugoamnov/status/978444939959898112) It's pretty nice as this way you send the draw commands of the viewports exactly in the same way you send the rest of the UI graphics.

I implemented the change locally and it works fine. API changes are minor : it just needs a function to create an Image with a bgfx texture handle.

Note : I opted for a uint16_t instead of directly a bgfx::TextureHandle : it is less explicit in term of the function signature, but it was the only way to not depend on bgfx in vg's header. In my opinion depending on bgfx in the header would be kind of okay since vg works only with bgfx anyway, but all this is up to you ;) Another option would be to make the name explicit like : createBgfxImage or registerBgfxImage.

ImageHandle createImage(Context* ctx, uint32_t flags, uint16_t bgfx_texture)
{
    ImageHandle handle = allocImage(ctx);
    if(!isValid(handle)) {
        return VG_INVALID_HANDLE;
    }

    Image* tex = &ctx->m_Images[handle.idx];

    uint32_t bgfxFlags = BGFX_TEXTURE_NONE;

#if BX_PLATFORM_EMSCRIPTEN
    if(!bx::isPowerOf2(w) || !bx::isPowerOf2(h)) {
        flags = ImageFlags::Filter_NearestUV | ImageFlags::Filter_NearestW;
        bgfxFlags |= BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_W_CLAMP;
    }
#endif

    if(flags & ImageFlags::Filter_NearestUV) {
        bgfxFlags |= BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT;
    }
    if(flags & ImageFlags::Filter_NearestW) {
        bgfxFlags |= BGFX_TEXTURE_MIP_POINT;
    }
    tex->m_Flags = bgfxFlags;

    tex->m_bgfxHandle = { bgfx_texture };

    return handle;
}
jdryg commented 6 years ago

Merged.

Instead of uint16_t I used a const reference to bgfx::TextureHandle (which can be forward declared w/o including bgfx.h in the header).

hugoam commented 6 years ago

Perfect :D Thanks a lot !