【问题标题】:Porting OpenGL ES Framebuffer to OpenGL将 OpenGL ES 帧缓冲区移植到 OpenGL
【发布时间】:2015-02-04 04:56:39
【问题描述】:

以下代码在 iOS 和 Android 上运行良好:

unsigned int depth_texture = 0,
             framebuffer = 0;

glGenTextures( 1, &depth_texture );
glBindTexture( GL_TEXTURE_2D, depth_texture );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

glTexImage2D( GL_TEXTURE_2D,
              0,
              GL_DEPTH_COMPONENT,
              256,
              256,
              0,
              GL_DEPTH_COMPONENT,
              GL_UNSIGNED_INT,
              NULL );

glBindTexture( GL_TEXTURE_2D, 0 );

glGenFramebuffers( 1, &framebuffer );

glBindFramebuffer( GL_FRAMEBUFFER, framebuffer );

glFramebufferTexture2D( GL_FRAMEBUFFER,
                        GL_DEPTH_ATTACHMENT,
                        GL_TEXTURE_2D,
                        depth_texture,
                        0 );

unsigned int type = glCheckFramebufferStatus( GL_FRAMEBUFFER );

if( type == GL_FRAMEBUFFER_COMPLETE )
{ printf( "Complete!" ); }
else
{ printf( "Error!" ); }

现在我将此代码移植到 OpenGL 桌面(2.1 及更高版本),但它拒绝工作。我总是收到错误GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER。我发现使它工作的唯一方法是指定一个 COLOR_ATTACHMENT (这将修复绘图缓冲区错误)。我阅读了 GL glFrameBuffer 文档,但我无法理解为什么上面的代码不起作用。我只想将深度渲染到纹理中......我错过了什么吗?

【问题讨论】:

    标签: opengl opengl-es-2.0 opengl-3


    【解决方案1】:

    如果您不想渲染到任何颜色缓冲区,则需要一个指定以下内容的调用:

    glDrawBuffer(GL_NONE);
    

    这是每个帧缓冲区的状态,因此需要在绑定 FBO 时调用它。

    如果你错过了这个,你会看到你看到的错误,正如 OpenGL 3.3 规范中“帧缓冲区完整性”下的错误条件所指定的那样:

    对于由 DRAW_BUFFERi 命名的任何颜色附着点,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 的值不得为 NONE。

    {FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER}

    FBO 的默认绘图缓冲区为 GL_COLOR_ATTACHMENT0,因此如果您没有 GL_COLOR_ATTACHMENT0 的附件,则此错误情况适用,并将绘图缓冲区保留为默认值。

    为避免非常相似的GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 错误情况,您还需要将读取缓冲区设置为GL_NONE

    glReadBuffer(GL_NONE);
    

    据我所知,没有任何 OpenGL ES 规范中列出这些错误情况。所以那里不需要glDrawBuffer() 调用。

    它变得更奇怪了:检查从 3.0 开始的所有桌面 OpenGL 规范,其中引入了 FBO,错误情况在 3.1、3.2、3.3 和 4.0 的规范中列出。它不在 3.0 中,更有趣的是,它在 4.1 及更高版本中消失了。正如@derhass 在评论中指出的那样,这是ARB_ES2_compatibility 扩展的一部分,成为OpenGL 4.1 的核心。

    记住这一点,您就可以在下一个 OpenGL 琐事之夜大展身手。如果有这样的事情。 :)

    【讨论】:

    • 一个愚蠢的问题 - FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 对于颜色附件的完整性不能为 none。而glDrawBuffer(GL_NONE) 将其设置为无?还是glDrawBuffer(GL_NONE)有不同的含义
    • 有点,但不完全。在您的情况下,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 对于所有颜色附件点都是 NONE ,因为您没有任何颜色附件。但基于绘图缓冲区的默认值,GL_COLOR_ATTACHMENT0 将“由 DRAW_BUFFERi 命名”。所以对应的附件“一定不能是NONE”,但确实是。因此,错误!
    • 至于为什么在 4.1 中消失了:这来自 GL_ARB_ES2_compatibility:“删除所有对影响完整性的绘制/读取缓冲区的引用”,还添加了“如果 GL 绑定到帧缓冲区对象并且绘制缓冲区选择没有附加图像的附件,然后该片段颜色不会写入任何缓冲区。"
    • 我还需要添加 glReadBuffer( GL_NONE );为了让它在我的卡上工作。
    • @McBob 有道理,我补充了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多