I got a 2 png images, being used as textures in a Qt/C++ 2D OpenGL application. The first is used as some kind of "middle" ground and the second is used as an "object" being rendered "ontop" (Note: they all have the same z-value atm, I get the desired behaviour be rendering it in a defined order). The "object"-texture is partly translucent. The "middleground" texture is mostly solid. The problem is that, the translucent part of my "object" texture does the solid background color and not the "middleground" texture.
Any tips how to achieve this?
Following OpenGL falgs are used for my textures rendering
glEnable (GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Thanks for any help.
Edit:
More code:
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1f);
glEnable(GL_TEXTURE_2D);
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, c->_texture);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
{
glTexCoord2i(0,0);
glVertex2i(-128,-128);
glTexCoord2i(0,1);
glVertex2i(-128,128);
glTexCoord2i(1,1);
glVertex2i(128,128);
glTexCoord2i(1,0);
glVertex2i(128,-128);
}
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
Edit: How I load my texture and as far as I can say it loads it with alpha channel
QImage img("./images/dummycar.png","PNG");
QImage t(QGLWidget::convertToGLFormat(img));
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Screenshot: http://img824.imageshack.us/img824/1912/blackbox.png
The Skyimage is the "middleground" the background is solid black.
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
You're specifying 3
channels for the internalFormat
, so that's RGB, not RGBA. Try using GL_RGBA
in that position instead.
Have you tried fiddling with glAlphaFunc? You can use it to discard drawing translucent parts of your object texture based on alpha value.
What about either
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)
or
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
?
I hope that helps.
If you're rendering one texture per object, then you need to use glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE).
If texture still has "box" around it even after that, then it was loaded without alpha channel.
This perfectly works for me:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, texture2->tex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f(0.5f, 1.0f, 0.5f, 0.5f);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0, 0);
glVertex2f(x, y);
glTexCoord2f(1, 0);
glVertex2f(x + texture2->width, y);
glTexCoord2f(1, 1);
glVertex2f(x + texture2->width, y+ texture2->height);
glTexCoord2f(0, 1);
glVertex2f(x, y + texture2->height);
glEnd();
glDisable(GL_BLEND);
Semi-transparent texture, tinted by last color.
If "having a box around texture" does not describe your problem, then you need to post screenshots.
--EDIT--
Updated data based on your screenshot.
You need to FIRST render background, and then render the car. You see background color because even if surface is transparent, it fills z-buffer with values, and since background is below car, it becomes invisible.
When you're rendering semi-transparent objects, you need to follow those rules.
All non-transparent objects should be rendered before semi-transparent objects. Always.
All transparent objects should be rendered in back to front object. Furthest objects should be rendered first, closest objects should be rendered second.
If rendering in back-to-front order is not possible (unsorted particles with GL_ADD blend), writing into depth buffer should be disabled using glDepthMask(GL_FALSE). If you don't do it, you'll get ugly artifacts. (like the one on your screenshot).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With