#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. Спасибо, хотя это проблема.