2

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?

Yuri A. Brito
  • 231
  • 2
  • 10
  • I think it may be more your image than OpenGL. is your image background black, or is there no fill? two very different things – Syntactic Fructose May 29 '14 at 18:49
  • 1
    Could you read back your grass texture and make sure the alpha component is different from 1.0 where you expect it to be ? – agrum May 29 '14 at 19:01
  • @SyntacticFructose No fill. I have tested with at least 3 different pngs, all 32bit and with transparent background. – Yuri A. Brito May 29 '14 at 19:01
  • @agrum I just did as you suggested and the black part is being read as "0 0 0 0" where the other parts have a pretty wide variation with alpha > 0. – Yuri A. Brito May 29 '14 at 19:19
  • Show the code where you do the drawing.. I use this (works fine): http://pastebin.com/pDn5JsGC – Brandon May 29 '14 at 19:45
  • Ok, I don't know SOIL so I wanted to make sure the function you called read properly your .png, which seems to be the case. We can start putting the blame of openGL now. – agrum May 29 '14 at 19:45
  • +1 Brandon, the full drawing code would be quite useful. – agrum May 29 '14 at 19:46
  • It's spread between some files. https://github.com/ghostec/White/blob/master/main.cpp (line 72 renderer.render()) Then, https://github.com/ghostec/White/blob/master/Renderer/src/OpenGL/Renderer.cpp (...) - there are some indirections, scene calls draw on each model. On ModelAsset there is the next important step on drawing: https://github.com/ghostec/White/blob/master/Renderer/src/OpenGL/ModelAsset.cpp This code doesn't implement the blending because I didn't wanna commit code that doesn't work. However, the blending part is up there in the post. – Yuri A. Brito May 29 '14 at 20:14
  • Well, I can tell just from looking at your image that you are drawing no fewer than 3 things here. There are the two textured quads and then the thing you drew to change the background color from black to red (*your clear color is black*). Alpha blending is order-dependent, if you draw that red background ***after*** the translucent textures, then this is the behavior you should expect. – Andon M. Coleman May 29 '14 at 20:51
  • @AndonM.Coleman Actually, as of the code on the post, my clear color is white. The glClear inside the Renderer::render() was removed in the code I'm testing. Changing the draw order just makes the red background to be over the grass, all I can see is red. – Yuri A. Brito May 29 '14 at 20:57
  • 1
    @YuriA.Brito Draw the red background first, but disable depth testing. That will prevent it from writing to the depth buffer (*depth and stencil writes are disabled when their respective test is also disabled*) and causing your problems. Re-enable the depth test after you draw it. The depth test is what makes draw order so important in this particular case. – Andon M. Coleman May 29 '14 at 21:01
  • @AndonM.Coleman That solved my problem! =) Thank you very much! If you post as an answer I will choose as the corret one. – Yuri A. Brito May 29 '14 at 21:46

1 Answers1

3

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
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106