【发布时间】:2015-05-27 16:26:44
【问题描述】:
我正在编写一个交互式路径跟踪器,我想知道在现代 GL 中在屏幕上绘制结果的最佳方式是什么。我将渲染结果存储在像素缓冲区中,该缓冲区在每次传递时更新(+1 ssp)。我想在每次通过后在屏幕上绘制它。我做了一些搜索,人们建议绘制一个带纹理的四边形来显示 2d 图像。这是否意味着我每次更新时都会创建一个新纹理?鉴于我的像素更新非常频繁,这仍然是个好主意吗?
【问题讨论】:
标签: opengl
我正在编写一个交互式路径跟踪器,我想知道在现代 GL 中在屏幕上绘制结果的最佳方式是什么。我将渲染结果存储在像素缓冲区中,该缓冲区在每次传递时更新(+1 ssp)。我想在每次通过后在屏幕上绘制它。我做了一些搜索,人们建议绘制一个带纹理的四边形来显示 2d 图像。这是否意味着我每次更新时都会创建一个新纹理?鉴于我的像素更新非常频繁,这仍然是个好主意吗?
【问题讨论】:
标签: opengl
您无需在每次想要更新内容时都创建全新的纹理。如果大小保持不变,您可以保留一次存储,使用 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);
【讨论】: