我正在遵循基本 Metal 教程的设置,并尝试渲染统一颜色的空白屏幕。
出于某种原因,我遇到了这个问题:Metal 仅绘制到屏幕的一部分。
我设置了一个单一 View 应用程序,并将 MainStoryboard 的 View 附加到我正在创建的类中。我将其背景颜色设置为绿色。
这是类(class)
class MBEMetalView: UIView {
var device:MTLDevice?
var MTLLayer:CAMetalLayer?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
device = MTLCreateSystemDefaultDevice()
//The book said to cast the layer to a CAMetalLayer
//but that causes a crash in the redraw method because
//failed assertion `No rendertargets set in RenderPassDescriptor.'
//So we do this.. which might be wasteful?
MTLLayer = CAMetalLayer()
MTLLayer?.device = device
MTLLayer?.pixelFormat = MTLPixelFormat.bgra8Unorm
MTLLayer?.framebufferOnly = true
MTLLayer?.frame = frame
layer.addSublayer(MTLLayer!)
}
override func didMoveToWindow() {
redraw()
}
func redraw() {
var drawable = MTLLayer?.nextDrawable()
var texture = drawable?.texture
var passDescriptor = MTLRenderPassDescriptor()
passDescriptor.colorAttachments[0].texture = texture
passDescriptor.colorAttachments[0].loadAction = MTLLoadAction.clear
passDescriptor.colorAttachments[0].storeAction = MTLStoreAction.store
passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 1, 0, 1)
var commandQueue = device?.makeCommandQueue()
var commandBuffer = commandQueue?.makeCommandBuffer()
var commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: passDescriptor)
commandEncoder?.endEncoding()
if let drawOn = drawable {
commandBuffer?.present(drawOn)
commandBuffer?.commit()
}
}
}
该类应该将整个屏幕渲染为绿色,但事实并非如此,它只填充了一部分,如 iPhone 6s plus 的图片所示(红色是 View 的背景,而不是 Metal 正在绘制的内容)。
这个结果让我想起了几个问题:
- 为什么 Metal 只渲染到屏幕的一部分
- 我接下来的教程是在 Objective-C 中完成的,他们能够将继承的 UIView 层转换为 CAMetal 层
而不是创建一个新层(这允许他们删除
.addSublayer
行)。然而,当我尝试这个时,我遇到了崩溃 在评论中显示?这是为什么? - 传入的帧将如何受到 iPhone X 等具有安全区域的设备的影响?我需要画一些额外的东西吗 安全区之外?哪里可以查到保险箱的尺寸 以编程方式从我的 View 框架中获取区域(如果新设备 已发布)
最佳答案
您可以在 init(coder)
中设置 CAMetalLayer
的框架,并且永远不会更改它。但在 init(coder) 中,最终帧大小尚不清楚(它只是使用您此时在 Interface Builder 中设置的任何大小,但尚未使用设备大小)。在didMoveToWindow()
中,还将Metal层的框架设置为其最终大小。 (或者也许在 layoutSubviews()
中。)
关于ios - Metal 仅绘制 View 的一部分并查询图层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47902056/