首页 文章

OpenGL纹理透明度不起作用

提问于
浏览
19

我有一个绑定到简单四边形的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 回答

  • 1

    检查您的纹理是否为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参数 .

  • 32

    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

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

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

相关问题