OpenGL translucent texture over other texture
Asked Answered
I

3

7

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.

Ignacioignacius answered 2/7, 2010 at 7:10 Comment(1)
Screenshots with explanations would be nice.Tchao
S
7
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.

Swordfish answered 2/7, 2010 at 10:56 Comment(1)
I knew it was something stupid. Thanks a lot, that saved my day :)Ignacioignacius
M
4

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.

Maddox answered 2/7, 2010 at 7:27 Comment(2)
That did not work. I tried glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.1f); but no change. GL_MODULATE changed nothing, GL_BLEND changed the color, but the "box" around my object was still thereIgnacioignacius
This was really helpful to me. Using BB, when I enabled alpha test and used GL_GREATER, it worked like a charm.Grow
T
3

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.

  1. All non-transparent objects should be rendered before semi-transparent objects. Always.

  2. All transparent objects should be rendered in back to front object. Furthest objects should be rendered first, closest objects should be rendered second.

  3. 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).

Tchao answered 2/7, 2010 at 9:14 Comment(5)
Does this show underlying textures? So far it works for me too, but my problem is, that I want to see another texture object beyond the one I draw. But atm I get the background color instead (black). Screenshot: img824.imageshack.us/img824/1912/blackbox.pngIgnacioignacius
@soxs060389: I've updated my answer. You should FIRST render ground, and AFTER THAT render the car. It won't work if you do it in reverse order.Tchao
I was doing that since hour zer0. The car is and was always the last item to be rendered.Ignacioignacius
@soxs060389: "then it was loaded without alpha channel." Texture loading code wasn't here when I answered.Tchao
I know, nevertheless I appreciate your help. I am quite new to OpenGL Blending/Textures and alikeIgnacioignacius

© 2022 - 2024 — McMap. All rights reserved.