mupen64plus / mupen64plus-core

Core module of the Mupen64Plus project
1.25k stars 254 forks source link

Rendering graphics output offscreen #1048

Open jgcodes2020 opened 7 months ago

jgcodes2020 commented 7 months ago

I am attempting to render an overlay on top of the graphics output. To do this, I would need to have the graphics plugin render to an FBO. Then, during Vidext_GL_SwapBuffers:

  1. Blit the FBO to the screen.
  2. Render my overlay on top.
  3. Actually swap buffers.

I've been messing around with FBOs, trying to get it to show something and it hasn't been working. Is there something related to the core that I should know?

richard42 commented 7 months ago

I don't think the video plugin would need to render to an FBO; if I understand correctly, you could apply an overlay from within the core, regardless of which video plugin is being used, by rendering your overlay exactly like the OSD does. The video plugin renders to the back buffer, and inside of Vidext_GL_SwapBuffers, you render on top of this just before the plugin makes the GL call to swap the buffers.

Alternatively, you could also put your overlay renderer into a video plugin, but then it would only work in that one plugin.

jgcodes2020 commented 7 months ago

if I understand correctly, you could apply an overlay from within the core, regardless of which video plugin is being used, by rendering your overlay exactly like the OSD does.

The primary issue with this is that OpenGL 3.0+ removed much of the state-saving facilities that OpenGL 2.x had. The expected workaround is to use multiple contexts. I'm not sure if using multiple GL contexts to draw to the same window is allowed by the GL standard (this is what I'm doing at the moment), as without it, I'd have to:

I did at one point try the approach I just described, and it seems to be heavily error-prone, and likely to mess with whatever settings were imposed by the graphics plugin.

richard42 commented 7 months ago

Yes, you can use shared contexts to write to the same GL rendering target. The biggest software application that I maintain for my employer does this in a program with dozens of different contexts, including those also shared with OpenCL, Metal, and Cuda, and it (somewhat miraculously) all works.