【发布时间】:2018-06-02 18:41:33
【问题描述】:
我正在按照基本金属教程的设置,并尝试渲染一个统一颜色的空白屏幕。
由于某种原因,我遇到了 Metal 仅绘制到屏幕的一部分的问题。
我设置了一个单视图应用程序并将 MainStoryboard 的视图附加到我正在创建的类中。我将其背景颜色设置为绿色。
这是课程
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 的这张图片所示的一部分(红色是视图的背景,而不是 Metal 正在绘制的内容)。
这个结果让人想起几个问题:
- 为什么 Metal 只渲染到屏幕的一部分
- 我正在关注的教程是在 Objective-C 中进行的,他们能够将继承的 UIView 的层转换为 CAMetal 层
而不是创建一个新层(这允许他们删除
.addSublayer行)。但是,当我尝试这个时,我遇到了崩溃 在 cmets 中显示?这是为什么呢? - 像 iPhone X 这样具有安全区域的设备会如何影响传入的帧?我需要额外的东西来画吗 在安全区域之外?我在哪里可以得到保险箱的尺寸 以编程方式显示我视图框架中的区域(以防新设备 发布)
【问题讨论】: