【问题标题】:OpenGL translucent texture over other textureOpenGL半透明纹理优于其他纹理
【发布时间】:2010-07-02 07:10:03
【问题描述】:

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

任何提示如何实现这一点?

以下 OpenGL 标志用于我的纹理渲染

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);

感谢您的帮助。

编辑:

更多代码:

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 通道

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

天空图像是“中间背景”,背景是纯黑色。

【问题讨论】:

  • 有解释的截图会很好。

标签: opengl transparent textures translucency


【解决方案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

【讨论】:

  • 我知道这很愚蠢。非常感谢,这拯救了我的一天:)
【解决方案2】:

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

那两个呢

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)

glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)?

希望对你有帮助。

【讨论】:

  • 那行不通。我试过 glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.1f);但没有变化。 GL_MODULATE 什么都没改变,GL_BLEND 改变了颜色,但我的对象周围的“盒子”仍然存在
  • 这对我很有帮助。使用 BB,当我启用 alpha 测试并使用 GL_GREATER 时,它就像一个魅力。
【解决方案3】:

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

如果在此之后纹理周围仍然有“框”,那么它是在没有 Alpha 通道的情况下加载的。

这非常适合我:

    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);

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

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

--编辑--

根据your screenshot更新数据。

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

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

  1. 所有非透明对象都应该在半透明对象之前渲染。总是。

  2. 所有透明对象都应该从后到前渲染。应首先渲染最远的对象,其次应渲染最近的对象。

  3. 如果无法以从后到前的顺序渲染(未排序的粒子与 GL_ADD 混合),则应使用 glDepthMask(GL_FALSE) 禁用写入深度缓冲区。如果你不这样做,你会得到丑陋的文物。 (就像你屏幕截图上的那个)。

【讨论】:

  • 这是否显示底层纹理?到目前为止,它也对我有用,但我的问题是,我想看到另一个纹理对象超出我绘制的对象。但是 atm 我得到了背景颜色(黑色)。截图:img824.imageshack.us/img824/1912/blackbox.png
  • @soxs060389:我已经更新了我的答案。您应该首先渲染地面,然后再渲染汽车。如果你按相反的顺序执行它是行不通的。
  • 我从零时开始就这样做了。汽车是并且始终是要渲染的最后一个项目。
  • @soxs060389:“然后加载时没有 Alpha 通道。”我回答时纹理加载代码不在这里。
  • 我知道,不过我感谢您的帮助。我对 OpenGL 混合/纹理等很陌生
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 2015-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多