swift – ModelIO框架不起作用
我正在尝试导入3D模型文件并使用MetalIO使用ModelIO和MetalKit(在OS X 10.11上)渲染它们,但我从这些框架(特别是ModelIO)看到的行为并不像预期的那样.
我可以导入.obj文件并将它们转换为MetalKit网格而不会导致任何错误,但是网格(至少在渲染下)似乎只是一个三角形的大粉丝,它们都是从一个点发出的.下面屏幕截图中的模型应该是“Suzanne”猴头的细分版本: 在检查时,导入文件中MDLSubmesh的顶点索引没有任何意义.连续的索引集合始终引用索引0处的顶点,有时在同一组索引中多次,这将解释渲染期间的外观.我已经确认这个.obj文件可以很好地导入到其他应用程序中. 我尝试导入其他3D文件格式(所有正式支持的框架),但除了.obj之外的任何格式都会在调用MDLAsset的init()时导致未捕获的NSException. 我正在使用Xcode 7.2并以OS X 10.11为目标. 解决方法
我也遇到过类似的问题,虽然我是Metal的新秀,但我想出了一些问题.
我试图进口Melita茶壶,但我也有一个“爆炸”的面孔,而不是标志性的茶叶冲泡设备.在阅读MDLVertexBufferLayout的文档后,我找到了解决方案:
通过查看MDLVertexDescriptor的默认实现的.layouts和.attributes属性,他们为每个属性类型创建一个缓冲区(如上面的引用,第一种情况),我想使用混合模式. 我用我自己的数组手动设置.layouts和.attributes然后,我得到了……半个梅丽塔锅? class func setup(meshWithDevice device: MTLDevice) -> MTKMesh { // Allocator let allocator = MTKMeshBufferAllocator(device: device) // Vertex Descriptor,tells the MDLAsset how to layout the buffers let vertexDescriptor = MDLVertexDescriptor() // Vertex Buffer Layout,tells how many buffers will be used,and the stride of its structs // (the init(stide: Int) crashes in the Beta) let vertexLayout = MDLVertexBufferLayout() vertexLayout.stride = MemoryLayout<Vertex>.size // Apply the Layouts vertexDescriptor.layouts = [vertexLayout] // Apply the attributes,in my case,position and normal (float4 x2) vertexDescriptor.attributes = [ MDLVertexAttribute(name: MDLVertexAttributePosition,format: MDLVertexFormat.float4,offset: 0,bufferIndex: 0),MDLVertexAttribute(name: MDLVertexAttributeNormal,offset: MemoryLayout<float4>.size,bufferIndex: 0) ] var error : NSError? = nil // Load the teapot let asset = MDLAsset(url: Bundle.main.url(forResource: "teapot",withExtension: "obj")!,vertexDescriptor: vertexDescriptor,bufferAllocator: allocator,preserveTopology: true,error: &error) if let error = error { print(error) } // Obtain the teapot Mesh let teapotModel = asset.object(at: 0) as! MDLMesh // Convert into MetalKit Mesh,insted of ModelIO let teapot = try! MTKMesh(mesh: teapotModel,device: device) return teapot } (XCode 8 Beta 6中的Swift 3.0) 如果我设法渲染整个内容,我会更新我的帖子. 编辑:立即工作 Whelp,这个bug就在我的最后,我在索引计数中错了: //// Buffers renderPass.setVertexBuffer(mesh.vertexBuffers[0].buffer,at: 0) renderPass.setVertexBuffer(uniformBuffer,at: 1) let submesh = mesh.submeshes[0] let indexSize = submesh.indexType == .uInt32 ? 4 : 2 //// Draw Indices renderPass.drawIndexedPrimitives(submesh.primitiveType,indexCount: submesh.indexBuffer.length / indexSize,indexType: submesh.indexType,indexBuffer: submesh.indexBuffer.buffer,indexBufferOffset: 0) 问题是让indexSize = submesh.indexType == .uInt32? 4:2,在我做右边32:16之前,但.length属性以字节而不是位,所以很笨. 无论如何,我设法用Metal加载一个Obj文件,所以问题是:我上面提到的每个属性的单独缓冲,或者代码中完全不同的问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |