【发布时间】:2014-07-21 18:33:09
【问题描述】:
将像素从纹理复制到纹理的最佳方法是什么?
我找到了一些方法来实现这一点。
例如,有一个方法glCopyImageSubData(),但我的目标版本是OpenGL 2.1,所以我不能使用它。
此外,由于性能非常重要,glGetTexImage2D() 不是一个选项。
由于我将视频帧作为纹理处理,因此我必须每秒复制大约 30~60 次。
我找到的可用选项如下:
- 为源纹理创建 fbo 并使用 glCopyTexSubImage2D() 将其复制到目标纹理。
- 为源纹理和目标纹理创建 fbo 并对 fbo 进行 blit。
- 为目标纹理创建 fbo 并将源纹理渲染到 fbo。
您可以忽略创建 fbo 的成本,因为 fbo 只会创建一次。
请不要张贴诸如“视情况而定”之类的内容。做你的基准。 我不仅仅针对一个 GPU。如果取决于,请告诉我它是如何取决于什么的。
此外,因为很难测量 OpenGL 调用的时间,所以我想知道它不是一个定量的结果。我需要一些关于应该避免使用哪种方法的建议。
如果你知道更好的复制纹理的方法,也请告诉我。
感谢您的阅读。
【问题讨论】:
-
我认为给予 GL2.1 限制(FBO 也不是核心功能,但可能作为扩展广泛使用),除了您列出的那些之外,没有其他好的替代品。我还认为所有 3 个选项之间的性能差异会很小。
-
在现代 GL 中计时 GL 调用实际上是简单。如果您的驱动程序支持计时器查询(大多数 2.1 实现不支持),您可以在命令之前将查询插入命令队列并在命令之后完成查询。等待几帧以获得该查询的结果,您将非常准确地测量它所花费的时间。您不能在较旧的驱动程序上使用它,但如果您只是想大致了解使用现代实现的每次调用之间的性能差异,这可能会有所帮助。
-
如果需要,您可以立即获得计时器查询的结果……但这会强制管道停止。因此,从长远来看,这取决于您使用计时器查询的目的。如果您想在对运行时性能影响最小的情况下进行性能测量,请仅在结果之后查询它变得可用。如果您想立即知道命令的成本,请继续获取结果而不在它可用时进行其他工作(换句话说,强制 CPU/GPU 同步)。在您的情况下,我认为第二种方法可以正常工作。
-
@derhass 很高兴知道我找到了所有方法!谢谢。
-
@AndonM.Coleman 我不知道。事实上,我正在使用 Qt,而 Qt 已经为此提供了一个包装类!我现在正在测试它。我稍后会更新结果。谢谢。
标签: opengl copy textures benchmarking fbo