SceneKit Cocoa 快照失败断言

22

我正在开发一款Swift/Cocoa/Xcode应用程序。

这个应用程序包含一个SceneKit视图。渲染API设置为默认值(我认为这是Metal)。

如果在这个SceneKit视图对象上运行snapshot(),我会收到以下错误消息。 我想做的是从相机捕获场景的UIImage。

Texture PixelFormat MTLPixelFormatBGRA8Unorm does not match Resolve PixelFormat MTLPixelFormatRGBA8Unorm
如果我将渲染API设置为OpenGL,就没有错误,一切正常。
我在iOS应用程序上尝试了相同的操作,在这两种情况下都可以工作(Metal或OpenGL)。
我不明白为什么会出现这个错误,以及该怎么做才能避免它。
以下是示例代码:
    import SceneKit
    import Cocoa

    class ViewController: NSViewController {

        @IBOutlet weak var vue_scene: SCNView!
        @IBOutlet weak var img_snapshot: NSImageView!

        let camera_node = SCNNode()
        var box_node:SCNNode = SCNNode()

        override func viewDidLoad() {
            super.viewDidLoad()

            let scene = SCNScene()
            vue_scene.scene = scene

            vue_scene.backgroundColor = NSColor.clear

            vue_scene.showsStatistics = false
            vue_scene.allowsCameraControl = false
            vue_scene.autoenablesDefaultLighting = true

            camera_node.camera = SCNCamera()
            camera_node.camera?.zNear = 0.01
            camera_node.camera?.zFar = 1000000.0
            vue_scene.pointOfView = camera_node
            vue_scene.scene!.rootNode.addChildNode(camera_node)

            let box = SCNBox(width: 10.0, 
                            height: 10.0, 
                            length: 10.0, 
                     chamferRadius: 0.0)
            box.firstMaterial?.diffuse.contents = NSColor.red

            box.firstMaterial?.isDoubleSided = true
            box_node = SCNNode(geometry:box)
            box_node.position = SCNVector3Make(0,0,0)
            box_node.opacity = 1.0
            vue_scene.scene!.rootNode.addChildNode(box_node)

            camera_node.position = SCNVector3Make(0.0,
                                                  0.0,
                                                 70.0)
        }

        @IBAction func on_btn(_ sender: Any) {
            // signal SIGABRT here:
            // /Library/Caches/com.apple.xbs/Sources/Metal/Metal-56.6.1/ToolsLayers/Debug/MTLDebugCommandBuffer.mm:215: failed assertion `Texture PixelFormat MTLPixelFormatBGRA8Unorm does not match Resolve PixelFormat MTLPixelFormatRGBA8Unorm'
            let image = vue_scene.snapshot()
            img_snapshot.image = image;
        }
    }

Q1:您使用的是哪个macOS版本?快照仅在10.10及以上版本中可用。 Q2:您在哪台Mac硬件上运行此程序?Metal支持2012年或之后的Mac。请参见https://support.apple.com/en-us/HT205073。另外,在macOS上,快照返回NSImage而不是UIImage。 - sambro
Mac OS X的部署目标是v10.11。我的Mac是2013年中期的。你说的NSImage/UIImage是正确的。 - Bob5421
你能展示一些样例代码吗? - sambro
无法重现此行为。使用您的源代码,snapshot() 可以与 OpenGL 和 Metal API 一起工作。macOS 10.11.6 iMac(27 英寸,2012 年末),Xcode 8.1。 - Ef Dot
1个回答

2

它在 Metal 上工作。

在 macOS 上,使用 Tab View(例如)来容纳 SceneViewNSImageView

我还在 macOS 12.3 Monterey 上测试了它在 Xcode 13.3 中的运行情况。

import SceneKit
import Cocoa

class ViewController: NSViewController {
    
    @IBOutlet var sceneView: SCNView!
    @IBOutlet var imageView: NSImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()            
        sceneView.scene = SCNScene()
        
        sceneView.pointOfView?.position.z = 20
        sceneView.allowsCameraControl = true
        sceneView.showsStatistics = true
        sceneView.backgroundColor = NSColor.black
        sceneView.autoenablesDefaultLighting = true

        let box = SCNBox(width: 1.0, height: 1.0,
                        length: 1.0, chamferRadius: 0.0)
        
        box.firstMaterial?.diffuse.contents = NSColor.systemTeal

        let boxNode = SCNNode(geometry: box)
        boxNode.position = SCNVector3(0,0,-10)
        sceneView.scene!.rootNode.addChildNode(boxNode)
    }
    
    @IBAction func createSnapshot(_ sender: NSButton) {
        let image = sceneView.snapshot()
        imageView.image = image
    }
}

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接