我有一个2 png图像,在Qt / C ++ 2D OpenGL应用程序中用作纹理。第一个被用作某种“中间”地面,第二个用作“对象”被渲染为“ontop”(注意:它们都具有相同的z值atm,我得到所需的行为将其呈现在定义的顺序)。 “物体” - 纹理部分是半透明的。 “中间地带”纹理大多是实心的。 问题是,我的“对象”纹理的半透明部分是固体背景颜色而不是“中间地板”纹理。
任何提示如何实现这一目标?
以下OpenGL falgs用于我的纹理渲染
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
Skyimage是“中间地带”,背景是纯黑色。
答案 0 :(得分:7)
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
您为3
指定了internalFormat
个频道,因此它是RGB,而不是RGBA。请尝试在该位置使用GL_RGBA
。
答案 1 :(得分:4)
你试过摆弄glAlphaFunc吗?您可以使用它根据Alpha值丢弃对象纹理的绘制半透明部分。
怎么样
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)
或
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
?
我希望有所帮助。
答案 2 :(得分: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缓冲区,并且由于背景位于汽车下方,因此它将变为不可见。
当您渲染半透明对象时,您需要遵循这些规则。
应在半透明对象之前渲染所有非透明对象。总是
所有透明对象都应该在前面对象中呈现。应首先渲染最远的物体,然后渲染最近的物体。
如果无法以从前到后的顺序进行渲染(使用GL_ADD混合的未排序粒子),则应使用glDepthMask(GL_FALSE)禁用写入深度缓冲区。如果你不这样做,你会得到丑陋的文物。 (就像截图上的那个)。