【问题标题】:Why doesn't Metal render my simple clear window code?为什么 Metal 不呈现我简单的清晰窗口代码?
【发布时间】:2019-08-12 00:05:00
【问题描述】:

我一直在关注this 教程。我下载了源代码并尝试将其“翻译”为 Swift。这是我的“翻译”代码:

import Cocoa
import AppKit
import MetalKit

import simd


class MetalViewController: NSViewController {

    @IBOutlet var inview: MTKView!
    override func viewDidLoad() {
        super.viewDidLoad()
        let _view: MTKView = self.inview
        _view.device = MTLCreateSystemDefaultDevice()
        let _renderer: Renderer=initView(view: _view)
        _view.delegate=_renderer as? MTKViewDelegate
        _view.preferredFramesPerSecond=60
    }
}
class Renderer: NSObject {
    init(device: MTLDevice){
        self._device=device
        self._commandQueue=_device.makeCommandQueue()!
        super.init()
    }
    func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {

    }
    func draw(in view: MTKView) {
        let color = Color(red: 1.0,green: 0.0,blue: 0.0,alpha: 0.0)
        view.clearColor = MTLClearColorMake(color.red, color.green, color.blue, color.alpha)
        let commandbuffer = _commandQueue.makeCommandBuffer()
        let renderpassdescriptor: MTLRenderPassDescriptor = view.currentRenderPassDescriptor!
        let renderencoder: MTLRenderCommandEncoder = (commandbuffer?.makeRenderCommandEncoder(descriptor: renderpassdescriptor))!
        renderencoder.endEncoding()
        commandbuffer!.present(view.currentDrawable!)
        commandbuffer!.commit()
    }

    var _device: MTLDevice
    var _commandQueue: MTLCommandQueue

}

struct Color{
    var red, green, blue, alpha: Double
}

func initView(view: MTKView) -> Renderer{
    var renderer: Renderer
    renderer=Renderer(device: view.device!)
    return renderer
}

所以我将 AAPLRenderer 和 AAPLViewControllers 放在一个文件中,并使其没有头文件。我将带有@IBOutlet 的视图链接到视图控制器,因为该视图是一个 NSView 并且我无法将其转换为 MTKView 而不会出现编译时错误。 AppDelegate 是原始的,我没有主文件。

我最终得到一个不显示红色的窗口,而是什么也不显示。我不明白为什么会这样。请帮帮我,谢谢。

【问题讨论】:

    标签: xcode gpu metal metalkit


    【解决方案1】:

    我看到了两个问题。

    1) MTKViewdelegate 属性是 weak var,这意味着如果您不保留渲染器的实例,它将立即被取消初始化并且永远不会收到任何委托回调。保留对渲染器的引用作为视图控制器上的属性。

    class MetalViewController: NSViewController {
        @IBOutlet var inview: MTKView!
        var renderer: Renderer!
    
        override func viewDidLoad() {
            // ...
            let view: MTKView = self.inview
            // ...
            renderer = initView(view: view)
            view.delegate = renderer
            // ...
        }
    }
    

    2) 因为Renderer 类没有明确声明符合MTKViewDelegate 协议,所以在将其分配为视图的委托时条件转换失败。使Renderer 显式符合协议,并删除如上所示的条件转换。

    class Renderer: NSObject, MTKViewDelegate
    

    【讨论】:

    • 这行得通,谢谢。但是,为什么我必须保留渲染器?不就是在view的delegate里面吗?
    • 听起来你可能不明白强引用和弱引用的区别。你可以read more here
    【解决方案2】:

    嗯,它可以是任何东西。但是,我要检查的第一件事是你的红色的 alpha 设置应该是 alpha = 1.0 而不是 alpha = 0.0。

    【讨论】:

    • 谢谢,不过是个问题。
    猜你喜欢
    • 2017-04-04
    • 2021-04-21
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    相关资源
    最近更新 更多