public void Configure(GameView view) { view.DepthPixelFormat = depthPixelFormat; view.StencilPixelFormat = stencilPixelFormat; view.SampleCount = sampleCount; dynamicConstantBuffer = new IMTLBuffer[max_inflight_buffers]; // allocate one region of memory for the constant buffer for (int i = 0; i < max_inflight_buffers; i++) { dynamicConstantBuffer [i] = device.CreateBuffer(max_bytes_per_frame, MTLResourceOptions.CpuCacheModeDefault); dynamicConstantBuffer [i].Label = string.Format("ConstantBuffer{0}", i); } // load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("lighting_fragment"); if (fragmentProgram == null) { Console.WriteLine("ERROR: Couldnt load fragment function from default library"); } // load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("lighting_vertex"); if (vertexProgram == null) { Console.WriteLine("ERROR: Couldnt load vertex function from default library"); } // setup the vertex buffers vertexBuffer = device.CreateBuffer <float> (cubeVertexData, MTLResourceOptions.CpuCacheModeDefault); vertexBuffer.Label = "Vertices"; // create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { Label = "MyPipeline", SampleCount = sampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, DepthAttachmentPixelFormat = depthPixelFormat }; pipelineStateDescriptor.ColorAttachments [0].PixelFormat = MTLPixelFormat.BGRA8Unorm; NSError error; pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error); var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState(depthStateDesc); }
void LoadAssets() { // Generate meshes MDLMesh mdl = MDLMesh.CreateBox(new Vector3(2f, 2f, 2f), new Vector3i(1, 1, 1), MDLGeometryType.Triangles, false, new MTKMeshBufferAllocator(device)); NSError error; boxMesh = new MTKMesh(mdl, device, out error); // Allocate one region of memory for the uniform buffer dynamicConstantBuffer = device.CreateBuffer(MaxBytesPerFrame, (MTLResourceOptions)0); dynamicConstantBuffer.Label = "UniformBuffer"; // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("lighting_fragment"); // Load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("lighting_vertex"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = MTLVertexDescriptor.FromModelIO(boxMesh.VertexDescriptor); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { Label = "MyPipeline", SampleCount = view.SampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, VertexDescriptor = vertexDescriptor, DepthAttachmentPixelFormat = view.DepthStencilPixelFormat, StencilAttachmentPixelFormat = view.DepthStencilPixelFormat }; pipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.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); }
bool PrepareDepthStencilState() { var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Always, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState(depthStateDesc); if (depthState == null) { return(false); } return(true); }
void LoadAssets() { // Allocate one region of memory for the uniform buffer dynamicConstantBuffer = device.CreateBuffer(max_bytes_per_frame, 0); dynamicConstantBuffer.Label = "UniformBuffer"; // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("lighting_fragment"); // Load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("lighting_vertex"); // Setup the vertex buffers vertexBuffer = device.CreateBuffer <float>(cubeVertexData, (MTLResourceOptions)0); vertexBuffer.Label = "Vertices"; // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { Label = "MyPipeline", SampleCount = 1, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, DepthAttachmentPixelFormat = MTLPixelFormat.Depth32Float }; pipelineStateDescriptor.ColorAttachments[0].PixelFormat = MTLPixelFormat.BGRA8Unorm; NSError error; pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error); if (pipelineState == null) { Console.WriteLine("Failed to created pipeline state, error " + error); } var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState(depthStateDesc); }
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 view = (MTKView)View; view.Delegate = this; view.Device = device; view.SampleCount = 1; view.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; view.ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; view.PreferredFramesPerSecond = 60; view.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("quad_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("quad_fragment"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float2; vertexDescriptor.Attributes[1].BufferIndex = 0; vertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); vertexDescriptor.Layouts[0].Stride = 6 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; this.vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0); this.mipmapping = 0; this.constantBuffer = device.CreateBuffer(sizeof(float), MTLResourceOptions.CpuCacheModeDefault); SetConstantBuffer(this.mipmapping, constantBuffer); // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = view.SampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, VertexDescriptor = vertexDescriptor, DepthAttachmentPixelFormat = view.DepthStencilPixelFormat, StencilAttachmentPixelFormat = view.DepthStencilPixelFormat }; pipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.ColorPixelFormat; NSError error; 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); // Texture KTX NSUrl url = NSBundle.MainBundle.GetUrlForResource("crate", "ktx"); MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device); this.texture = mTKTextureLoader.FromUrl(url, new MTKTextureLoaderOptions(), out error); Console.WriteLine("Failed to created pipeline state, error {0}", error); MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor() { MinFilter = MTLSamplerMinMagFilter.Linear, MagFilter = MTLSamplerMinMagFilter.Linear, MipFilter = MTLSamplerMipFilter.Linear, SAddressMode = MTLSamplerAddressMode.ClampToEdge, TAddressMode = MTLSamplerAddressMode.ClampToEdge, }; this.sampler = device.CreateSamplerState(samplerDescriptor); this.clock = new System.Diagnostics.Stopwatch(); this.clock.Start(); this.time = 0; }
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 triangleVertexProgram = defaultLibrary.CreateFunction("triangle_vertex"); IMTLFunction cubeVertexProgram = defaultLibrary.CreateFunction("cube_vertex"); // Load the fragment program into the library IMTLFunction triangleFragmentProgram = defaultLibrary.CreateFunction("triangle_fragment"); IMTLFunction cubeFragmentProgram = defaultLibrary.CreateFunction("cube_fragment"); // Triangle vertex descriptor MTLVertexDescriptor triangleVertexDescriptor = new MTLVertexDescriptor(); triangleVertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; triangleVertexDescriptor.Attributes[0].BufferIndex = 0; triangleVertexDescriptor.Attributes[0].Offset = 0; triangleVertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float4; triangleVertexDescriptor.Attributes[1].BufferIndex = 0; triangleVertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); triangleVertexDescriptor.Layouts[0].Stride = 8 * sizeof(float); triangleVertexDescriptor.Layouts[0].StepRate = 1; triangleVertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; // Cube vertex descriptor MTLVertexDescriptor cubeVertexDescriptor = new MTLVertexDescriptor(); cubeVertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; cubeVertexDescriptor.Attributes[0].BufferIndex = 0; cubeVertexDescriptor.Attributes[0].Offset = 0; cubeVertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float2; cubeVertexDescriptor.Attributes[1].BufferIndex = 0; cubeVertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); cubeVertexDescriptor.Layouts[0].Stride = 6 * sizeof(float); cubeVertexDescriptor.Layouts[0].StepRate = 1; cubeVertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; // Create buffers triangleVertexBuffer = device.CreateBuffer(triangleVertexData, MTLResourceOptions.CpuCacheModeDefault); cubeVertexBuffer = device.CreateBuffer(cubeVertexData, MTLResourceOptions.CpuCacheModeDefault); this.clock = new System.Diagnostics.Stopwatch(); clock.Start(); this.view = CreateLookAt(new Vector3(0, 0, 5), 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.cubeParameters.WorldViewProjection = Matrix4.Identity; cubeConstantBuffer = device.CreateBuffer((uint)Marshal.SizeOf(this.cubeParameters), MTLResourceOptions.CpuCacheModeDefault); // Create Pipeline Descriptor var trianglePipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = mtkView.SampleCount, VertexFunction = triangleVertexProgram, FragmentFunction = triangleFragmentProgram, VertexDescriptor = triangleVertexDescriptor, DepthAttachmentPixelFormat = mtkView.DepthStencilPixelFormat, StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat, }; var cubePipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = mtkView.SampleCount, VertexFunction = cubeVertexProgram, FragmentFunction = cubeFragmentProgram, VertexDescriptor = cubeVertexDescriptor, DepthAttachmentPixelFormat = mtkView.DepthStencilPixelFormat, StencilAttachmentPixelFormat = mtkView.DepthStencilPixelFormat, }; MTLRenderPipelineColorAttachmentDescriptor triangleRenderBufferAttachment = trianglePipelineStateDescriptor.ColorAttachments[0]; triangleRenderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat; MTLRenderPipelineColorAttachmentDescriptor cubeRenderBufferAttachment = cubePipelineStateDescriptor.ColorAttachments[0]; cubeRenderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat; NSError error; trianglePipelineState = device.CreateRenderPipelineState(trianglePipelineStateDescriptor, out error); if (trianglePipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error); } cubePipelineState = device.CreateRenderPipelineState(cubePipelineStateDescriptor, out error); if (cubePipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error); } var depthStencilDescriptor = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthStencilState = device.CreateDepthStencilState(depthStencilDescriptor); // Texture NSImage image = NSImage.ImageNamed("crate.png"); MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device); this.cubeTexture = mTKTextureLoader.FromCGImage(image.CGImage, new MTKTextureLoaderOptions(), out error); MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor() { MinFilter = MTLSamplerMinMagFilter.Linear, MagFilter = MTLSamplerMinMagFilter.Linear, SAddressMode = MTLSamplerAddressMode.Repeat, TAddressMode = MTLSamplerAddressMode.Repeat, }; this.sampler = device.CreateSamplerState(samplerDescriptor); // Create FrameBuffer texture IMTLTexture drawableTexture = mtkView.CurrentDrawable.Texture; MTLTextureDescriptor textureDescriptor = new MTLTextureDescriptor() { Width = drawableTexture.Width, Height = drawableTexture.Height, PixelFormat = drawableTexture.PixelFormat, TextureType = drawableTexture.TextureType, MipmapLevelCount = drawableTexture.MipmapLevelCount, ArrayLength = drawableTexture.ArrayLength, SampleCount = drawableTexture.SampleCount, Depth = drawableTexture.Depth, CpuCacheMode = drawableTexture.CpuCacheMode, Usage = MTLTextureUsage.RenderTarget, StorageMode = MTLStorageMode.Managed, }; this.colorFrameBufferTexture = device.CreateTexture(textureDescriptor); }
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 view = (MTKView)View; view.Delegate = this; view.Device = device; view.SampleCount = 1; view.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; view.ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; view.PreferredFramesPerSecond = 60; view.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("triangle_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("triangle_fragment"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[1].BufferIndex = 0; vertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); vertexDescriptor.Layouts[0].Stride = 8 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0); // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = view.SampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, VertexDescriptor = vertexDescriptor, DepthAttachmentPixelFormat = view.DepthStencilPixelFormat, StencilAttachmentPixelFormat = view.DepthStencilPixelFormat }; pipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.ColorPixelFormat; NSError error; 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); this.rectangle = new MTLScissorRect(125, 166, 250, 444); }
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("cube_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("cube_fragment"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[1].BufferIndex = 0; vertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); vertexDescriptor.Layouts[0].Stride = 8 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0); this.clock = new System.Diagnostics.Stopwatch(); clock.Start(); this.view = CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY); var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height); proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100); constantBuffer = device.CreateBuffer(64, 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, }; MTLRenderPipelineColorAttachmentDescriptor renderBufferAttachment = pipelineStateDescriptor.ColorAttachments[0]; renderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat; renderBufferAttachment.BlendingEnabled = true; renderBufferAttachment.SourceRgbBlendFactor = MTLBlendFactor.One; renderBufferAttachment.DestinationRgbBlendFactor = MTLBlendFactor.SourceAlpha; renderBufferAttachment.SourceAlphaBlendFactor = MTLBlendFactor.One; renderBufferAttachment.DestinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; renderBufferAttachment.RgbBlendOperation = MTLBlendOperation.Add; renderBufferAttachment.AlphaBlendOperation = MTLBlendOperation.Add; NSError error; 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); }
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); } }
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(); NSError error; // Setup view view = (MTKView)View; view.Delegate = this; view.Device = device; view.SampleCount = 1; view.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; view.ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; view.PreferredFramesPerSecond = 60; view.ClearColor = new MTLClearColor(0, 0, 0, 1.0f); // Functions var source = System.IO.File.ReadAllText("Triangle.metal"); MTLCompileOptions compileOptions = new MTLCompileOptions() { LanguageVersion = MTLLanguageVersion.v2_0, }; IMTLLibrary customLibrary = device.CreateLibrary(source, compileOptions, out error); IMTLFunction kernelFunction = customLibrary.CreateFunction("tessellation_kernel_triangle"); IMTLFunction vertexFunction = customLibrary.CreateFunction("tessellation_vertex_triangle"); IMTLFunction fragmentFunction = customLibrary.CreateFunction("tessellation_fragment"); // Create a vertex descriptor MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Layouts[0].Stride = 4 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerPatchControlPoint; // Create RenderPipeline var renderPipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = view.SampleCount, VertexFunction = vertexFunction, FragmentFunction = fragmentFunction, VertexDescriptor = vertexDescriptor, DepthAttachmentPixelFormat = view.DepthStencilPixelFormat, StencilAttachmentPixelFormat = view.DepthStencilPixelFormat, MaxTessellationFactor = 16, IsTessellationFactorScaleEnabled = false, TessellationFactorFormat = MTLTessellationFactorFormat.Half, TessellationControlPointIndexType = MTLTessellationControlPointIndexType.None, TessellationFactorStepFunction = MTLTessellationFactorStepFunction.Constant, TessellationOutputWindingOrder = MTLWinding.Clockwise, TessellationPartitionMode = MTLTessellationPartitionMode.FractionalEven, }; renderPipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.ColorPixelFormat; renderPipelineState = device.CreateRenderPipelineState(renderPipelineStateDescriptor, out error); if (renderPipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error); } MTLDepthStencilDescriptor depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState(depthStateDesc); computePipelineState = device.CreateComputePipelineState(kernelFunction, out error); // Buffers tessellationFactorsBuffer = device.CreateBuffer(256, MTLResourceOptions.StorageModePrivate); tessellationFactorsBuffer.Label = "Tessellation Factors"; controlPointsBuffer = device.CreateBuffer(controlPointPositionsTriangle, MTLResourceOptions.StorageModeManaged); controlPointsBuffer.Label = "Control Points Triangle"; }
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("cube_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("cube_fragment"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float3; vertexDescriptor.Attributes[1].BufferIndex = 0; vertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); vertexDescriptor.Attributes[2].Format = MTLVertexFormat.Float2; vertexDescriptor.Attributes[2].BufferIndex = 0; vertexDescriptor.Attributes[2].Offset = 7 * sizeof(float); vertexDescriptor.Layouts[0].Stride = 9 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; // Primitive Torus(1.0f, 0.3f, 28, out List <PositionNormalTexture> vertexData, out List <ushort> indexData); vertexBuffer = device.CreateBuffer(vertexData.ToArray(), MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0); indexDataArray = indexData.ToArray(); indexBuffer = device.CreateBuffer(indexDataArray, MTLResourceOptions.CpuCacheModeDefault); // Use clock this.clock = new System.Diagnostics.Stopwatch(); clock.Start(); Vector3 cameraPosition = new Vector3(0, 0, 1.5f); this.view = CreateLookAt(cameraPosition, new Vector3(0, 0, 0), Vector3.UnitY); var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height); proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100); // Constant Buffer this.param = new Parameters() { CameraPosition = cameraPosition, WorldViewProjection = Matrix4.Identity, World = Matrix4.Identity, WorldInverseTranspose = Matrix4.Identity, }; 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, }; MTLRenderPipelineColorAttachmentDescriptor renderBufferAttachment = pipelineStateDescriptor.ColorAttachments[0]; renderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat; NSError error; 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); MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device); // Texture NSUrl url = NSBundle.MainBundle.GetUrlForResource("cubemap2", "ktx"); this.texture = mTKTextureLoader.FromUrl(url, new MTKTextureLoaderOptions(), out error); Console.WriteLine("Failed to created pipeline state, error {0}", error); MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor() { MinFilter = MTLSamplerMinMagFilter.Linear, MagFilter = MTLSamplerMinMagFilter.Linear, MipFilter = MTLSamplerMipFilter.Linear, SAddressMode = MTLSamplerAddressMode.ClampToEdge, TAddressMode = MTLSamplerAddressMode.ClampToEdge, }; this.sampler = device.CreateSamplerState(samplerDescriptor); }
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); }
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("cube_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("cube_fragment"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[1].BufferIndex = 0; vertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); vertexDescriptor.Attributes[2].Format = MTLVertexFormat.Float2; vertexDescriptor.Attributes[2].BufferIndex = 0; vertexDescriptor.Attributes[2].Offset = 8 * sizeof(float); vertexDescriptor.Layouts[0].Stride = 10 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0); this.clock = new System.Diagnostics.Stopwatch(); clock.Start(); this.view = CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY); var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height); proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspect, 0.1f, 100); this.constantBuffer1 = device.CreateBuffer((uint)Marshal.SizeOf(this.param), MTLResourceOptions.CpuCacheModeDefault); this.constantBuffer2 = 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, }; MTLRenderPipelineColorAttachmentDescriptor renderBufferAttachment = pipelineStateDescriptor.ColorAttachments[0]; renderBufferAttachment.PixelFormat = mtkView.ColorPixelFormat; NSError error; pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error); if (pipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error); } var depthStencilState1Description = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true, FrontFaceStencil = new MTLStencilDescriptor() { WriteMask = 0xff, StencilCompareFunction = MTLCompareFunction.Always, DepthStencilPassOperation = MTLStencilOperation.IncrementClamp, } }; depthStencilState1 = device.CreateDepthStencilState(depthStencilState1Description); var depthStencilState2Description = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true, FrontFaceStencil = new MTLStencilDescriptor() { ReadMask = 0xff, WriteMask = 0x0, StencilCompareFunction = MTLCompareFunction.NotEqual, } }; depthStencilState2 = device.CreateDepthStencilState(depthStencilState2Description); // Texture NSImage image = NSImage.ImageNamed("crate.png"); 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.Repeat, TAddressMode = MTLSamplerAddressMode.Repeat, }; this.sampler = device.CreateSamplerState(samplerDescriptor); }