多采样渲染到纹理

Posted

技术标签:

【中文标题】多采样渲染到纹理【英文标题】:Multisampled rendering to texture 【发布时间】:2012-06-01 11:46:25 【问题描述】:

我正在使用以下架构:

ios 上的 OpenGL ES 2 具有相同 ShareGroup 的两个 EAGL 上下文 两个线程(服务器,客户端=主线程);服务器将内容渲染到纹理,客户端使用简单的纹理四边形显示纹理。

服务器线程的其他细节(工作代码)

在初始化期间创建一个 fbo:

void init(void) 
    glGenFramebuffer(1, &fbo);

服务器的渲染循环大致是这样的:

GLuint loop(void) 
    glBindFrameBuffer(GL_FRAMEBUFFER, fbo);
    glViewport(0,0,width,height);

    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    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);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

    // Framebuffer completeness check omitted

    glClear(GL_COLOR_BUFFER_BIT);

    // actual drawing code omitted

    // the drawing code bound other textures, so..
    glBindTexture(GL_TEXTURE_2D, tex);
    glGenerateMipmap(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, GL_NONE);
    glFlush();

    return tex;

到目前为止,这一切都很好。

新(错误)代码

现在我想将多重采样添加到服务器线程,使用 GL_APPLE_framebuffer_multisample 扩展并修改初始化代码如下:

void init(void) 
    glGenFramebuffer(1, &resolve_fbo);
    glGenFramebuffers(1, &sample_fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, sample_fbo);
    glGenRenderbuffers(1, &sample_colorRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, sample_colorRenderbuffer);
    glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 4, GL_RGBA8_OES, width, height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, sample_colorRenderbuffer);

    // Framebuffer completeness check (sample_fbo) omitted

    glBindRenderbuffer(GL_RENDERBUFFER, GL_NONE);
    glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);

主循环已改为:

GLuint loop(void) 
    glBindFrameBuffer(GL_FRAMEBUFFER, sample_fbo);
    glViewport(0,0,width,height);

    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    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);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

    glClear(GL_COLOR_BUFFER_BIT);

    // actual drawing code omitted

    glBindFramebuffer(GL_FRAMEBUFFER, resolve_fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

    // Framebuffer completeness check (resolve_fbo) omitted

    // resolve multisampling
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, resolve_fbo);
    glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, sample_fbo);
    glResolveMultisampleFramebufferAPPLE();

    // the drawing code bound other textures, so..
    glBindTexture(GL_TEXTURE_2D, tex);
    glGenerateMipmap(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, GL_NONE);
    glFlush();

    return tex;

我现在看到的是纹理包含来自多个 loop() 调用的数据,混合在一起。我想我要么错过了某种“解除绑定”,要么可能是 glFinish() 调用(我以前在不同的地方遇到过这样的问题,我用 glTexImage2D() 设置纹理数据并在之后使用它 - 这需要glFinish() 调用强制更新纹理)。

但是在绘图代码之后插入glFinish() 并没有改变这里的任何内容..

【问题讨论】:

【参考方案1】:

哦,没关系,这么愚蠢的错误。我省略了 loop() 方法实际上包含一个 for 循环并渲染多个纹理的细节,错误是我仅在此循环之前绑定了示例 fbo,所以在第一次运行之后,解析 fbo 被绑定..

在循环内移动 fbo 绑定解决了这个问题。

无论如何,谢谢@所有的读者,很抱歉浪费你的时间:)

【讨论】:

以上是关于多采样渲染到纹理的主要内容,如果未能解决你的问题,请参考以下文章

如何在多采样纹理上渲染帧缓冲区对象?

从也是渲染目标的纹理中采样

用于渲染精灵的纹理采样坐标

将一个纹理绑定到两个不同的统一采样器

Opengl 和 Webgl:从附加到当前帧缓冲区的纹理中采样

尝试对立方体贴图纹理进行采样时出现 GL_INVALID_OPERATION