Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
korfuri opened this issue Apr 21, 2019 · 3 comments
Closed

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

korfuri opened this issue Apr 21, 2019 · 3 comments

Comments

@korfuri
Copy link

korfuri commented Apr 21, 2019

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
Copy link
Owner

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
Copy link
Author

korfuri commented Apr 22, 2019

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:

  • Split the rendering of projectM into its own thread
  • Before rendering projectM, create a new context with glfw that sets GLFW_VISIBLE to false and the relevant version hints to 3.3 core.
  • Tell projectM to render to a texture, and share that texture ID with the main thread
  • To allow the texture to be shared, I had to change the glfwCreateWindow() call so that its parent window argument is set, and points to the application's window. Fortunately the application's window is a global and I can access it.
  • Add the relevant mutex synchronization to signal to the main thread when my rendering is done.

@korfuri korfuri closed this as completed Apr 22, 2019
@memononen
Copy link
Owner

Nice you found the solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants