mupen64plus/mupen64plus-core

Rendering graphics output offscreen

jgcodes2020 opened this issue · 3 comments

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?

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.

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:

  • make the auxiliary context current
  • render the overlay to a texture-backed FBO
  • make the primary context current
  • save all relevant state in the primary context (this takes a lot of glGet)
  • draw a full-screen quad with the texture from earlier
  • restore all relevant state in the primary context

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.

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.