在OpenGL中绘制纹理,同时忽略其alpha通道

时间:2010-07-08 16:08:26

标签: opengl textures alpha alphablending premultiplied-alpha

我将纹理加载到具有各种alpha值的RGBA格式的内存中。

图像按如下方式加载:

 GLuint texture = 0;
 glGenTextures(1, &texture);
 glBindTexture(GL_TEXTURE_2D, texture);
 self.texNum = texture;

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.imageWidth, self.imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, [self.imageData bytes]);

我想知道如何绘制此纹理,以便将图像中的Alpha通道视为全1,并将纹理绘制为RGB图像。

考虑基本图像:

http://www.ldeo.columbia.edu/~jcoplan/alpha/base.png

此图像是从0到255 alpha的进展,并且整个

的RGB值为255,0,0

但是,如果我在禁用混合的情况下绘制它,我会得到一个如下图像: www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

当我真正想要的是一个看起来像这样的图像: www.ldeo.columbia.edu/~jcoplan/alpha/correct.png

我真的很感激一些指针,让它完全忽略alpha通道。请注意,我最初不能将图像作为RGB加载,因为我确实需要其他点的alpha通道。

编辑:我尝试使用GL_COMBINE来解决我的问题:

glColorf(1,1,1,1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); 
[self drawTexture];

但仍然没有运气,它仍然是黑色到红色。

4 个答案:

答案 0 :(得分:3)

  

我将纹理加载到具有各种alpha值的RGBA格式的内存中

glDisable(GL_BLEND)

  

但是,如果我在禁用混合的情况下绘制它,我会得到一张如下图像:www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

这是因为在源图像中,所有透明像素都是黑色的。这是纹理/图像的问题,或者可能是加载器功能,但它不是OpenGL问题。

您可能尝试使用glTexEnv(GL_COMBINE ...)来修复它(即根据alpha通道混合纹理颜色和基础颜色),但由于我没有做过类似的事情,我不完全确定,而且不能给你准确的操作数。在Direct3D9中可以使用(使用D3DTOP_MODULATEALPHA_ADDCOLOR),因此很可能在opengl中有一种方法。

答案 1 :(得分:1)

您不应该禁用混合,而是使用glBlendFunc和适当的参数:

glBlendFunc(GL_ONE, GL_ZERO);

答案 2 :(得分:0)

或者您可以告诉OpenGL使用

仅上传图像的RGB通道
glPixelStorei(GL_UNPACK_ALIGNMENT, 4)

在您将格式设置为glTexImage2D的{​​{1}}致电之前。它将导致它跳过每个像素的第四个字节,即alpha通道。

答案 3 :(得分:0)

我遇到了类似的问题,并发现这是因为iOS图像加载正在对RBG值进行预乘(如本文其他一些答案和评论中所述)。我想知道是否有一种禁用预乘的方法,但与此同时我使用从this threadthis thread派生的代码“取消预先乘法”。

    // un pre-multiply
    uint8_t *imageBytes = (uint8_t *)imageData ;
    int byteCount = width*height*4 ;
    for (int i=0; i < byteCount; i+= 4) {
        uint8_t a = imageBytes[i+3] ;
        if (a!=255 && a!=0 ){
            float alphaFactor = 255.0/a ;
            imageBytes[i] *= alphaFactor ; 
            imageBytes[i+1] *= alphaFactor ; 
            imageBytes[i+2] *= alphaFactor ; 
        }
    }