使用 Alpha 渲染纹理的问题

Posted

技术标签:

【中文标题】使用 Alpha 渲染纹理的问题【英文标题】:Problem with Rendering Textures with Alpha 【发布时间】:2011-07-25 14:50:37 【问题描述】:

我目前正在设计一个游戏引擎,我在图像中遇到了一个问题,即图像中的 alpha 值没有被渲染。我目前正在使用一个 OpenGL 系统,其中每个纹理对象都有顶点、颜色和纹理坐标的缓冲区,这些缓冲区在 drawRect: 方法中被绑定和绘制在一起。尽管 alpha 将混合整个图像,但我希望用于混合到纹理中的颜色,因为它当前充当纹理的“支持”,在具有 alpha 的纹理区域中变得可见。当绘制时不使用颜色时,任何 alpha 区域都只会显示为白色。

这是我不想渲染的带有 alpha 的图像(作为测试),它是这样显示的:

这是我的代码:

我的纹理对象类的一部分:

if (width2 == 2 && height2 == 2)

        // Allocate the texture.  Apples storage method currently does not work for GL_TEXTURE_2D.  REVISIT CODE TO INTEGRATE IT!
        glEnable(GL_TEXTURE_2D);
        glGenTextures(1, &myTextureName);
        glBindTexture(GL_TEXTURE_2D, myTextureName);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, myData);
        //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT ,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,myTextureName, 0);

        type = Normal_Texture;
        CDMeshVertexesCreateRectangle(1, 1, texture);
    

    else 
        // The extension GL_TEXTURE_RECTANGLE_ARB can be used for non-power of two textures, but it is slower than GL_TEXTURE_2D and 
        // not supported by all graphics cards.
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
        glGenTextures(1, &myTextureName);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, myData);
        //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT ,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,myTextureName, 0);

        type = Rectangular_Texture;
        CDMeshVertexesCreateRectangle(width, height, texture);
    

为了在对象内部渲染而运行的代码:

glEnableClientState(GL_VERTEX_ARRAY); // Activate vertex coordinates array
glEnableClientState(GL_COLOR_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexPointer(vertexStride, GL_FLOAT, 0, 0);   

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glColorPointer(colorStride, GL_FLOAT, 0, 0);

// Enable client states for drawing the various arrays
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(texType);

// Bind buffer and use the VBO's to draw
glBindBuffer(GL_ARRAY_BUFFER, texBuffer);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glBindTexture(texType, texID);

//render
glDrawArrays(renderStyle, 0, vertexCount);

glDisableClientState(GL_VERTEX_ARRAY); // Deactivate vertex coordinates array
glDisableClientState(GL_COLOR_ARRAY);

// Disale client states as were done with them.
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(texType);

用于渲染的其他设置:

glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);

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

有什么建议吗?

更新 2 我编辑了 gltexEnv() 函数以使用 GL_MODULATE 而不是 GL_BLEND。这对我遇到的问题没有影响,尽管我将继续使用 GL_MODULATE 进行 alpha 混合。

更新 3 为了解释我到底需要什么,我主要希望能够使用提供混合纹理的颜色指针来显示图像,而不是像现在这样在纹理后面填充这种颜色。纹理数据设置正确,我已经通过许多步骤来缩小问题范围。这是问题的示例图像:

【问题讨论】:

【参考方案1】:

一旦我到达那里,我也需要为我的应用程序这样做:/。

我现在无法对此进行测试,但我知道您的混合功能是关键 - 现在您正在使用 alpha 直接将纹理混合到表面上。尝试改变你的混合功能。我过去使用过这些:glBlendFunc (GL_ONE, GL_ONE);或 glBlendFunc (GL_SRC_ALPHA, GL_ONE);

有一个纹理组合器的 wiki 条目:http://www.opengl.org/wiki/Texture_Combiners

【讨论】:

感谢您的回答,但这些混合功能并没有解决问题。我查看了这篇文章,虽然很有帮助,但我希望 alpha 例如应用于上下文的背景及其背后的任何对象。这甚至可能吗? 我确信这是可能的,但我不是混合函数方面的专家。所以澄清一下,如果你有一个上面有一种颜色的正方形,并且你有一个带有那个面和一些 alpha 的纹理,你希望正方形颜色在纹理的 alpha 上混合,但是要以未改变的方式显示纹理其他地方的颜色? 另外,看看这个帖子:***.com/questions/2841316/… 我已经检查过了,谢谢,虽然我记得它对于混合纹理很重要,但它并没有解决我在纹理中使用 alpha 时遇到的问题。 当我有机会时,我会玩弄我的纹理;但我没有使用 alpha 进行混合——我只是将颜色相乘。你可能最好尝试做一个纹理蒙版,但我真的不知道你在想什么;)idevgames.com/forums/thread-899.html【参考方案2】:

我一直在 Stack Overflow 网站上查看示例和其他人的问题,并偶然发现了这个示例:Link

使用此示例中的以下代码,在绘制纹理之前将颜色指针与纹理混合:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);  
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);

这是现在的结果:

【讨论】:

以上是关于使用 Alpha 渲染纹理的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 alpha 混合组件合成纹理

如何渲染 GL_ALPHA 纹理?

我是不是需要在我的 FBO 中使用 RenderBuffer 对象来渲染到保留 Alpha 通道的纹理?

使用相同的着色器处理 GL_RGBA 和 GL_ALPHA 纹理?

使用 GLSL 在两个不同的通道上进行 Alpha 混合纹理

OpenGL:渲染具有大量纹理透明度的模型,没有绘制顺序?