创建和编写GL_ALPHA纹理(OpenGL ES 2)

时间:2014-03-16 21:33:04

标签: ios opengl-es-2.0 fragment-shader texture2d render-to-texture

我是OpenGL的新手,所以我不知道该怎么做。 目前我这样做是为了在iOS中创建一个Alpha纹理:

GLuint framebuffer, renderBufferT;
glGenFramebuffers(1, &framebuffer);
glGenTextures(1, &renderBufferT);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glBindTexture(GL_TEXTURE_2D, renderBufferT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderBufferT, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
{
    NSLog(@"createAlphaBufferWithSize not complete %x", status);
    return NO;
}

但它返回错误:GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

我也想知道如何在片段着色器中写入此纹理。是否与RGBA完全相同,如下所示:

gl_FragColor = vec1(0.5);

我的目的是使用高效的纹理,因为我的代码中有很多纹理读取,而我只需要一个颜色组件。

感谢我可以选择的方向。

2 个答案:

答案 0 :(得分:1)

我不是iOS人,但该错误表明您的OpenGL ES驱动程序(PowerVR)不支持渲染为GL_ALPHA格式。我还没有看到任何OpenGL ES驱动程序可以在任何平台上执行此操作。您可以使用PowerVR SDK中的纹理压缩工具创建GL_ALPHA纹理以与OpenGL ES一起使用,但我认为您可以渲染的最小格式是16位颜色 - 如果它甚至可用。

使纹理高效的更好方法是使用压缩格式,因为GPU使用专用硬件对其进行解码。你真的需要PowerVR纹理压缩工具。它是免费下载:

http://www.imgtec.com/powervr/insider/sdkdownloads/sdk_licence_agreement.asp

答案 1 :(得分:0)

所以我仍然没有找到上述问题的答案,但我找到了解决方法。 本质上,由于每个像素由4个颜色组件组成,而我只需要一个仅用于alpha,那么我所做的就是使用一个纹理来存储我需要的4个不同的逻辑alpha纹理。维护这些逻辑alpha纹理需要花费一点力气。

为了绘制这个包含4个逻辑alpha纹理的纹理,我使用着色器并创建一个标记位,用于标记我打算写入哪个颜色分量。 我使用的混合是

 (GL_ONE, GL_ONE_MINUS_SRC_COLOR), 

片段着色器是这样的:

 uniform lowp vec4 uSignBit;
 void main()
 {
     lowp vec4 textureColor = texture2D(uTexture,vTexCoord);
     gl_FragColor = uSignBit * textureColor.a;
 }

所以,当我打算将一些纹理的alpha值写入逻辑alpha纹理编号2时,我写道:

 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
 glUniform4f(uSignBit, 0.0, 1.0, 0.0, 0.0);