[RFE] Option for NanoVG with bgfx rendering

Started by mcslee, February 21, 2019, 22:39:27

Previous topic - Next topic

mcslee

Hi there - first off, huge thanks for creating LWJGL. Have been evaluating the latest version for a mixed 2D/3D UI animation project, lots of impressive stuff here.

I was wondering if there has been any consideration of using the BGFX backend for NanoVG, as an alternative to the native OpenGL implementation. Especially given Apple's announcement of deprecating OpenGL, BGFX seems like great solution for portability and (hopeful) compatibility with low-level graphics API changes.

BGFX already provides a reference implementation of the NanoVG API using BGFX as the rendering layer:
https://github.com/bkaradzic/bgfx/tree/master/examples/20-nanovg
https://github.com/bkaradzic/bgfx/tree/master/examples/common/nanovg

This would be very useful for projects seeking to overlay 2D NanoVG graphics in a 3D project, but without being locked to OpenGL.

I am just familiarizing myself with the LWJGL implementation details, but it seems like this should not be too difficult a change, with some modifications to the implementation included here:
https://github.com/LWJGL/lwjgl3/tree/master/modules/lwjgl/nanovg/src/main/c

Obviously, the resulting nanovg module would have a dependency on the BGFX module as well as the included shaders. I do understand wanting to keep the modules in LWJGL as light-weight as possible, so perhaps this could be an alternate option, separate from the more basic NanoVG package?

Is this something the team has considered? Or could offer any guidance on pursuing? I'm not super familiar with the build/generator system yet, so figured I'd ask here before spending lots of time on this.

Alternatively, is there any other API or tool that people are using for a simple 2D vector graphics API on top of the BGFX layer? Support for basic shapes, fill/stroke, text, etc. Apart from the hard OpenGL dependency, NanoVG really seems like a great choice, but maybe I'm missing some other option?

Thanks!

spasi

I have a working prototype for this, but there are some complicated issues that need solving. I'll let you know when I've made more progress.

mcslee

Great to hear - and thanks for the quick reply!

spasi

NanoVG & bgfx integration will be available in 3.2.2 snapshot 3. Also added bindings to Blendish & OUI.

First screenshot is the NanoVG demo running over bgfx over Metal on macOS. The second screenshot is the oui-blendish demo ported to LWJGL.

mcslee

Fantastic - that was quick! Looking at the demo code and appears to be just what I need. Thanks so much, look forward to test driving this once the next snapshot build goes up - will let you know how it goes.

mcslee

Have the latest snapshot running and this is working great for me so far, big thanks again for this!

I'm curious - did you make some modifications to the NVGLUFramebuffer used in the BGFX renderer? I noticed that the BGFX call nvgluCreateFramebuffer returns a NVGLUFramebuffer, as defined by the normal NanoVG package:
https://github.com/LWJGL/lwjgl3/blob/master/modules/lwjgl/nanovg/src/generated/java/org/lwjgl/nanovg/NanoVGBGFX.java#L111
https://github.com/LWJGL/lwjgl3/blob/master/modules/lwjgl/nanovg/src/generated/java/org/lwjgl/nanovg/NVGLUFramebuffer.java

But this doesn't match the different type of NGBLUFramebuffer struct that BGFX defines - which has different fields:
https://github.com/LWJGL-CI/bgfx/blob/master-linux/examples/common/nanovg/nanovg_bgfx.h#L16
https://github.com/LWJGL-CI/bgfx/blob/master-linux/examples/common/nanovg/nanovg_bgfx.cpp#L1241

I was pleasantly surprised though, to find that calls to texture() and image() from Java seemed to still work! Either the field alignment was magically correct (which seems unlikely since the BGFX struct is smaller), or I'm thinking you must have already dealt with this somehow? But I'm curious what is going on here. Is https://github.com/LWJGL-CI/bgfx the right place to be looking for the BGFX lib that the snapshot is built against? Or are there modifications somewhere else that are handling this struct?

In any case, it does seem to be working properly, which is great. I'm just quite confused what is going on with this struct. Appreciate any guidance here!

Thanks again.

spasi

Quote from: mcslee on March 01, 2019, 21:23:14I'm curious - did you make some modifications to the NVGLUFramebuffer used in the BGFX renderer? I noticed that the BGFX call nvgluCreateFramebuffer returns a NVGLUFramebuffer, as defined by the normal NanoVG package:
https://github.com/LWJGL/lwjgl3/blob/master/modules/lwjgl/nanovg/src/generated/java/org/lwjgl/nanovg/NanoVGBGFX.java#L111
https://github.com/LWJGL/lwjgl3/blob/master/modules/lwjgl/nanovg/src/generated/java/org/lwjgl/nanovg/NVGLUFramebuffer.java

But this doesn't match the different type of NGBLUFramebuffer struct that BGFX defines - which has different fields:
https://github.com/LWJGL-CI/bgfx/blob/master-linux/examples/common/nanovg/nanovg_bgfx.h#L16
https://github.com/LWJGL-CI/bgfx/blob/master-linux/examples/common/nanovg/nanovg_bgfx.cpp#L1241

Thanks, I missed this difference. The next snapshot will introduce an NVGLUFramebufferBGFX with the correct layout.

Quote from: mcslee on March 01, 2019, 21:23:14I was pleasantly surprised though, to find that calls to texture() and image() from Java seemed to still work! Either the field alignment was magically correct (which seems unlikely since the BGFX struct is smaller), or I'm thinking you must have already dealt with this somehow?

It happens to work because struct members in C are naturally aligned by default. The BGFX struct is actually larger on x64 because of the alignment/padding requirements. It just so happens that the image member matches exactly between the two implementations and GL's texture member matches BGFX's handle.

Quote from: mcslee on March 01, 2019, 21:23:14But I'm curious what is going on here. Is https://github.com/LWJGL-CI/bgfx the right place to be looking for the BGFX lib that the snapshot is built against? Or are there modifications somewhere else that are handling this struct?

That's correct, there are no other modifications.

mcslee

Quote from: spasi on March 01, 2019, 22:44:40
It happens to work because struct members in C are naturally aligned by default. The BGFX struct is actually larger on x64 because of the alignment/padding requirements. It just so happens that the image member matches exactly between the two implementations and GL's texture member matches BGFX's handle.

Oh wow - well that was very good luck! I'll watch the repo for that next snapshot - and big thanks again for the super quick fixes on this.