Search code examples
copengltransparencysdl-2

Cannot set Alpha channel to 0 in OpenGL + SDL2


I am trying to save OpenGL rendered screen to PNG image with transparent background. But all I am getting in the 4th channel is all 255 values.

Even before drawing anything on screen and just clearing does not help.

What I have done in OpenGL for initialization to get the transparent background is roughly the following:

gWindow = SDL_CreateWindow("View", SDL_WINDOWPOS_UNDEFINED, 
         SDL_WINDOWPOS_UNDEFINED, width, height,
         SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
gContext = SDL_GL_CreateContext(gWindow);
GLfloat clear_col[4] = {0.0, 0.0, 0.0, 0.0};

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, width/(float)height, nearplane, farplane);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glShadeModel(GL_FLAT);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
pixels = (unsigned char*) malloc(width*height*4);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// checking the values
FILE*ffp = fopen("saved.bin", "wb");
fwrite(pixels, width*height*4, 1, ffp);
fclose(ffp);

Thanks in advance.


Solution

  • By default, SDL will not explictely request a framebuffer with an alpha channel. You'll have to call

    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 1);
    

    before you create the window to make sure that you actually get an alpha buffer. Note that this conceptually requests at least 1 bit alpha. Usually, GL implementations provide pixel formats/visuals with either 0 or 8 bits of alpha per pixel. If you want to make sure to get at least 8 bits, you could also request that explicitely.