Issue combining OpenGL and SDL_Renderer

Hello,
I am currently learning SDL2 and c++ and i ran into an issue while trying to combine OpenGL’s shaders and SDL’s textures. My idea is to render my images to an SDL_texture and then bind this texture to my OpenGL context in order to apply shaders. I already figured out how to bind a texture to my context but as soon as i apply SDL_RenderCopy to copy my images onto it, it breaks (black screen). When binding a texture that was copied onto another texture earlier, I experience the same thing. Although applying SDL_RenderClear works fine as well as using an unmodified texture created from an SDL_Surface with SDL_CreateTextureFromSurface. I think something locks the texture but I can’t figure out how to unlock it (SDL_UnlockTexture does nothing). I already tried out a bunch of things but unfortunately nothing worked. If someone knows a solution, please let me know.
Thank you in advance.

The code snippet for creating and binding the texture:

// load image as texture
SDL_Surface* surface = IMG_Load("img.png");
SDL_Texture* image = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);

// create main texture
SDL_Texture* overlay = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 500, 500);

SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_SetRenderTarget(renderer, overlay);
SDL_RenderClear(renderer);

SDL_RenderCopy(renderer, image, NULL, NULL); // this line breaks the overlay texture somehow.

SDL_SetRenderTarget(renderer, NULL);
SDL_RenderPresent(renderer);

// generate OpenGL texture
GLuint texture;
glGenTextures(1, &texture);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
SDL_GL_BindTexture(overlay, NULL, NULL);
glUniform1i(glGetUniformLocation(shader.getShaderId(), "imageTexture"), 0);```

So, you’d want the order to be something like

SDL_SetRenderTarget(renderer, overlay);
// It's a good idea to always reset the viewport when changing render targets.
// Some backends (including OpenGL) require it when changing framebuffer objects.
SDL_RenderSetViewport(renderer, NULL);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);

// Do whatever drawing to your target texture you want to do

SDL_SetRenderTarget(renderer, NULL);
SDL_RenderSetViewport(renderer, NULL);
// Call this before doing any OpenGL stuff
SDL_RenderFlush(renderer);

// Do your OpenGL stuff
// If all you're doing is fetching the SDL texture via SDL_GL_BindTexture() then
// you don't need to create your own via glGenTextures()
// DO NOT create an OpenGL texture every frame!
SDL_GL_BindTexture(overlay, NULL, NULL);

// Bind your shaders and do your OpenGL drawing

SDL_RenderPresent(renderer);

I don’t know enough about the 2D renderer’s OpenGL backend to know if binding your OpenGL shader and then calling SDL_RenderCopy() will be enough; you may have to do the actual drawing of overlay to the screen yourself.

@rtrussell is the go-to person for combining SDL_Renderer and OpenGL

1 Like

Yeah thats basically what I’m trying to do. The code snippet was only meant to run once at the begining for testing purposes, which is why i create the OpenGL textures. I did this because I want multiple textures to go into the shader and SDL_GL_BindTexture binds the texture to the default texture (I think it’s just the first one) but maybe just doing glActiveTexture is enough (I haven’t tried yet).