如何让白色透明

Posted

技术标签:

【中文标题】如何让白色透明【英文标题】:How to make white transparent 【发布时间】:2017-08-15 07:21:48 【问题描述】:

我正在玩 OGL 的混合。我有一个白色的背景。我在这个背景上画了四边形。四边形用白色和黑色纹理绑定。颜色数组填充了颜色和 alpha 值:

for (i = 0; i < IMAGE_WIDTH; i++) 
    for (j = 0; j < MAGE_HEIGHT; j++) 
        c = ((((i&0x8)==0)^((j&0x8))==0))*255;
        Image[i][j][0] = (GLubyte) c;
        Image[i][j][1] = (GLubyte) c;
        Image[i][j][2] = (GLubyte) c;
        Image[i][j][3] = (GLubyte) 255;
    ;

显示纹理四边形:

glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE);    
glDisable (GL_DEPTH_TEST);                                              

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texCheck);        

glLoadIdentity();                                                                      
glTranslatef (0.0f, 0.0f, -9.0f);

glBegin (GL_QUADS);    
    glColor3f (1.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-5.0f, -5.0f, 0.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f( 5.0f, -5.0f, 0.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f( 5.0f, 5.0f, 0.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(-5.0f, 5.0f, 0.0f);
glEnd();

glDisable(GL_TEXTURE_2D);
glEnable (GL_DEPTH_TEST);                                              
glDisable (GL_BLEND);  

四边形上绑定纹理的黑色是不可见的并且工作正常。我应该怎么做才能使绑定纹理的白色透明而绑定纹理的黑色不透明。

【问题讨论】:

【参考方案1】:

你的混合功能应该是

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

提供GL_ONE 作为第二个参数意味着在不考虑源Alpha 值的情况下采用目标颜色值,因此不会发生适当的混合。

【讨论】:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 不起作用。纹理变得不透明。 @slowbro 可能是因为您将 alpha 值设置为不透明 Image[i][j][3] = (GLubyte) 255;?将其设置为低于 255 的值。【参考方案2】:

你必须解决两个问题:

    如果应该以不同的方式混合纹理的不同纹素,则必须设置不同的 Alpha 通道。如果在您的情况下,黑色纹素应该是不透明的而白色纹素应该是不可见的,那么黑色纹素的 alpha 通道必须设置为 255 并且白色纹素的 alpha 通道必须设置为 0。请注意,0255 之间的任何 alpha 值都会导致透明效果,或多或少。

    您已将混合功能设置为glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

混合通过原始目标颜色和源颜色(在您的情况下是纹素的颜色)的函数计算新的目标颜色(帧缓冲区中的片段颜色)。

如果您设置glBlendFunc 使用 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 功能,您可以使用 glBlendEquation 和等式 GL_FUNC_ADD(这是默认值)然后目标颜色是 计算如下:

C_dest_new = C_src * A_src + C_dest * (1-A_src)

如果 alpha 通道等于 0.0:

C_dest_new = C_src * 0 + C_dest * (1-0) = C_dest

如果 alpha 通道等于 1.0 (255):

C_dest_new = C_src * 1 + C_dest * (1-1) = C_src    

答案的扩展

要将白色纹素的 alpha 通道设置为 0,生成纹理的代码必须以某种方式进行更改,如下所示:

for (i = 0; i < IMAGE_WIDTH; i++) 
    for (j = 0; j < MAGE_HEIGHT; j++) 
        c = ((((i&0x8)==0)^((j&0x8))==0))*255;
        Image[i][j][0] = (GLubyte) c;
        Image[i][j][1] = (GLubyte) c;
        Image[i][j][2] = (GLubyte) c;
        Image[i][j][3] = (GLubyte) (255 - c);
    

【讨论】:

如何在上面的代码中设置黑色纹素的alpha通道为255,白色纹素的alpha通道为0?

以上是关于如何让白色透明的主要内容,如果未能解决你的问题,请参考以下文章

opencv中如何让白色的区域变成透明背景,然后和别的图片融合???

c++gdi如何让图片透明

C语言API如何让窗口里的部分背景透明?

如何让状态栏透明,文字颜色为灰色?

如何从具有透明背景的 matplotlib 导出绘图?

如何让字体显示在透明背景之上