public MetalKitEssentialsMesh(MTKMesh mtkMesh, MDLMesh mdlMesh, IMTLDevice device) { mesh = mtkMesh; submeshes = new List<MetalKitEssentialsSubmesh> (); if ((nuint)mtkMesh.Submeshes.Length != mdlMesh.Submeshes.Count) throw new Exception ("Number od submeshes should be equal"); for (int i = 0; i < mtkMesh.Submeshes.Length; i++) { // Create our own app specifc submesh to hold the MetalKit submesh. var submesh = new MetalKitEssentialsSubmesh (mtkMesh.Submeshes[i], mdlMesh.Submeshes.GetItem <MDLSubmesh>((nuint)i), device); submeshes.Add (submesh); } }
public void CreateBoxWithDimensonTest() { Vector3 V3 = new Vector3(1, 2, 3); Vector3i V3i = new Vector3i(4, 5, 6); using (var obj = MDLMesh.CreateBox(V3, V3i, MDLGeometryType.Triangles, true, null)) { Assert.IsNotNull(obj, "obj"); Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.5f, 1, 1.5f), MinBounds = new Vector3(-0.5f, -1, -1.5f) }, obj.BoundingBox, "BoundingBox"); Assert.AreEqual((nuint)1, obj.Submeshes.Count, "Submeshes Count"); Assert.AreEqual(1, obj.VertexBuffers.Length, "VertexBuffers Count"); Assert.AreEqual(TestRuntime.CheckXcodeVersion(7, 3) ? (nuint)214 : (nuint)24, obj.VertexCount, "VertexCount"); Assert.AreEqual((nuint)31, obj.VertexDescriptor.Attributes.Count, "VertexDescriptor Attributes Count"); Assert.AreEqual((nuint)31, obj.VertexDescriptor.Layouts.Count, "VertexDescriptor Layouts Count"); } }
public void CreateCylindroidTest() { var V2 = new Vector2(1, 1); using (var obj = MDLMesh.CreateCylindroid(1, V2, 3, 1, MDLGeometryType.Triangles, true, null)) { Assert.IsNotNull(obj, "obj"); #if MONOMAC if (TestRuntime.CheckSystemVersion(ApplePlatform.MacOSX, 10, 12)) { Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.866025448f, 0.5f, 1f), MinBounds = new Vector3(-0.866025388f, -0.5f, -0.5f) }, obj.BoundingBox, "BoundingBox"); } else { Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(1f, 0.5f, 1f), MinBounds = new Vector3(-0.866025388f, -0.5f, -0.866025388f) }, obj.BoundingBox, "BoundingBox"); } #else if (TestRuntime.CheckXcodeVersion(8, 2)) { Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.866025448f, 0.5f, 1f), MinBounds = new Vector3(-0.866025388f, -0.5f, -0.5f) }, obj.BoundingBox, "BoundingBox"); } else if (TestRuntime.CheckXcodeVersion(8, 0)) { Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.866025448f, 1.0f, 1f), MinBounds = new Vector3(-0.866025388f, -1.0f, -0.5f) }, obj.BoundingBox, "BoundingBox"); } else { Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(1f, 0.5f, 1f), MinBounds = new Vector3(-0.866025388f, -0.5f, -0.866025388f) }, obj.BoundingBox, "BoundingBox"); } #endif Assert.That(obj.VertexBuffers.Length, Is.GreaterThanOrEqualTo(1), "VertexBuffers Count"); Assert.AreEqual((nuint)1, obj.Submeshes.Count, "Submeshes Count"); Assert.AreEqual((nuint)18, obj.VertexCount, "VertexCount"); Assert.AreEqual((nuint)31, obj.VertexDescriptor.Attributes.Count, "VertexDescriptor Attributes Count"); Assert.AreEqual((nuint)31, obj.VertexDescriptor.Layouts.Count, "VertexDescriptor Layouts Count"); } }
public void CreatePlaneTest() { var V2 = new Vector2(3, 3); var V2i = new Vector2i(3, 3); using (var obj = MDLMesh.CreatePlane(V2, V2i, MDLGeometryType.Triangles, null)) { Assert.IsNotNull(obj, "obj"); Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(1.5f, 0, 1.5f), MinBounds = new Vector3(-1.5f, 0, -1.5f) }, obj.BoundingBox, "BoundingBox"); Assert.AreEqual(1, obj.Submeshes.Count, "Submeshes Count"); Assert.That(obj.VertexBuffers.Length, Is.GreaterThanOrEqualTo(1), "VertexBuffers Count"); Assert.AreEqual(16, obj.VertexCount, "VertexCount"); Assert.AreEqual(31, obj.VertexDescriptor.Attributes.Count, "VertexDescriptor Attributes Count"); Assert.AreEqual(31, obj.VertexDescriptor.Layouts.Count, "VertexDescriptor Layouts Count"); } }
public void Setup() { if (!UIDevice.CurrentDevice.CheckSystemVersion(9, 0)) { Assert.Ignore("Requires iOS9+"); } if (Runtime.Arch == Arch.SIMULATOR && IntPtr.Size == 4) { // There's a bug in the i386 version of objc_msgSend where it doesn't preserve SIMD arguments // when resizing the cache of method selectors for a type. So here we call all selectors we can // find, so that the subsequent tests don't end up producing any cache resize (radar #21630410). object dummy; using (var obj = MDLMesh.CreateBox(Vector3.Zero, Vector3i.Zero, MDLGeometryType.Triangles, true, null)) { obj.AddAttribute("foo", MDLVertexFormat.Char); // obj.AddNormals (null, 0); // throws NSInvalidArgumentException, need to figure out valid arguments // obj.AddTangentBasis ("foo", "bar", "zap"); // throws "Need float or half UV components Need float or half UV components" // obj.AddTangentBasisWithNormals ("foo", "bar", "zap"); // throws "Need float or half UV components Reason: Need float or half UV components" dummy = obj.BoundingBox; // obj.GenerateAmbientOcclusionTexture (1, 1, new MDLObject [] { }, "name", "name"); // obj.GenerateAmbientOcclusionVertexColors (1, 1, new MDLObject[] {}, "name"); // obj.GenerateAmbientOcclusionVertexColors (1.1, 1, new MDLObject[] [] { }, "name"); // obj.GenerateLightMapTexture (Vector2i.Zero, new MDLLight[] {}, new MDLObject[] {}, "str", "str"); // obj.GenerateLightMapVertexColors (new MDLLight[] { }, new MDLObject[] { }, "v"); obj.MakeVerticesUnique(); dummy = obj.Submeshes; dummy = obj.VertexBuffers; dummy = obj.VertexCount; dummy = obj.VertexDescriptor; } using (var obj = MDLMesh.CreateCylindroid(1, Vector2.Zero, 3, 0, MDLGeometryType.Triangles, false, null)) { } using (var obj = MDLMesh.CreateEllipsoid(Vector3.Zero, 3, 2, MDLGeometryType.Triangles, false, false, null)) { } using (var obj = MDLMesh.CreateEllipticalCone(0, Vector2.Zero, 3, 1, MDLGeometryType.Triangles, false, null)) { } using (var obj = MDLMesh.CreateIcosahedron(0, false, null)) { } using (var obj = MDLMesh.CreatePlane(new Vector2(1, 1), new Vector2i(1, 1), MDLGeometryType.Triangles, null)) { } // using (var obj = MDLMesh.CreateSubdividedMesh (new MDLMesh (), 0, 0)) { // } } }
protected ArrayList FlattenChildren(MDLObject obj) { ArrayList ares = new ArrayList(0); if (obj.type == MDLType.mdl_group) { MDLMesh[] childmeshes = new MDLMesh[obj.nchildren]; for (int i = 0; i < obj.nchildren; i++) { ares.AddRange(FlattenChildren(obj.childrens[i])); } } if (obj.type == MDLType.mdl_mesh) { ares.Add(obj); } return(ares); }
public void CreateHemisphereTest() { TestRuntime.AssertXcodeVersion(8, 0); Vector3 V3 = new Vector3(1, 2, 3); Vector2i V2i = new Vector2i(4, 5); using (var obj = MDLMesh.CreateHemisphere(V3, V2i, MDLGeometryType.Triangles, true, true, null)) { Assert.IsNotNull(obj, "obj"); Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.9510565f, 2, 2.85317f), MinBounds = new Vector3(-0.9510565f, 0.6180339f, -2.85317f) }, obj.BoundingBox, "BoundingBox"); Assert.AreEqual(1, obj.Submeshes.Count, "Submeshes Count"); Assert.AreEqual(1, obj.VertexBuffers.Length, "VertexBuffers Count"); Assert.That(obj.VertexCount, Is.GreaterThanOrEqualTo(16), "VertexCount"); Assert.AreEqual(31, obj.VertexDescriptor.Attributes.Count, "VertexDescriptor Attributes Count"); Assert.AreEqual(31, obj.VertexDescriptor.Layouts.Count, "VertexDescriptor Layouts Count"); } }
public void CreateConeTest() { TestRuntime.AssertXcodeVersion(8, 0); Vector3 V3 = new Vector3(1, 2, 3); Vector2i V2i = new Vector2i(4, 5); using (var obj = MDLMesh.CreateCone(V3, V2i, MDLGeometryType.Triangles, true, true, null)) { Assert.IsNotNull(obj, "obj"); Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.5f, -0.5f, 1.5f), MinBounds = new Vector3(-0.5f, -2.5f, -1.5f) }, obj.BoundingBox, "BoundingBox"); Assert.AreEqual(1, obj.Submeshes.Count, "Submeshes Count"); Assert.AreEqual(3, obj.VertexBuffers.Length, "VertexBuffers Count"); Assert.AreEqual(36, obj.VertexCount, "VertexCount"); Assert.AreEqual(31, obj.VertexDescriptor.Attributes.Count, "VertexDescriptor Attributes Count"); Assert.AreEqual(31, obj.VertexDescriptor.Layouts.Count, "VertexDescriptor Layouts Count"); } }
public void CreateBoxTest() { Vector3 V3 = new Vector3(1, 2, 3); Vector3i V3i = new Vector3i(4, 5, 6); using (var obj = MDLMesh.CreateBox(V3, V3i, MDLGeometryType.Triangles, true, null)) { Assert.IsNotNull(obj, "obj"); Asserts.AreEqual(new MDLAxisAlignedBoundingBox { MaxBounds = new Vector3(0.5f, 1, 1.5f), MinBounds = new Vector3(-0.5f, -1, -1.5f) }, obj.BoundingBox, "BoundingBox"); Assert.AreEqual(1, obj.Submeshes.Count, "Submeshes Count"); Assert.AreEqual(1, obj.VertexBuffers.Length, "VertexBuffers Count"); // iOS 9.3 is the basis of tvOS 9.2 (hopefully they'll get in sync with iOS 10+) #if __TVOS__ bool nine3 = UIDevice.CurrentDevice.CheckSystemVersion(9, 2); #else bool nine3 = UIDevice.CurrentDevice.CheckSystemVersion(9, 3); #endif Assert.AreEqual(nine3 ? 214 : 24, obj.VertexCount, "VertexCount"); Assert.AreEqual(31, obj.VertexDescriptor.Attributes.Count, "VertexDescriptor Attributes Count"); Assert.AreEqual(31, obj.VertexDescriptor.Layouts.Count, "VertexDescriptor Layouts Count"); } }
public override void ViewDidLoad() { base.ViewDidLoad(); // Set the view to use the default device device = MTLDevice.SystemDefault; if (device == null) { Console.WriteLine("Metal is not supported on this device"); View = new NSView(View.Frame); } // Create a new command queue commandQueue = device.CreateCommandQueue(); // Load all the shader files with a metal file extension in the project defaultLibrary = device.CreateDefaultLibrary(); // Setup view mtkView = (MTKView)View; mtkView.Delegate = this; mtkView.Device = device; mtkView.SampleCount = 1; mtkView.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; mtkView.ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; mtkView.PreferredFramesPerSecond = 60; mtkView.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("mesh_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("mesh_fragment"); // Generate meshes MTKMeshBufferAllocator mtkBufferAllocator = new MTKMeshBufferAllocator(device); NSUrl url = NSBundle.MainBundle.GetUrlForResource("Fighter", "obj"); MDLAsset mdlAsset = new MDLAsset(url, new MDLVertexDescriptor(), mtkBufferAllocator); MDLObject mdlObject = mdlAsset.GetObject(0); MDLMesh mdlMesh = mdlObject as MDLMesh; NSError error; objMesh = new MTKMesh(mdlMesh, device, out error); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = MTLVertexDescriptor.FromModelIO(objMesh.VertexDescriptor); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; this.clock = new System.Diagnostics.Stopwatch(); clock.Start(); this.view = CreateLookAt(new Vector3(0, 1, 2), new Vector3(0, 0, 0), Vector3.UnitY); var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height); this.proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100); this.constantBuffer = device.CreateBuffer((uint)Marshal.SizeOf(this.param), MTLResourceOptions.CpuCacheModeDefault); // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = mtkView.SampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, VertexDescriptor = vertexDescriptor, DepthAttachmentPixelFormat = mtkView.DepthStencilPixelFormat, StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat }; pipelineStateDescriptor.ColorAttachments[0].PixelFormat = mtkView.ColorPixelFormat; pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error); if (pipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error); } var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState(depthStateDesc); NSImage image = NSImage.ImageNamed("Fighter_Diffuse.jpg"); MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device); this.texture = mTKTextureLoader.FromCGImage(image.CGImage, new MTKTextureLoaderOptions(), out error); MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor() { MinFilter = MTLSamplerMinMagFilter.Linear, MagFilter = MTLSamplerMinMagFilter.Linear, SAddressMode = MTLSamplerAddressMode.ClampToEdge, TAddressMode = MTLSamplerAddressMode.ClampToEdge, }; this.sampler = device.CreateSamplerState(samplerDescriptor); }