2017-10-18 84 views
2

如果你使用的是iOS金屬,並有自定義編程的對象模型,並(像我)你的模型MDLMesh對象停止與金屬2和iOS 11的問世工作,那麼你可能已經開始研究如何以編程方式生成MDLMesh。程序生成使用initWithVertexBuffers

Apple文檔說:「通常情況下,您通過遍歷MDLAsset對象的對象層次結構來獲取網格,但您也可以從您自己的頂點數據創建網格或創建參數化網格。」不幸的是,它沒有提供說明或示例代碼。

你快速找到雙MDLMesh初始化調用,initWithVertexBuffer和initWithVertexBuffers。就像你在網上找不到任何示例代碼或討論一樣,至少我沒有找到任何代碼。

因爲它是不直觀明顯,這種漫不經心的觀察者應該怎樣做,代碼樣本特此請求。

+0

回答你自己的問題並沒有什麼錯 - 這在這裏很常見。你應該繼續這樣做(並確保將其標記爲已接受)。 – user5226582

回答

3

有大量的實例創建使用的EG的工廠參數方法之一MDLMesh,立方體:

[MDLMesh newBoxWithDimensions:... 

用最簡單的這些,對於一個「平面」(矩形),我生成具有最小數量的頂點的一個1x1矩形:

MDLMesh *mdlMesh = [MDLMesh newPlaneWithDimensions:(vector_float2){1.0, 1.0} 
              segments:(vector_uint2){1, 1} 
             geometryType:MDLGeometryTypeTriangles 
             allocator:metalAllocator]; 

然後我用Xcode的調試器來調查什麼導致MDLMesh樣子,以此來指導一個更簡單的對象我的創作,一個綱領性的等邊三角形。

以下代碼適用於我。我敢肯定,比我更懂金屬的人可以提供更好的解決方案。但希望這將讓你開始,在正確的方向的一些外表...

所以,直到有用於

[MDLMesh newEquilateralTriangleWithEdgeLength:... 

一個新的工廠參數方法下面的代碼似乎這樣的伎倆......

static const float equilateralTriangleVertexData[] = 
{ 
     0.000000, 0.577350, 0.0, 
    -0.500000, -0.288675, 0.0, 
     0.500000, -0.288675, 0.0, 
}; 

static const vector_float3 equilateralTriangleVertexNormalsData[] = 
{ 
    { 0.0, 0.0, 1.0 }, 
    { 0.0, 0.0, 1.0 }, 
    { 0.0, 0.0, 1.0 }, 
}; 

static const vector_float2 equilateralTriangleVertexTexData[] = 
{ 
    { 0.50, 1.00 }, 
    { 0.00, 0.00 }, 
    { 1.00, 0.00 }, 
}; 

int numVertices = 3; 

int lenBufferForVertices_position   = sizeof(equilateralTriangleVertexData); 
int lenBufferForVertices_normal   = numVertices * sizeof(vector_float3); 
int lenBufferForVertices_textureCoordinate = numVertices * sizeof(vector_float2); 

MTKMeshBuffer *mtkMeshBufferForVertices_position   = (MTKMeshBuffer *)[metalAllocator newBuffer:lenBufferForVertices_position   type:MDLMeshBufferTypeVertex]; 
MTKMeshBuffer *mtkMeshBufferForVertices_normal   = (MTKMeshBuffer *)[metalAllocator newBuffer:lenBufferForVertices_normal   type:MDLMeshBufferTypeVertex]; 
MTKMeshBuffer *mtkMeshBufferForVertices_textureCoordinate = (MTKMeshBuffer *)[metalAllocator newBuffer:lenBufferForVertices_textureCoordinate type:MDLMeshBufferTypeVertex]; 

// Now fill the Vertex buffers with vertices. 

NSData *nsData_position   = [NSData dataWithBytes:equilateralTriangleVertexData  length:lenBufferForVertices_position]; 
NSData *nsData_normal   = [NSData dataWithBytes:equilateralTriangleVertexNormalsData length:lenBufferForVertices_normal]; 
NSData *nsData_textureCoordinate = [NSData dataWithBytes:equilateralTriangleVertexTexData  length:lenBufferForVertices_textureCoordinate]; 

[mtkMeshBufferForVertices_position   fillData:nsData_position   offset:0]; 
[mtkMeshBufferForVertices_normal   fillData:nsData_normal   offset:0]; 
[mtkMeshBufferForVertices_textureCoordinate fillData:nsData_textureCoordinate offset:0]; 

NSArray <id<MDLMeshBuffer>> *arrayOfMeshBuffers = [NSArray arrayWithObjects:mtkMeshBufferForVertices_position, mtkMeshBufferForVertices_normal, mtkMeshBufferForVertices_textureCoordinate, nil]; 

static uint16_t indices[] = 
{ 
    0, 1, 2, 
}; 

int numIndices = 3; 

int lenBufferForIndices = numIndices * sizeof(uint16_t); 
MTKMeshBuffer *mtkMeshBufferForIndices = (MTKMeshBuffer *)[metalAllocator newBuffer:lenBufferForIndices type:MDLMeshBufferTypeIndex]; 

NSData *nsData_indices = [NSData dataWithBytes:indices length:lenBufferForIndices]; 
[mtkMeshBufferForIndices fillData:nsData_indices offset:0]; 

MDLScatteringFunction *scatteringFunction = [MDLPhysicallyPlausibleScatteringFunction new]; 
MDLMaterial *material = [[MDLMaterial alloc] initWithName:@"plausibleMaterial" scatteringFunction:scatteringFunction]; 

// Not allowed to create an MTKSubmesh directly, so feed an MDLSubmesh to an MDLMesh, and then use that to load an MTKMesh, which makes the MTKSubmesh from it. 
MDLSubmesh *submesh = [[MDLSubmesh alloc] initWithName:@"summess" // Hackspeke for @"submesh" 
              indexBuffer:mtkMeshBufferForIndices 
              indexCount:numIndices 
              indexType:MDLIndexBitDepthUInt16 
              geometryType:MDLGeometryTypeTriangles 
               material:material]; 

NSArray <MDLSubmesh *> *arrayOfSubmeshes = [NSArray arrayWithObjects:submesh, nil]; 

MDLMesh *mdlMesh = [[MDLMesh alloc] initWithVertexBuffers:arrayOfMeshBuffers 
               vertexCount:numVertices 
               descriptor:mdlVertexDescriptor 
               submeshes:arrayOfSubmeshes]; 
+0

更改了equilateralTriangleVertexData的定義,因爲當它是一個vector_float3數組時,三角形不能正確顯示。不知道爲什麼,但是讓它成爲一組浮動工程。其他數據似乎沒問題。 –