Почему Metal не отображает мой простой понятный код окна?

#xcode #gpu #metal #metalkit

#xcode #графический процессор #Металлические #metalkit

Вопрос:

Я следовал этому руководству. Я скачал исходный код и попытался «перевести» его на 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 является оригинальным, и у меня нет основного файла.

В итоге я получаю окно, которое не отображается красным, а скорее ничего не показывает. Я не понимаю, почему это происходит. Пожалуйста, помогите мне, спасибо.

Ответ №1:

Я вижу две проблемы.

1) MTKView Свойством delegate является 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
  

Комментарии:

1. Это работает, спасибо. Но почему я должен сохранять средство визуализации? Разве это не находится внутри делегата представления?

2. Похоже, вы, возможно, не понимаете различия между сильными и слабыми ссылками. Вы можете прочитать больше здесь .

Ответ №2:

Ну, это может быть что угодно. Но первое, что я бы проверил, это то, что ваша настройка alpha для этого красного цвета должна иметь alpha = 1.0, а не alpha = 0.0.

Комментарии:

1. Спасибо, хотя это проблема.