使用纹理中的alpha来绘制纯色

时间:2010-11-14 01:39:21

标签: iphone opengl-es cocos2d-iphone

如何使用OpenGLES 1.1(iPhone)绘制纹理,但只使用alpha绘制一些颜色?

结果应该是与原始纹理完全相同的alpha蒙版,内部使用单一纯色而不是原始颜色。

我正在glDrawArrays使用glCoordPointerglVertexPointer

我认为做两次传球,一次是质地,一次是纯色。我似乎无法找到glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);的反转。

编辑:经过一番调查后,我认为应该可以使用glTexEnvf来实现。这只是找到正确论据的问题。

3 个答案:

答案 0 :(得分:8)

如前所述,glTexEnv是可行的方式。

要替换纹理的RGB组件并保持其alpha不变,您可以尝试这样的事情(此代码使用红色作为替换颜色):

glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );

glActiveTexture( GL_TEXTURE_0 );
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, spriteTexture);

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_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);

// ... draw as usual

这里有一些解释。

使用GL_COMBINE时,您可以完全控制不同纹理阶段的输入/输出如何组合在一起。在这种情况下,我们指定要替换(GL_REPLACE)纹理阶段0的RGB分量与来自前一阶段(GL_PREVIOUS)的内容,在这种情况下是单一颜色(使用glColor4f设置)。

我们没有为alpha组件设置任何特殊内容,因为我们需要常规行为。 添加以下行将具有与未包括(默认行为)相同的效果:

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);

答案 1 :(得分:2)

如果您可以使用OpenGL ES 2.0,则可以使用自定义片段着色器执行此操作。如果您使用的是基于1.1构建的框架,或者是针对不支持2.0的设备,那么这将没有多大帮助。但如果可以的话,这就是你的做法:

uniform lowp sampler2D sampler; // which texture unit to use
uniform lowp vec4 solidColor;

varying highp vec2 fragmentTexCoord;

void main()
{
    // Get the color with an alpha of zero
    vec4 color = vec4(1,1,1,0) * solidColor;
    // Get the alpha from the texture, zero the r,g,b components
    vec4 alpha = vec4(0,0,0,1) * texture2D(sampler, fragmentTexCoord);
    // their sum is the solid color with the alpha mask of the texture
    gl_FragColor = color + alpha;
}

如果可以确保solidColor的alpha值为零,则可以跳过乘法步骤。

答案 2 :(得分:0)

glBlendFunc(source_factor, dest_factor)转换为:

dest= source*source_factor + dest*dest_factor

所以glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA)是:

dest= source*0 + dest*(1 - source.alpha)

第二遍(不是相反的)应该是glBlendFunc(GL_SRC_ALPHA, GL_ONE)

dest= source*source.alpha + dest

因为你已经在第一遍中应用了alpha蒙版。虽然您仍然需要弄清楚如何使用alpha而不是源纹理来应用常量颜色。

相关问题