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() ); |
您要为
您是否尝试过使用glAlphaFunc?您可以使用它来丢弃基于alpha值的对象纹理的绘制半透明部分。
那两个呢
要么
希望对您有所帮助。
如果要为每个对象渲染一个纹理,则需要使用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)禁止写入深度缓冲区。如果不这样做,您将得到丑陋的文物。 (如屏幕快照中的一个)。