gpt4 book ai didi

swift - Metal API View 没有渲染 channel 描述符

转载 作者:行者123 更新时间:2023-12-03 17:45:58 27 4
gpt4 key购买 nike

我目前正在尝试在 Xcode 中不使用 IB 的情况下构建一个 Metal 应用程序(纯粹以编程方式,没有 Storyboard),并且在使用 MTKView Delegate 进行渲染时遇到了一些问题。

我创建了以下 3 个类

应用程序委托(delegate):

import Cocoa
import MetalKit

class AppDelegate: NSObject, NSApplicationDelegate
{
var newWindow: NSWindow?
var controller: ViewController?

func applicationDidFinishLaunching(_ notification: Notification) {
newWindow = NSWindow(contentRect: NSMakeRect(10, 10, 300, 300), styleMask: [.miniaturizable, .closable, .resizable, .titled], backing: .buffered, defer: false)

controller = ViewController()
let content = newWindow!.contentView! as NSView
let view = controller!.view
content.addSubview(view)
newWindow!.makeKeyAndOrderFront(nil)
}

}

View Controller :

import Cocoa
import MetalKit

class ViewController: NSViewController {

var renderer: Renderer?

override func loadView() {
view = MTKView.init()
}

override func viewDidLoad() {
guard let metalView = view as? MTKView else {
fatalError("Cant Get Metal View")
}

super.viewDidLoad()

renderer = Renderer(metalView: metalView)
}
}

渲染器.swift:

import MetalKit

class Renderer: NSObject {

static var device: MTLDevice!
static var commandQueue: MTLCommandQueue!
var mesh: MTKMesh!
var vertexBuffer: MTLBuffer!
var pipelineState: MTLRenderPipelineState!

init(metalView: MTKView) {

guard
let device = MTLCreateSystemDefaultDevice(),
let commandQueue = device.makeCommandQueue() else {
fatalError("GPU not available")
}

Renderer.device = device
Renderer.commandQueue = commandQueue
metalView.device = device

let mdlMesh = Primative.makeCube(device: device, size: 1)

do {
mesh = try MTKMesh(mesh: mdlMesh, device: device)
} catch let error {
print(error.localizedDescription)
}
vertexBuffer = mesh.vertexBuffers[0].buffer

let library = device.makeDefaultLibrary()
let vertexFunction = library?.makeFunction(name: "vertex_main")
let fragmentFunction = library?.makeFunction(name: "fragment_main")

let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = vertexFunction
pipelineDescriptor.fragmentFunction = fragmentFunction
pipelineDescriptor.vertexDescriptor =
MTKMetalVertexDescriptorFromModelIO(mdlMesh.vertexDescriptor)
pipelineDescriptor.colorAttachments[0].pixelFormat = metalView.colorPixelFormat
do {
pipelineState = try device.makeRenderPipelineState(descriptor: pipelineDescriptor)
} catch let error {
fatalError(error.localizedDescription)
}

super.init()
metalView.clearColor = MTLClearColor(red: 1.0, green: 1.0,
blue: 0.8, alpha: 1.0)
metalView.delegate = self
}
}

extension Renderer: MTKViewDelegate {
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {

}

func draw(in view: MTKView) {
// Creating Render Pass Descriptor
if let descriptor = view.currentRenderPassDescriptor
{
print("Drawing")
}
else {
print("Not Drawing")
}
}
}

这三个类可以很好地渲染窗口,并且输出

Not Drawing

表明该值始终为 null,但它每帧都在执行某些操作。

我尝试过的事情

  • 创建我自己的渲染 channel 描述符:这导致了 sig 错误。
  • 查看了 View ,肯定被识别为MTKView

如果我使用基于文件中 Storyboard的项目,我知道这是可行的,但我希望了解如何在没有它的情况下做到这一点。

任何帮助将不胜感激

最佳答案

来自MTKView.currentRenderPassDescriptor的文档:

This property is nil if the view’s device property isn’t set or if currentDrawable is nil.

您需要为MTKView提供一个可以使用的 Metal 设备。 IB 可能会默认给它 MTLCreateSystemDefaultDevice() ,但是当您以编程方式创建 View 时,您需要手动执行:

override func loadView() {
view = MTKView(frame: .zero, device: MTLCreateSystemDefaultDevice())
}

关于swift - Metal API View 没有渲染 channel 描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61316696/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com