Copying GLES framebuffer to SDL texture

Howdy folks,

I’m pretty new to the GL family, but I’ve got a game up and running with GLES 2 inside an SDL2 window. I’m pretty familiar with SDL, but I’m having a bit of trouble with scaling resolution.

I know that I could just watch for window events, destroy and recreate the GL context, and call it a day. But I want to maintain a particular internal resolution (for retro pixely vibes). I’ve worked with SDL textures and renderers before, so my mind immediately went to copying the GL buffer to an SDL texture, then stretching the texture via the renderer, ez pz.

I’ve done a bit of digging, but haven’t found examples of what exactly I’m looking for. At my current stage of research, it looks like I’ll need to:

  1. Either generate a new FBO and texture, or bind to the one created by SDL(???)
  2. Draw stuff
  3. glReadPixels, into a uint8 buffer (sizeof(char) * pb_w * pb_h * 4)
  4. copy ^this buffer to the SDL_Texture
  5. SDL_SetRenderTarget/SDL_RenderCopy/SDL_RenderPresent

But so far, I can’t even seem to get expected results at step 3. Despite rendering a red triangle on a black background, it seems I’m just reading exclusively black pixels.

Source here: sdl2-gles2-tri.c · GitHub

Any suggestions welcome, doesn’t have to be FBO → Texture → Renderer, just looking for any tips on how to set a static resolution for GL and stretch it with the SDL window.

– Ben

A word of caution: glReadPixels() can be really slow.

Also, you don’t need to destroy and recreate the GL context just because the window size changed or whatever.

Just set up an FBO with a render texture backing it, render to that, then switch to the default FBO and draw your texture. Or you can use glBlitFramebuffer() instead of making an actual draw call to get your render texture on the screen.

A word of caution: glReadPixels() can be really slow.


Or you can use glBlitFramebuffer()

As I understand it, this function isn’t available in GLES2. Which is what led me to glReadPixels()

So would I just draw the texture as a fullscreen quad, and badda-bing badda-boom, stretched texture? And I suppose I could change the vertices of the quad if I wanted to keep aspect ratio.

Ah dang, somehow I missed that you were using GLES2 and not regular OpenGL.

Yep. It’s just that easy.

I took a couple stabs at it in GLES2, but after a handful of lines, an extra set of shaders, and just seeing black screens, I decided to switch to GLES3.

I already had the separate fbo, and glBlitFramebuffer() #justworks. Thanks!