public static MTLVertexDescriptor FromModelIO(MDLVertexDescriptor descriptor) { if (descriptor == null) { throw new ArgumentException("descriptor"); } return(Runtime.GetNSObject <MTLVertexDescriptor> (MTKMetalVertexDescriptorFromModelIO(descriptor.Handle))); }
public static MTLVertexDescriptor FromModelIO(MDLVertexDescriptor descriptor, out NSError error) { if (descriptor == null) { throw new ArgumentException("descriptor"); } IntPtr err; var vd = Runtime.GetNSObject <MTLVertexDescriptor> (MTKMetalVertexDescriptorFromModelIOWithError(descriptor.Handle, out err)); error = Runtime.GetNSObject <NSError> (err); return(vd); }
void LoadAssets() { // Load the fragment program into the library. IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("fragmentLight"); // Load the vertex program into the library. IMTLFunction vertexProgram = defaultLibrary.CreateFunction("vertexLight"); /* * Create a vertex descriptor for our Metal pipeline. Specifies the layout * of vertices the pipeline should expect. */ var mtlVertexDescriptor = new MTLVertexDescriptor(); // Positions. mtlVertexDescriptor.Attributes [(int)VertexAttributes.Position].Format = MTLVertexFormat.Float3; mtlVertexDescriptor.Attributes [(int)VertexAttributes.Position].Offset = 0; mtlVertexDescriptor.Attributes [(int)VertexAttributes.Position].BufferIndex = (nuint)(int)BufferIndex.MeshVertexBuffer; // Normals. mtlVertexDescriptor.Attributes[(int)VertexAttributes.Normal].Format = MTLVertexFormat.Float3; mtlVertexDescriptor.Attributes[(int)VertexAttributes.Normal].Offset = 12; mtlVertexDescriptor.Attributes[(int)VertexAttributes.Normal].BufferIndex = (nuint)(int)BufferIndex.MeshVertexBuffer; // Texture coordinates. mtlVertexDescriptor.Attributes[(int)VertexAttributes.Texcoord].Format = MTLVertexFormat.Half2; mtlVertexDescriptor.Attributes[(int)VertexAttributes.Texcoord].Offset = 24; mtlVertexDescriptor.Attributes[(int)VertexAttributes.Texcoord].BufferIndex = (nuint)(int)BufferIndex.MeshVertexBuffer; // Single interleaved buffer. mtlVertexDescriptor.Layouts[(int)BufferIndex.MeshVertexBuffer].Stride = 28; mtlVertexDescriptor.Layouts[(int)BufferIndex.MeshVertexBuffer].StepRate = 1; mtlVertexDescriptor.Layouts[(int)BufferIndex.MeshVertexBuffer].StepFunction = MTLVertexStepFunction.PerVertex; // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { Label = "MyPipeline", SampleCount = view.SampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, VertexDescriptor = mtlVertexDescriptor }; pipelineStateDescriptor.ColorAttachments [0].PixelFormat = view.ColorPixelFormat; pipelineStateDescriptor.DepthAttachmentPixelFormat = view.DepthStencilPixelFormat; pipelineStateDescriptor.StencilAttachmentPixelFormat = view.DepthStencilPixelFormat; NSError error; pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error); if (pipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error.LocalizedDescription); } var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true, }; depthState = device.CreateDepthStencilState(depthStateDesc); /* * From our Metal vertex descriptor, create a Model I/O vertex descriptor we'll * load our asset with. This specifies the layout of vertices Model I/O should * format loaded meshes with. */ var mdlVertexDescriptor = MDLVertexDescriptor.FromMetal(mtlVertexDescriptor); mdlVertexDescriptor.Attributes.GetItem <MDLVertexAttribute> ((int)VertexAttributes.Position).Name = MDLVertexAttributes.Position; mdlVertexDescriptor.Attributes.GetItem <MDLVertexAttribute> ((int)VertexAttributes.Normal).Name = MDLVertexAttributes.Normal; mdlVertexDescriptor.Attributes.GetItem <MDLVertexAttribute> ((int)VertexAttributes.Texcoord).Name = MDLVertexAttributes.TextureCoordinate; var bufferAllocator = new MTKMeshBufferAllocator(device); NSUrl assetUrl = NSBundle.MainBundle.GetUrlForResource("Data/Assets/realship/realship.obj", string.Empty); if (assetUrl == null) { Console.WriteLine("Could not find asset."); } /* * Load Model I/O Asset with mdlVertexDescriptor, specifying vertex layout and * bufferAllocator enabling ModelIO to load vertex and index buffers directory * into Metal GPU memory. */ var asset = new MDLAsset(assetUrl, mdlVertexDescriptor, bufferAllocator); // Create MetalKit meshes. MDLMesh[] mdlMeshes; NSError mtkError; var mtkMeshes = MTKMesh.FromAsset(asset, device, out mdlMeshes, out mtkError); if (mtkMeshes == null) { Console.WriteLine("Failed to create mesh, error {0}", error.LocalizedDescription); return; } // Create our array of App-Specific mesh wrapper objects. meshes = new List <MetalKitEssentialsMesh> (); for (int i = 0; i < mtkMeshes.Length; i++) { var mtkMesh = mtkMeshes [i]; var mdlMesh = mdlMeshes [(nuint)i]; var mesh = new MetalKitEssentialsMesh(mtkMesh, mdlMesh, device); meshes.Add(mesh); } for (int i = 0; i < maxInflightBuffers; i++) { frameUniformBuffers [i] = device.CreateBuffer((nuint)Marshal.SizeOf <FrameUniforms> (), MTLResourceOptions.CpuCacheModeDefault); } }