SceneKit Cocoa 快照失败断言

Posted

技术标签:

【中文标题】SceneKit Cocoa 快照失败断言【英文标题】:SceneKit Cocoa snapshot failed assertion 【发布时间】:2017-06-18 16:12:06 【问题描述】:

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

此应用程序包含一个 SceneKit 视图。渲染 API 设置为 Default(我认为这是 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 硬件上运行它? Mac 2012 或更高版本支持 Metal。见support.apple.com/en-us/HT205073。此外,在 macOS 上,快照返回 NSImage 而不是 UIImage。 mac os x 部署目标是 v 10.11。我的 mac 是 2013 年中。你对 NSImage/UIImage 是真的 你能展示一些示例代码吗? 无法重现此行为。通过您的源代码,snapshot() 可以与 OpenGL 和 Metal API 一起使用。 macOS 10.11.6 iMac(27 英寸,2012 年末),Xcode 8.1。 【参考方案1】:

它适用于金属。

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

我在 macOS 10.15.4 Catalina 上使用 Xcode 11.4。

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
    

【讨论】:

以上是关于SceneKit Cocoa 快照失败断言的主要内容,如果未能解决你的问题,请参考以下文章

如何将堆栈跟踪打印到控制台/登录 Cocoa?

确定 Windows 线程是不是在关键部分或类似部分?

Mattt Thompson:Cocoa之死

从 Cocoa 应用程序(通过 NSTask)静默运行 xcodebuild 两次失败

为啥流利的断言失败但断言通过了枚举?

AFNetworking POST 写入服务器并返回失败错误(Cocoa 错误 3840)