首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ModelIO框架不工作

ModelIO框架不工作
EN

Stack Overflow用户
提问于 2016-01-02 03:27:53
回答 1查看 1K关注 0票数 4

我试图导入3D模型文件,并使用Metal (在OSX10.11上)使用ModelIOMetalKit呈现它们,但我从这些框架(特别是ModelIO)中看到的行为并不像预期的那样。

我可以导入.obj文件并将它们转换为MetalKit网格,而不会造成任何错误,但是网格(至少在渲染下)似乎只是一个大的三角形扇形,所有三角形都是从一个点发出的。下面屏幕截图中的模型应该是"Suzanne“猴头的细分版本:

在检查时,导入文件中的MDLSubmesh顶点索引没有任何意义。连续的索引集继续引用索引0的顶点,有时在同一组索引中多次引用,这将解释呈现过程中的外观。我已经确认这个.obj文件可以导入到其他应用程序中。

我尝试过导入其他3D文件格式(所有这些格式都得到了框架的官方支持),但是除了.obj之外,任何其他格式都会在调用MDLAssetinit()时引起不透明的init()

我正在使用Xcode 7.2并以OSX10.11为目标。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-26 04:40:43

我也经历过类似的问题,虽然我是一名金属新手,但我发现了一些事情。

我试图进口梅丽塔茶壶,但我也有一个“爆炸”的面孔,而不是标志性的泡茶设备。在阅读了MDLVertexBufferLayout的文档之后,我找到了解决方案,该文档内容如下:

网格可以将顶点数据存储在阵列模型的结构中,其中每个顶点属性(例如顶点位置或表面法线)的数据位于单独的顶点缓冲器中,或者存储在结构模型数组中,其中多个顶点属性共享相同的缓冲区。

  • 在数组结构中,网格的vertexBuffers数组包含多个MDLMeshBuffer对象,网格的vertexDescriptor对象为每个缓冲区包含一个单独的MDLVertexBufferLayout对象。
  • 在结构数组中,网格包含单个顶点缓冲区,其描述符包含单个顶点缓冲区布局对象。要确定缓冲区中的哪些字节引用了哪些顶点和顶点属性,请使用布局的步长以及描述符的顶点属性的格式和偏移量属性。

通过查看默认实现的.layouts.attributes属性,它们为每个属性类型创建一个缓冲区(如上面的引号,第一个例子),其中我想使用混合模式。

我用自己的数组手动设置了.layouts.attributes,然后,我得到了.半个梅丽塔壶?

代码语言:javascript
复制
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, format: MDLVertexFormat.float4, 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 )

如果我能把整件事都呈现出来,我就会更新我的帖子。

编辑:现在开始工作

孩子,这个错误在我的头上,我在指数上错了:

代码语言:javascript
复制
//// Buffers
renderPass.setVertexBuffer(mesh.vertexBuffers[0].buffer, offset: 0, 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)

问题在于let indexSize = submesh.indexType == .uInt32 ? 4 : 2,在我从右边做32 : 16之前,但是.length属性是以字节(而不是位)的形式出现的,非常愚蠢。

无论如何,我成功地用Metal加载了一个Obj文件,所以问题要么是:我前面提到的单个缓冲每个属性的问题,要么是代码中的一个完全不同的问题。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34562300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档