memononen / nanovg

Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
zlib License
5.07k stars 767 forks source link

How can I copy a nvgPaint from one context to another? #543

Closed korfuri closed 5 years ago

korfuri commented 5 years ago

Hi, I'm trying to use one context to render an image using OpenGL, then use nvgImagePattern() to obtain a NVGPaint for it, and finally use that NVGPaint for a nvgFillPaint() operation in a different context. Is there a "proper" way to do this?

What about if one context uses GL2 and the other one uses GL3 (or GLES3)?

x/y problem statement: I'm writing a module for VCV Rack, which uses nanovg with GL2. The module is loaded dynamically into Rack. My module uses projectM to render visuals with OpenGL. On OSX, the shaders that projectM use require me to request an OpenGL3 context because they use GLSL 300 (according to this comment at least). So my solution (maybe very naive - I know next to nothing about OpenGL) is to create a separate NVGcontext for projectM rendering, possibly running the code for that in a separate thread, have it render to a texture, and use that texture as a NVGpaint to fill a shape in the "main" NVGcontext that Rack provides me (the GL2 one).

Thoughts? thanks!

memononen commented 5 years ago

I don't think there's any proper way to do that.

I've reread your question maybe 10 times, and still not quite sure what you want to do. I sounds like half half way implemented wrong idea :)

So, if I understood correctly, you want to render something cool with projectM, and display that with NanoVG?

In that case all you need to do is to share the texture you rendered to between the two OpenGL contexts, and use nvglCreateImageFromHandleGL2() to obtain NanoVG image handle which you can pass to nvgImagePattern(). You should call nvglCreateImageFromHandleGL2() when the render target is created, not every frame.

I don't know how to share textures between OpenGL contexts.

korfuri commented 5 years ago

Sorry for the unclear question - it's kind of a mess. Here's a short writeup in case someone else finds this issue in the future:

What I wanted to do was render some library's stuff (projectM) which requires an OpenGL 3.3 core context, but I'm embedded in a program (VCV Rack) that gives me a context of less than that.

As it turns out, I didn't need to do anything at the NVG level. All I had to do was:

memononen commented 5 years ago

Nice you found the solution!