我有一个纹理加载到内存是RGBA格式的各种alpha值。

图像是这样加载的:

 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到255alpha的级数,并且具有255,0,0的RGB值。

但是,如果我用混合禁用绘制它,我会得到一个看起来像: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];

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

有帮助吗?

解决方案

我的纹理加载到内存中,具有各种alpha值

的RGBA格式

gldisable(gl_blend)

但是,如果我用混合禁用它,我会得到一个看起来像:www.ldeo.columbia.edu/~jcoplean/alpha/no_alpha.png

但是

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

你可能会尝试使用gltexenv(gl_combine ...)来修复它(即与基于alpha通道的底层颜色混合纹理颜色),但是因为我没有这样做,我并不完全确定,并且不能给你确切的操作数。它可以在Direct3D9中(使用D3DTOP_ModulateAlealpha_AddColor),因此很可能在OpenGL中进行方法。

其他提示

你不应该禁用混合但使用 glblendfund 参数:

glBlendFunc(GL_ONE, GL_ZERO);
.

或者你可以告诉OpenGL只上传你的图像的RGB通道

glPixelStorei(GL_UNPACK_ALIGNMENT, 4)

在你打电话之前 glTexImage2D 格式设置为 GL_RGB.它会导致它跳过每个像素的第四个字节,即的alpha通道。

我有一个类似的问题,发现它是因为iOS映像加载在RBG值上进行了预期(如在这里的一些其他答案和评论中讨论的那样)。我很想知道是否有一种禁用预乘法的方法,而是使用从这个线程这个线程

    // 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 ; 
        }
    }
.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top