【问题标题】:Copy Metal frame buffer texture for reading复制金属帧缓冲纹理以供阅读
【发布时间】:2018-12-19 20:59:55
【问题描述】:

我正在尝试截取 MetalKit 视图 (MTKView) 的屏幕截图,就像答案 Take a snapshot of current screen with Metal in swift 一样,但它要求 MTKView 将 framebufferOnly 设置为 false,这会根据 Apple 禁用一些优化。

有没有办法复制 MTKView 纹理(例如 view.currentDrawable.texture)以便我可以读取像素?我不需要经常截图,所以禁用程序运行的整个生命周期的优化将是一种耻辱。

我尝试使用 MTLTexture.newTextureViewWithPixelFormat 和 blit 缓冲区,但我仍然得到相同的异常,即帧缓冲区仅为 true。

【问题讨论】:

    标签: swift macos cocoa metal metalkit


    【解决方案1】:

    当请求截屏时,您可以切换framebufferOnly,进行一次渲染,然后将其切换回来。

    或者,您可以针对您自己规范的纹理进行一次渲染传递,将其 blit 到可绘制对象的纹理(以免在视觉上丢帧),然后保存您自己的纹理内容。

    【讨论】:

    • 我什至没有考虑渲染到另一个目标(我认为像 OpenGL 中的 FBO),但这可能是最好的方法。是通过在MTLRenderPassDescriptor的颜色附件中设置纹理来完成的吗?
    • 你知道如何使用 MetalKit 强制渲染通道吗?我首先尝试切换 framebufferOnly,但我似乎需要允许一些事件循环在它注册之前通过。老实说,甚至不清楚何时在渲染循环中拍摄屏幕截图,所以也许我也搞砸了。
    • 是的,您只需在渲染通道描述符中设置颜色附件纹理。此外,渲染管线描述符中的颜色附件像素格式必须匹配。您可以在 MTKView 上调用 draw 以强制渲染通道。顺便说一句,在命令缓冲区完成之前,您不能访问纹理内容,并确保 blit 命令编码器在最后也放入 synchronize 命令。
    • 我决定切换 frameBufferOnly。奇怪的是,它需要在将 frameBufferOnly 设置为 false 后调用 MTKView.draw 3x,否则我会得到一个空白图像。
    猜你喜欢
    • 2014-12-05
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    相关资源
    最近更新 更多