OpenGL:绘制二维图像的最快方法
Posted
技术标签:
【中文标题】OpenGL:绘制二维图像的最快方法【英文标题】:OpenGL: fastest way to draw 2d image 【发布时间】:2015-05-27 16:26:44 【问题描述】:我正在编写一个交互式路径跟踪器,我想知道在现代 GL 中在屏幕上绘制结果的最佳方式是什么。我将渲染结果存储在像素缓冲区中,该缓冲区在每次传递时更新(+1 ssp)。我想在每次通过后在屏幕上绘制它。我做了一些搜索,人们建议绘制一个带纹理的四边形来显示 2d 图像。这是否意味着我每次更新时都会创建一个新纹理?鉴于我的像素更新非常频繁,这仍然是个好主意吗?
【问题讨论】:
【参考方案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'来自哪里?是不是像上面的“数据”? 创建一个要点会很好以上是关于OpenGL:绘制二维图像的最快方法的主要内容,如果未能解决你的问题,请参考以下文章