对图像的可见像素进行纯色着色

时间:2016-10-24 03:55:26

标签: image opengl-es glsl opengl-es-2.0

我有像Source这样的图片:

img

我的目标是像结果一样显示它:

img

颜色必须是可变的。

是否可以使用glEnable/glBlendFunc/glBlendFuncSeparate/glBlendEquationSeparate执行此操作?

或者我必须使用着色器(glsl)?这个着色器怎么样?

1 个答案:

答案 0 :(得分:0)

要创建这样的绘图,我仍然建议您使用着色器,但如果没有,仍有很多方法可以绘制它,但它需要您至少进行2次绘制调用。

所以问我最好的方法是将所有这些绘图仅绘制到alpha通道。这意味着只有alpha会被绘制,而颜色将保持不变。为此,您需要先将alpha清除为零,这样当清除颜色缓冲区时,请确保将alpha分量设置为零glClearColor(0,0,0,0)。在停止绘制之前,使用颜色蒙版仅启用alpha:glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)。现在使用glBlendFuncSeparate( GL_ZERO, GL_ONE, GL_ONE, GL_ONE)绘制图像。这意味着忽略纹理的颜色(它的RGB部分)并使用之前缓冲区上的任何颜色,这意味着使用纹理中的alpha并将其加到缓冲区中已有的任何颜色上(最后一个值更有意义)是GL_ZERO,但这会阻止重叠)。现在可以根据需要绘制尽可能多的纹理。您可能只有一个,但它应该适用于任何数量。

所以此时你的缓冲区到处都会有alpha零,但是你已经绘制了纹理并且纹理具有非零alpha。所以是时候绘制实际的颜色了。我们需要重新启用颜色蒙版以绘制颜色,以便glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)(alpha部分可以设置为false,但我们也可以重置那个)。现在绘制我们需要覆盖具有alpha的部分的实际颜色,让我们将混合设置为glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE, GL_ZERO)。这意味着我们将根据缓冲区上的当前alpha状态应用颜色。如果状态为1,那么将应用全颜色,如果alpha为0,则相同的颜色将保持不变,如果为0.5,它将先前在缓冲区上的颜色与新颜色混合,这意味着如果如果您有白色背景,可能需要将颜色清除为(1,1,1,0)。然后,alpha将被覆盖到颜色中将设置为新alpha的任何内容。

现在要么重新绘制一个带有禁用纹理的全屏矩形,并将颜色设置为目标颜色应该是什么(紫罗兰色),你就完成了。或者,您只能在绘制图像的任何位置重绘矩形。

不够容易?怎么样:

  • 为形状的颜色设置清晰的颜色glClearColor(violet.r, violet.g, violet.b, 0.0)将alpha保持为零
  • 清除颜色缓冲区
  • 将颜色蒙版设置为仅绘制为alpha glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)
  • 启用最常见的混合功能glBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  • 像其他任何
  • 一样绘制纹理
  • 将颜色遮罩重置为默认glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)

注意:此最后一个步骤仅在您的视图/屏幕/画布启用了混合时才有效。如果没有,则在大多数情况下仅显示RGB部分,这将导致整个屏幕具有纯色。