OpenGL纹理透明度不起作用

时间:2011-03-05 19:52:39

标签: opengl textures

我有一个绑定到简单四边形的OpenGL纹理。

我的问题是:我的纹理是128x128像素的图像。我只在该图像上填充大约100x60像素,其他像素是透​​明的。我把它保存在.png文件中。当我绘图时,绑定纹理的透明部分是白色的。

假设我有背景。当我在这个背景上绘制这个新的四边形时,我看不到透过纹理的透明部分。

有什么建议吗?

代码:

// Init code...
gl.glEnable(gl.GL_TEXTURE_2D);
gl.glDisable(gl.GL_DITHER);
gl.glDisable(gl.GL_LIGHTING);   
gl.glDisable(gl.GL_DEPTH_TEST);

gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE); 

// Drawing code...
gl.glBegin(gl.GL_QUADS);
gl.glTexCoord2d(0.0, 0.0);
gl.glVertex3f(0.0f, 0.0f, 0.0f);
gl.glTexCoord2d(1.0, 0.0);
gl.glVertex3f(1.0f, 0.0f, 0.0f);
gl.glTexCoord2d(1.0, 1.0);
gl.glVertex3f(1.0f, 1.0f, 0.0f);
gl.glTexCoord2d(0.0, 1.0);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glEnd();

我已尝试过几乎所有内容,从启用混合到更改为GL_REPLACE,但是我无法让它工作。

编辑:

// Texture. Have tested both gl.GL_RGBA and gl.GL_RGB8.
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, (int)gl.GL_RGBA, imgWidth, imgHeight,
            0, gl.GL_BGR_EXT, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);

3 个答案:

答案 0 :(得分:32)

检查您的纹理是否为RGBA格式,并启用混合并设置混合功能:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

绘制纹理。如果你的纹理不是RGBA,那么就没有alpha,混合也不会做任何事情。

编辑:既然您发布了代码,我可能会发现一个严重的错误:

glTexImage2D(gl.GL_TEXTURE_2D, 0, (int)gl.GL_RGBA, imgWidth, imgHeight,  0, gl.GL_BGR_EXT, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);

你告诉GL纹理有internalFormat RGBA,但是位图数据有BGR格式,所以纹理数据没有alpha。假设alpha = 1.0。

要更正它,请使用RGBA格式加载PNG,并使用GL_RGBA作为glTexImage2D的internalFormat和format参数。

答案 1 :(得分:1)

When I'm drawing, the transparent part of the binded texture is white.

这意味着您的PNG解析器将透明区域转换为白色值。如果要使用OpenGL渲染透明图层,通常不依赖纹理文件来保持透明度,而是使用GLBlendFunc()。更多信息:

  

http://www.opengl.org/resources/faq/technical/transparency.htm

答案 2 :(得分:1)

此外,如果渲染到帧缓冲区并将结果复制到纹理中,请检查帧缓冲区是否已打开alpha。例如,当使用osgViewer时,可以通过(在调用setUpViewInWindow之前执行此操作)来实现:

osg::DisplaySettings *pSet = myviewer.getDisplaySettings();
if(pSet == NULL)
   pSet = new osg::DisplaySettings();
pSet->setMinimumNumAlphaBits(8);
myviewer.setDisplaySettings(pSet);

并且在qt下它应该与(来自http://forum.openscenegraph.org/viewtopic.php?t=6411):

一起使用
QGLFormat f;
f.setAlpha( true ); //enables alpha channel for this format
QGLFormat::setDefaultFormat( f ); //set it as default before instantiations
setupUi(this); //instantiates QGLWidget (ViewerQT)

通常情况下,最好直接渲染到帧缓冲区中,但是在准备一些遗留代码的过程中,我总是这样做,而且在开始时很难找到它。