【问题标题】:OpenGL: fastest way to draw 2d imageOpenGL:绘制二维图像的最快方法
【发布时间】:2015-05-27 16:26:44
【问题描述】:

我正在编写一个交互式路径跟踪器,我想知道在现代 GL 中在屏幕上绘制结果的最佳方式是什么。我将渲染结果存储在像素缓冲区中,该缓冲区在每次传递时更新(+1 ssp)。我想在每次通过后在屏幕上绘制它。我做了一些搜索,人们建议绘制一个带纹理的四边形来显示 2d 图像。这是否意味着我每次更新时都会创建一个新纹理?鉴于我的像素更新非常频繁,这仍然是个好主意吗?

【问题讨论】:

    标签: opengl


    【解决方案1】:

    您无需在每次想要更新内容时都创建全新的纹理。如果大小保持不变,您可以保留一次存储,使用 glTexImage2D() 和 NULL 作为最后一个参数。例如。对于具有 8 位分量精度的 512x512 RGBA 纹理:

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    

    在 OpenGL 4.2 及更高版本中,您还可以使用:

    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 512, 512);
    

    然后您可以使用glTexSubImage2D() 更新全部或部分纹理。例如,按照上面的示例更新整个纹理:

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 512, 512,
                    GL_RGBA, GL_UNSIGNED_BYTE, data);
    

    当然,如果每次只有纹理的矩形部分发生变化,您可以通过相应地选择第 2 到第 5 个参数来使更新更具选择性。

    一旦您的当前数据在纹理中,您可以绘制一个带纹理的屏幕大小四边形,或使用glBlitFramebuffer() 将纹理复制到默认帧缓冲区。您应该能够为第一个选项找到大量示例代码。第二个选项的代码如下所示:

    // One time during setup.
    GLuint readFboId = 0;
    glGenFramebuffers(1, &readFboId);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFboId);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, tex, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
    
    // Every time you want to copy the texture to the default framebuffer.
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFboId);
    glBlitFramebuffer(0, 0, texWidth, texHeight,
                      0, 0, winWidth, winHeight,
                      GL_COLOR_BUFFER_BIT, GL_LINEAR);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
    

    【讨论】:

    • 问题,在你的例子中,'tex'来自哪里?是不是像上面的“数据”?
    • 创建一个要点会很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多