我有一个每帧生成的纹理,我想知道在opengl中渲染它的最佳方法。它只是在rgba8(32位,每个组件8位)格式的cpu上生成的像素数据,我只需将其传输到gpu并将其绘制到屏幕上。我记得有一些像素缓冲区或帧缓冲区可以做到这一点而不必每一帧都与glTexImage2d生成一个新的纹理?
答案 0 :(得分:2)
Pixel Buffer Objects不会改变您需要调用glTexImage2D (...)
到( re - )分配纹理存储并复制图像的事实。 PBO提供了一种异步像素传输方式 - 基本上是这样做,以便在完成 从客户端复制 内存之前,对glTexImage2D (...)
的调用不必阻止(CPU)到服务器(GPU)。
这是真正改善性能的唯一方法是,如果您将内存映射到PBO(Pixel Unpack 缓冲区)并在计算图像时每帧都写入该映射内存在CPU上。
当缓冲区绑定到GL_PIXEL_UNPACK_BUFFER
时,为glTexImage2D (...)
参数调用带有 NULL 的data
,这将使用 已经 由服务器拥有,因此它避免了立即客户端 - >服务器副本。通过这样做,可能在性能上获得了微小的改进,但是不要指望任何巨大的改进。这取决于您映射/取消映射缓冲区内存的时间与将缓冲区上传到纹理并使用所述纹理之间的工作量。
此外,如果你每帧调用glTexSubImage2D (...)
而不是通过调用glTexImage2D (...)
来分配新的纹理图像存储(不要担心 - 当没有待处理的命令使用它时旧的存储被回收)你可能会引入一个新的同步开销源,可能会降低您的性能。您在这里寻找的内容称为buffer object streaming。
您更有可能通过使用不需要转换的像素格式来提高性能。 较新版本的GL(4.2+)可让您查询最佳像素传输格式使用glGetInternalFormativ (...)
。
<小时/> 在最后,主要是迂腐的音符,
glTexImage2D (...)
不会生成纹理。它为其图像分配存储空间,并可选择传输像素数据。纹理对象(和一般的OpenGL对象)实际上是在它们第一次 绑定 时生成的(例如glBindTexture (...)
)。从那时起,glTexImage2D (...)
仅管理属于所述纹理对象的内存。