Search code examples
c++openglrenderingsoil

Alpha channel being rendered black. How to make it transparent?


I'm loading a png texture with 32bit and some transparent regions. I have setted this code in my initialization function:

// OpenGL
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable( GL_ALPHA_TEST );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glClearColor( 0.0, 0.0, 0.0, 0.0 );

This is how I load a texture:

// Load textures
glGenTextures( 1, &this->texture );

int width, height;
unsigned char* image;

glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, this->texture );
std::string path = "../assets/textures/" + name;
image = SOIL_load_image( path.c_str(), &width, &height, 0, SOIL_LOAD_RGBA );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image );
SOIL_free_image_data( image );
glUniform1i( glGetUniformLocation( shader->shader, "materialTex" ), 0 );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

This is the effect I get:

example

I'm trying to make the grass background go from black to transparent.

Can you help me?


Solution

  • There are a couple of problems here, but they all boil down to the fact that alpha transparency is order dependent.

    It is not clear why you are using a depth buffer in the first place. The application appears to be 2D and furthermore you seem to be drawing every one of your 2D layers with the same depth. Nevertheless, the red background you are trying to draw needs to be drawn first.

    If you drew the background with depth testing enabled, it would write its depth value to the depth buffer and then the other sprites you tried to draw on top of it would fail because the default depth test is GL_LESS (this rejects parts of objects with the same depth). If you disable depth testing when you draw the background, that also disables depth writes, and that is one possible way to fix your problem.

    Realistically, you could just eliminate depth testing altogether and follow the golden rule for alpha blending:

    • Draw opaque geometry first, and then sort translucent objects by depth