OPENGL(ES) with SDL2 and "rendering to texture"


#1

Hi there,

I added SDL2 support to OpenLara, an opensource 3D engine for Tomb Raider 1, 2 and 3 (1 is currently completable!).

The problem is that performance is not exactly stellar on things like the Raspberry Pi.
However, I have an idea for getting rock-solid 60FPS: rendering the GL stuff to the original 320x240 resolution, and then upscaling each frame to physical fullscreen resolution., instead of letting the engine render the GL stuff at full physical screen resolution.
SO, this is what I do:

  1. I create a fullscreen SDL2 window, the corresponding renderer, and a 320x240 texture:

    SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_EVENTS|SDL_INIT_GAMECONTROLLER);

    SDL_GetCurrentDisplayMode(0, &sdl_displaymode);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

    sdl_window = SDL_CreateWindow(WND_TITLE, 0, 0,
        sdl_displaymode.w, sdl_displaymode.h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP);

    SDL_GLContext context = SDL_GL_CreateContext(sdl_window);
    SDL_GL_SetSwapInterval(0);

    sdl_renderer = SDL_CreateRenderer(sdl_window, -1,
          SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);

    sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 320, 240);
  1. I set the rendering target to the texture, my understanding is that the GL stuff would be rendered to sdl_texture, right?:

    SDL_SetRenderTarget(sdl_renderer, sdl_texture);
  1. I tell the engine to render the GL stuff at 320x240 (it makes glViewport() to 320x240, etc):
    Core::width  = 320;
    Core::height = 240;
  1. I use two rects during rendercopy so the target texture gets rendered to fullscreen physical resolution, and then renderpresent as usual:

    SDL_GetWindowSize(sdl_window, &w, &h);

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.w = 320;
    src_rect.h = 240;

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.w = w;
    dst_rect.h = h;

    SDL_RenderCopy(sdl_renderer, sdl_texture, &src_rect, &dst_rect);
    SDL_RenderPresent(sdl_renderer);

But all I get is a black screen. Do you guys know what could be going on here?


#2

Come on, guys! Is it even possible to use SDL_SetRenderTarget() with an OpenGL SDL2 program?


#3

I think mixing SDL_Renderer and OpenGL is not a very good idea (even though SDL2 has some functions to somehow support this)…

As far as I understand it, SDL_SetRenderTarget() sets the render target of the SDL_Renderer, not the render target for generic OpenGL code.

It should be possible to do all this in OpenGL directly (render to OpenGL texture or sth and then render that scaled to screen), see e.g. https://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/