iOS:如何在GLES2中进行渲染到1通道纹理

8
我经过长时间的尝试,现在非常确定这是不可能完成的。
以下是我目前用于渲染到纹理的代码。它可以完成任务,但非常浪费资源。我只需要一个单独的8位通道,可能是16位灰度。我不需要无用的R G和B通道。
但是,如果我尝试在glTexImage2D中切换GL_RGBA /* GL_ALPHA */,则glCheckFramebufferStatus会捕获“frame buffer incomplete”错误:36054 0x8CD6 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT。
IRC上的人建议使用GL_R,但Xcode没有为此提供自动完成,因此看起来可能是那些被剪枝出GLES的东西之一。
但这似乎真的很奇怪!这是一个移动设备。肯定有一些可以将执行操作所需的位数减少四倍的东西……这肯定是最后要削减的东西之一。
???
有人能否明确地解决这个问题?在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'
    // https://dev59.com/iXA65IYBdhLWcg3wzyP8

    // 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();
}

我认为可以将图像渲染到RGBA纹理中,然后使用glTexSubImage2D构建一个跨越每4个字节的子纹理... 我不知道是否有任何简单的方法将其保存为单独的纹理(这样原始纹理就可以被删除)。 - P i
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)不可用。


这个扩展在 Mac OS X 的 OpenGL 上也可用吗? - Yoav

5

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接