关于透明:OpenGL半透明纹理超过其他纹理

OpenGL translucent texture over other texture

我得到了2个png图像,在Qt / C ++ 2D OpenGL应用程序中用作纹理。 第一个用作某种"中间"背景,第二个用作"呈现"在"顶部"的"对象"(注意:它们都具有相同的z值atm,通过将其呈现在一个 定义的顺序)。"对象"纹理是部分半透明的。"中间地面"纹理大部分是实心的。
问题在于,"对象"纹理的半透明部分具有纯背景色,而不是"中间背景"纹理。

任何提示如何实现这一目标?

以下OpenGL falg用于我的纹理渲染

1
2
3
4
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);

谢谢你的帮助。

编辑:

更多代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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);

编辑:我如何加载我的纹理,就我所能说的它通过alpha通道加载

1
2
3
4
5
6
7
8
9
10
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);

截图:http://img824.imageshack.us/img824/1912/blackbox.png

Skyimage是"中间地带",背景是纯黑色。


1
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );

您要为internalFormat指定3通道,因此是RGB,而不是RGBA。尝试在该位置使用GL_RGBA


您是否尝试过使用glAlphaFunc?您可以使用它来丢弃基于alpha值的对象纹理的绘制半透明部分。

那两个呢

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)

要么

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)

希望对您有所帮助。


如果要为每个对象渲染一个纹理,则需要使用glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)。

如果纹理在此之后仍带有"框",则说明它已加载而没有Alpha通道。

这完全适合我:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    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);

半透明纹理,以最后一种颜色着色。

如果"在纹理周围有一个框"不能描述您的问题,那么您需要发布屏幕截图。

- 编辑 -

根据您的屏幕截图更新了数据。

您需要先渲染背景,然后渲染汽车。
您会看到背景颜色,因为即使表面是透明的,它也会用值填充z缓冲区,并且由于背景在汽车下方,因此它不可见。

渲染半透明对象时,需要遵循这些规则。

  • 所有非透明对象应在半透明对象之前呈现。总是。

  • 所有透明对象都应从后到前呈现。应该首先渲染最远的对象,然后渲染第二近的对象。

  • 如果无法以从前到后的顺序进行渲染(使用GL_ADD混合的未排序粒子),则应使用glDepthMask(GL_FALSE)禁止写入深度缓冲区。如果不这样做,您将得到丑陋的文物。 (如屏幕快照中的一个)。