8

经过数小时的抨击,我现在很确定这是不可能的。

到目前为止,这是我用于渲染纹理的代码(如下);它可以完成工作,但是非常浪费。我只想要一个 8 位通道,可能是 16 位灰度。我不想要一个无用的 RG 和 B 频道。

但是如果我尝试在 glTexImage2D 中切换 GL_RGBA /*GL_ALPHA*/,glCheckFramebufferStatus 会捕获“帧缓冲区不完整”错误:36054 0x8CD6 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

IRC 上的人建议使用 GL_R,但 Xcode 不为此提供自动完成功能,所以看起来它可能是为 GLES 从 GL 中剪除的东西之一

但这似乎真的很奇怪!这是一个移动设备。当然,可以将执行操作所需的位数减少四倍……当然,这将是最后要做的事情之一。

?!?

谁能彻底埋葬这个?是否可以在 GLES2.0 中渲染到单通道纹理?

+ (void)  blurTexture: (GLuint)     in_texId
             POTWidth: (GLuint)     in_W
            POTHeight: (GLuint)     in_H
       returningTexId: (GLuint*)    out_pTexId
{
    // search HELP: 'Using a Framebuffer Object as a Texture'
    // http://stackoverflow.com/questions/3613889/gl-framebuffer-incomplete-attachment-when-trying-to-attach-texture

    // Create the destination texture, and attach it to the framebuffer’s color attachment point.

    // create the texture
    GLuint id_texDest;
    {
        // fragshader will use 0 
        glActiveTexture( GL_TEXTURE0 );

        // Ask GL to give us a texture-ID for us to use
        glGenTextures( 1, & id_texDest );
        glBindTexture( GL_TEXTURE_2D, id_texDest );


        // actually allocate memory for this texture
        GLuint pixCount = in_W * in_H;

        typedef struct { uint8_t r, g, b, a } rgba;

        rgba * alphas = calloc( pixCount, sizeof( rgba ) );

        // XOR texture
        int pix=0;
        for ( int x = 0;  x < in_W;  x++ )
        {
            for ( int y = 0;  y < in_H;  y++ )
            {
                //alphas[ pix ].r = (y < 256) ? x^y : 0;
                //alphas[ pix ].g = (y < 512) ? 127 : 0;
                //alphas[ pix ].b = (y < 768) ? 127 : 0;
                alphas[ pix ].a = (y < 512) ? x^y : 0; // half mottled, half black

                pix++;
            }
        }

        // set some params on the ACTIVE texture
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_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 );

        // WRITE/COPY from P into active texture  
        glTexImage2D( GL_TEXTURE_2D, 0,
                     GL_RGBA /*GL_ALPHA*/, in_W, in_H, 0, 
                     GL_RGBA /*GL_ALPHA*/, 
                     GL_UNSIGNED_BYTE, 
                     (void *) alphas );

        //glGenerateMipmap( GL_TEXTURE_2D );

        free( alphas );

        glLogAndFlushErrors();

    }


    GLuint textureFrameBuffer;
    {
        GLint oldFBO;
        glGetIntegerv( GL_FRAMEBUFFER_BINDING, & oldFBO );

        // create framebuffer
        glGenFramebuffers( 1, & textureFrameBuffer );
        glBindFramebuffer( GL_FRAMEBUFFER, textureFrameBuffer );

        // attach renderbuffer
        glFramebufferTexture2D( GL_FRAMEBUFFER, 
                               GL_COLOR_ATTACHMENT0, 
                               GL_TEXTURE_2D, 
                               id_texDest, 
                               0 );

        //glDisable( GL_DEPTH_TEST );

        // Test the framebuffer for completeness. This test only needs to be performed when the framebuffer’s configuration changes.
        GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER ) ;
        NSAssert1( status == GL_FRAMEBUFFER_COMPLETE, @"failed to make complete framebuffer object %x", status );

        // 36054  0x8CD6  GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

        // unbind frame buffer
        glBindFramebuffer( GL_FRAMEBUFFER, oldFBO );
    }




    glLogAndFlushErrors();

    // clear texture bitmap to backcolor
    {
        GLint oldFBO;
        glGetIntegerv( GL_FRAMEBUFFER_BINDING, & oldFBO );

        glBindFramebuffer( GL_FRAMEBUFFER, textureFrameBuffer );
        glLogAndFlushErrors();

        {
            float j = 0.1f;
            glClearColor( j, j, j, j );
            glLogAndFlushErrors();
            glClear( GL_COLOR_BUFFER_BIT );
            glLogAndFlushErrors();
        }

        glBindFramebuffer( GL_FRAMEBUFFER, oldFBO );
    }

    glDeleteFramebuffers( 1, & textureFrameBuffer );

    * out_pTexId = id_texDest;

    glLogAndFlushErrors();
}
4

2 回答 2

7

从 iOS 5.0 开始,您可以使用 GL_EXT_texture_rg 渲染到 1 和 2 通道纹理。

http://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_rg.txt

http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iOS5.html#//apple_ref/doc/uid/TP30915195-SW47

编辑:我已经对此进行了测试,它可以工作,但仅适用于 A5 及更高版本(iPad2/3/4/mini、iPhone4S/5、iPod touch 第 5 代)。不幸的是,它在最需要它的 A4 和更早版本(iPhone4、iPod touch 第 4 代、3GS、iPad1)上不可用。

于 2012-10-31T05:36:59.267 回答
5

不,OpenGL ES 2.0 没有任何可渲染的 1 通道纹理格式。GL_ALPHA 和 GL_LUMINANCE 不可渲染,因此它们对 RTT 毫无用处。

于 2011-05-22T17:06:22.073 回答