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:绘制二维图像的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenGL 中绘制单色二维数组

使用 OpenGL 固定功能旋转和平移 2D 图像

使用 OpenGL 从 iPad 上的整数数据集绘制图像数据

用OpenGL进行曲线曲面的绘制

(转)使用OpenGL显示图像绘制Shapes

在openGl android(Wear)中绘制基于图像的纹理