public MetalKitEssentialsSubmesh(MTKSubmesh mtkSubmesh, MDLSubmesh mdlSubmesh, IMTLDevice device) { materialUniforms = device.CreateBuffer((nuint)Marshal.SizeOf <MaterialUniforms> (), MTLResourceOptions.CpuCacheModeDefault); var uniforms = Marshal.PtrToStructure <MaterialUniforms> (materialUniforms.Contents); submesh = mtkSubmesh; for (nuint i = 0; i < mdlSubmesh.Material.Count; i++) { MDLMaterialProperty property = ObjectAtIndexedSubscript(mdlSubmesh.Material, i); if (property == null) { continue; } if (property.Name == "baseColorMap") { if (property.Type != MDLMaterialPropertyType.String) { continue; } var textureURL = new NSUrl(string.Format("file://{0}", property.StringValue)); var textureLoader = new MTKTextureLoader(device); NSError error; diffuseTexture = textureLoader.FromUrl(textureURL, null, out error); if (diffuseTexture == null) { throw new Exception(string.Format("Diffuse texture load: {0}", error.LocalizedDescription)); } } else if (property.Name == "BlinnSpecularColor") { if (property.Type == MDLMaterialPropertyType.Float4) { uniforms.specularColor = property.Float4Value; } else if (property.Type == MDLMaterialPropertyType.Float3) { uniforms.specularColor = new Vector4(property.Float3Value); } } else if (property.Name == "emission") { if (property.Type == MDLMaterialPropertyType.Float4) { uniforms.emissiveColor = property.Float4Value; } else if (property.Type == MDLMaterialPropertyType.Float3) { uniforms.emissiveColor = new Vector4(property.Float3Value); } } } Marshal.StructureToPtr(uniforms, materialUniforms.Contents, true); }
public static void Update(this IMTLResourceStateCommandEncoder This, IMTLTexture texture, MTLSparseTextureMappingMode mode, MTLRegion[] regions, nuint[] mipLevels, nuint[] slices) { if (texture == null) { throw new ArgumentNullException(nameof(texture)); } if (regions == null) { throw new ArgumentNullException(nameof(regions)); } if (mipLevels == null) { throw new ArgumentNullException(nameof(mipLevels)); } if (slices == null) { throw new ArgumentNullException(nameof(slices)); } var regionsHandle = GCHandle.Alloc(regions, GCHandleType.Pinned); var mipLevelsHandle = GCHandle.Alloc(mipLevels, GCHandleType.Pinned); var slicesHandle = GCHandle.Alloc(slices, GCHandleType.Pinned); try { var regionsPtr = regionsHandle.AddrOfPinnedObject(); var mipLevelsPtr = mipLevelsHandle.AddrOfPinnedObject(); var slicesPtr = slicesHandle.AddrOfPinnedObject(); This.Update(texture, mode, regionsPtr, mipLevelsPtr, slicesPtr, (nuint)regions.Length); } finally { regionsHandle.Free(); mipLevelsHandle.Free(); slicesHandle.Free(); } }
void SetupRenderPassDescriptorForTexture(IMTLTexture texture) { if (renderPassDescriptor == null) { renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor(); } renderPassDescriptor.ColorAttachments [0].Texture = texture; renderPassDescriptor.ColorAttachments [0].LoadAction = MTLLoadAction.Clear; renderPassDescriptor.ColorAttachments [0].ClearColor = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f); renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store; if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height)) { // If we need a depth texture and don't have one, or if the depth texture we have is the wrong size // Then allocate one of the proper size MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false); if (ObjCRuntime.Runtime.Arch == ObjCRuntime.Arch.SIMULATOR) { desc.StorageMode = MTLStorageMode.Private; } depthTex = device.CreateTexture(desc); depthTex.Label = "Depth"; renderPassDescriptor.DepthAttachment.Texture = depthTex; renderPassDescriptor.DepthAttachment.LoadAction = MTLLoadAction.Clear; renderPassDescriptor.DepthAttachment.ClearDepth = 1.0f; renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare; } }
private void PlatformConstruct( GraphicsDevice graphicsDevice, ResourceUploadBatch uploadBatch, PixelFormat pixelFormat, int width, int height, TextureMipMapData[] mipMapData) { var textureDescriptor = MTLTextureDescriptor.CreateTexture2DDescriptor( pixelFormat.ToMTLPixelFormat(), (nuint)width, (nuint)height, true); // Ignored, because we'll set the mip level count explicitly below. textureDescriptor.Usage = MTLTextureUsage.ShaderRead; textureDescriptor.MipmapLevelCount = (nuint)mipMapData.Length; _originalPixelFormat = pixelFormat; DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(textureDescriptor)); for (var i = 0; i < mipMapData.Length; i++) { SetData( i, mipMapData[i].Data, mipMapData[i].BytesPerRow); } }
public Texture(string name, string extension) { path = NSBundle.MainBundle.PathForResource(name, extension); Width = 0; Height = 0; MetalTexture = null; flip = true; }
void LoadAssets () { var textureLoader = new MTKTextureLoader (metalView.Device); NSUrl url = NSBundle.MainBundle.GetUrlForResource ("AnimalImage", "png"); NSError error; sourceTexture = textureLoader.FromUrl (url, null, out error); }
public Texture (string name, string extension) { path = NSBundle.MainBundle.PathForResource (name, extension); Width = 0; Height = 0; MetalTexture = null; flip = true; }
bool NeedUpdate(IMTLTexture texture, IMTLTexture textureToCompare) { bool doUpdate = false; doUpdate = (textureToCompare.Width != texture.Width) || (textureToCompare.Height != texture.Height) || (textureToCompare.SampleCount != SampleCount); return(doUpdate); }
void LoadAssets() { var textureLoader = new MTKTextureLoader(metalView.Device); NSUrl url = NSBundle.MainBundle.GetUrlForResource("AnimalImage", "png"); NSError error; sourceTexture = textureLoader.TextureWithContentsOfUrl(url, null, out error); }
private void PlatformConstruct( GraphicsDevice graphicsDevice, PixelFormat pixelFormat, int arraySize, int width, int height, TextureBindFlags bindFlags, int mipMapCount, TextureMipMapData[] mipMapData) { var descriptor = new MTLTextureDescriptor { ArrayLength = (nuint) arraySize, CpuCacheMode = MTLCpuCacheMode.DefaultCache, Depth = 1, Height = (nuint) height, MipmapLevelCount = (nuint) mipMapCount, PixelFormat = pixelFormat.ToMTLPixelFormat(), ResourceOptions = MTLResourceOptions.StorageModeManaged, SampleCount = 1, StorageMode = MTLStorageMode.Managed, TextureType = arraySize > 1 ? MTLTextureType.k2DArray : MTLTextureType.k2D, Width = (nuint) width, Usage = bindFlags.ToMTLTextureUsage() }; DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(descriptor)); if (mipMapData != null) { for (var i = 0; i < mipMapData.Length; i++) { var mipWidth = CalculateMipMapSize(i, width); var mipHeight = CalculateMipMapSize(i, height); var region = MTLRegion.Create2D(0, 0, mipWidth, mipHeight); var dataHandle = GCHandle.Alloc(mipMapData[i].Data, GCHandleType.Pinned); try { DeviceTexture.ReplaceRegion( region, (nuint) i, dataHandle.AddrOfPinnedObject(), (nuint) mipMapData[i].BytesPerRow); } finally { dataHandle.Free(); } } } }
private void PlatformConstruct(GraphicsDevice graphicsDevice, int width, int height, float clearValue) { DeviceTexture = AddDisposable(graphicsDevice.Device.CreateTexture(new MTLTextureDescriptor { ArrayLength = 1, CpuCacheMode = MTLCpuCacheMode.DefaultCache, Depth = 1, Height = (nuint)height, MipmapLevelCount = 1, PixelFormat = MTLPixelFormat.Depth32Float, ResourceOptions = MTLResourceOptions.StorageModePrivate, SampleCount = 1, StorageMode = MTLStorageMode.Private, TextureType = MTLTextureType.k2D, Usage = MTLTextureUsage.RenderTarget, Width = (nuint)width })); }
bool PrepareCompute() { NSError error; // Create a compute kernel function IMTLFunction function = shaderLibrary.CreateFunction("grayscale"); if (function == null) { Console.WriteLine("ERROR: Failed creating a new function!"); return(false); } // Create a compute kernel kernel = device.CreateComputePipelineState(function, out error); if (kernel == null) { Console.WriteLine("ERROR: Failed creating a compute kernel: %@", error.Description); return(false); } MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false); if (texDesc == null) { Console.WriteLine("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!"); return(false); } outTexture = device.CreateTexture(texDesc); if (outTexture == null) { Console.WriteLine("ERROR: Failed creating an output 2d texture!"); return(false); } // Set the compute kernel's workgroup size and count workgroupSize = new MTLSize(1, 1, 1); localCount = new MTLSize((nint)size.Width, (nint)size.Height, 1); return(true); }
public AmtImageView(MgImageViewCreateInfo pCreateInfo) { if (pCreateInfo == null) { throw new ArgumentNullException(nameof(pCreateInfo)); } if (pCreateInfo.Image == null) { throw new ArgumentNullException(nameof(pCreateInfo.Image)); } var bImage = (AmtImage)pCreateInfo.Image; mImageView = bImage.OriginalTexture.CreateTextureView( AmtFormatExtensions.GetPixelFormat(pCreateInfo.Format), TranslateTextureType(pCreateInfo.ViewType), GenerateLevelRange(pCreateInfo.SubresourceRange), GenerateSliceRange(pCreateInfo.SubresourceRange)); }
void Draw(IMTLTexture texture) { GCHandle pinnedTransform = GCHandle.Alloc(vertexFactory.Vertices.ToArray(), GCHandleType.Pinned); IntPtr ptr = pinnedTransform.AddrOfPinnedObject(); pinnedTransform.Free(); var rstate = renderPipelineState; var commandBuffer = commandQueue.CommandBuffer(); var currentRenderPassDescriptor = mtkView.CurrentRenderPassDescriptor; var encoder = commandBuffer.CreateRenderCommandEncoder(currentRenderPassDescriptor); encoder.PushDebugGroup("RenderFrame"); encoder.SetRenderPipelineState(rstate); encoder.SetVertexBytes(ptr, (nuint)vertexFactory.Size(), index: 0); encoder.SetFragmentTexture(texture, index: 0); encoder.DrawPrimitives(MTLPrimitiveType.TriangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1); encoder.PopDebugGroup(); encoder.EndEncoding(); commandBuffer.Commit(); }
public MetalKitEssentialsSubmesh(MTKSubmesh mtkSubmesh, MDLSubmesh mdlSubmesh, IMTLDevice device) { materialUniforms = device.CreateBuffer ((nuint)Marshal.SizeOf <MaterialUniforms> (), MTLResourceOptions.CpuCacheModeDefault); var uniforms = Marshal.PtrToStructure <MaterialUniforms> (materialUniforms.Contents); submesh = mtkSubmesh; for (nuint i = 0; i < mdlSubmesh.Material.Count; i++) { MDLMaterialProperty property = ObjectAtIndexedSubscript (mdlSubmesh.Material, i); if (property == null) continue; if (property.Name == "baseColorMap") { if (property.Type != MDLMaterialPropertyType.String) continue; var textureURL = new NSUrl (string.Format ("file://{0}", property.StringValue)); var textureLoader = new MTKTextureLoader (device); NSError error; diffuseTexture = textureLoader.FromUrl (textureURL, null, out error); if (diffuseTexture == null) throw new Exception (string.Format ("Diffuse texture load: {0}", error.LocalizedDescription)); } else if (property.Name == "BlinnSpecularColor") { if (property.Type == MDLMaterialPropertyType.Float4) uniforms.specularColor = property.Float4Value; else if (property.Type == MDLMaterialPropertyType.Float3) uniforms.specularColor = new Vector4 (property.Float3Value); } else if (property.Name == "emission") { if(property.Type == MDLMaterialPropertyType.Float4) uniforms.emissiveColor = property.Float4Value; else if (property.Type == MDLMaterialPropertyType.Float3) uniforms.emissiveColor = new Vector4 (property.Float3Value); } } Marshal.StructureToPtr (uniforms, materialUniforms.Contents, true); }
public override void Resize() { #if __IOS__ UIView view = (UIView)ObjCRuntime.Runtime.GetNSObject(_window); nfloat scale = UIScreen.MainScreen.Scale; nfloat width = view.Bounds.Size.Width * scale; nfloat height = view.Bounds.Size.Height * scale; _layer.Frame = view.Layer.Frame; #else NSView view = (NSView)ObjCRuntime.Runtime.GetNSObject(_window); nfloat width = view.Bounds.Size.Width; nfloat height = view.Bounds.Size.Height; #endif _layer.DrawableSize = new CGSize(width, height); MTLTextureDescriptor descriptor = new MTLTextureDescriptor(); if (_samples > 1) { descriptor.TextureType = MTLTextureType.k2DMultisample; descriptor.PixelFormat = _layer.PixelFormat; descriptor.Width = (uint)width; descriptor.Height = (uint)height; descriptor.SampleCount = _samples; IMTLTexture colorAA = _dev.CreateTexture(descriptor); _descriptor.ColorAttachments[0].Texture = colorAA; } descriptor.TextureType = _samples > 1 ? MTLTextureType.k2DMultisample : MTLTextureType.k2D; descriptor.PixelFormat = MTLPixelFormat.Stencil8; descriptor.Width = (uint)width; descriptor.Height = (uint)height; descriptor.SampleCount = _samples; IMTLTexture stencil = _dev.CreateTexture(descriptor); _descriptor.StencilAttachment.Texture = stencil; }
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); 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; 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 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); }
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); }
void SetupRenderPassDescriptorForTexture(IMTLTexture texture) { if (renderPassDescriptor == null) renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor (); renderPassDescriptor.ColorAttachments [0].Texture = texture; renderPassDescriptor.ColorAttachments [0].LoadAction = MTLLoadAction.Clear; renderPassDescriptor.ColorAttachments [0].ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f); renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store; if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height)) { // If we need a depth texture and don't have one, or if the depth texture we have is the wrong size // Then allocate one of the proper size MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false); depthTex = device.CreateTexture (desc); depthTex.Label = "Depth"; renderPassDescriptor.DepthAttachment.Texture = depthTex; renderPassDescriptor.DepthAttachment.LoadAction = MTLLoadAction.Clear; renderPassDescriptor.DepthAttachment.ClearDepth = 1.0f; renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare; } }
public AmtImageView(IMTLTexture texture) { mImageView = texture; }
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 bool Finalize(IMTLDevice device) { if (MetalTexture != null) { return(true); } UIImage image = UIImage.FromFile(path); if (image == null) { return(false); } using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB()) { if (colorSpace == null) { return(false); } Width = image.CGImage.Width; Height = image.CGImage.Height; nuint width = (nuint)Width; nuint height = (nuint)Height; nuint rowBytes = width * 4; var context = new CGBitmapContext(IntPtr.Zero, (int)width, (int)height, 8, (int)rowBytes, colorSpace, CGImageAlphaInfo.PremultipliedLast); if (context == null) { return(false); } var bounds = new CGRect(0f, 0f, width, height); context.ClearRect(bounds); // Vertical Reflect if (flip) { context.TranslateCTM(width, height); context.ScaleCTM(-1f, -1f); } context.DrawImage(bounds, image.CGImage); MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, width, height, false); if (texDesc == null) { return(false); } MetalTexture = device.CreateTexture(texDesc); if (MetalTexture == null) { context.Dispose(); return(false); } IntPtr pixels = context.Data; if (pixels != IntPtr.Zero) { var region = new MTLRegion(); region.Origin.X = 0; region.Origin.Y = 0; region.Size.Width = (nint)width; region.Size.Height = (nint)height; MetalTexture.ReplaceRegion(region, 0, pixels, rowBytes); } context.Dispose(); } return(true); }
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; }
internal RenderTarget(GraphicsDevice graphicsDevice, IMTLTexture deviceTexture) : base(graphicsDevice) { DeviceTexture = deviceTexture; }
private void PlatformConstruct(GraphicsDevice graphicsDevice, Texture texture) { DeviceTexture = texture.DeviceTexture; }
public void SetTexture(IMTLTexture texture) { mTexture = texture; }
void SetupRenderPassDescriptorForTexture(IMTLTexture texture) { if (renderPassDescriptor == null) { renderPassDescriptor = new MTLRenderPassDescriptor(); } MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0]; colorAttachment.Texture = texture; colorAttachment.LoadAction = MTLLoadAction.Clear; colorAttachment.ClearColor = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f); if (SampleCount > 1) { if (msaaTex == null || NeedUpdate(texture, msaaTex)) { var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false); desc.TextureType = MTLTextureType.k2DMultisample; desc.SampleCount = SampleCount; msaaTex = device.CreateTexture(desc); } colorAttachment.Texture = msaaTex; colorAttachment.ResolveTexture = texture; // set store action to resolve in this case colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve; } else { colorAttachment.StoreAction = MTLStoreAction.Store; } if (DepthPixelFormat != MTLPixelFormat.Invalid) { if (depthTex == null || NeedUpdate(texture, depthTex)) { var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(DepthPixelFormat, texture.Width, texture.Height, false); desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D; desc.SampleCount = SampleCount; depthTex = device.CreateTexture(desc); MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment; depthAttachment.Texture = depthTex; depthAttachment.LoadAction = MTLLoadAction.Clear; depthAttachment.StoreAction = MTLStoreAction.DontCare; depthAttachment.ClearDepth = 1.0; } } if (StencilPixelFormat != MTLPixelFormat.Invalid) { if (stencilTex == null || NeedUpdate(texture, stencilTex)) { var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(StencilPixelFormat, texture.Width, texture.Height, false); desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D; desc.SampleCount = SampleCount; depthTex = device.CreateTexture(desc); MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment; stencilAttachment.Texture = depthTex; stencilAttachment.LoadAction = MTLLoadAction.Clear; stencilAttachment.StoreAction = MTLStoreAction.DontCare; stencilAttachment.ClearStencil = 1; } } }
bool PrepareCompute () { NSError error; // Create a compute kernel function IMTLFunction function = shaderLibrary.CreateFunction ("grayscale"); if(function == null) { Console.WriteLine ("ERROR: Failed creating a new function!"); return false; } // Create a compute kernel kernel = device.CreateComputePipelineState (function, out error); if(kernel == null) { Console.WriteLine ("ERROR: Failed creating a compute kernel: %@", error.Description); return false; } MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.RGBA8Unorm, (nuint)size.Width, (nuint)size.Height, false); if(texDesc == null) { Console.WriteLine ("ERROR: Failed creating a texture 2d descriptor with RGBA unnormalized pixel format!"); return false; } outTexture = device.CreateTexture (texDesc); if(outTexture == null) { Console.WriteLine ("ERROR: Failed creating an output 2d texture!"); return false; } // Set the compute kernel's workgroup size and count workgroupSize = new MTLSize (1, 1, 1); localCount = new MTLSize ((nint)size.Width, (nint)size.Height, 1); return true; }
public AmtImage(IMTLTexture texture) { mOriginalTexture = texture; }
void SetupRenderPassDescriptorForTexture (IMTLTexture texture) { if (renderPassDescriptor == null) renderPassDescriptor = new MTLRenderPassDescriptor (); MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0]; colorAttachment.Texture = texture; colorAttachment.LoadAction = MTLLoadAction.Clear; colorAttachment.ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f); if (SampleCount > 1) { if (msaaTex == null || NeedUpdate (texture, msaaTex)) { var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false); desc.TextureType = MTLTextureType.k2DMultisample; desc.SampleCount = SampleCount; msaaTex = device.CreateTexture (desc); } colorAttachment.Texture = msaaTex; colorAttachment.ResolveTexture = texture; // set store action to resolve in this case colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve; } else { colorAttachment.StoreAction = MTLStoreAction.Store; } if (DepthPixelFormat != MTLPixelFormat.Invalid && (depthTex == null || NeedUpdate (texture, depthTex))) { var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (DepthPixelFormat, texture.Width, texture.Height, false); desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D; desc.SampleCount = SampleCount; depthTex = device.CreateTexture (desc); MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment; depthAttachment.Texture = depthTex; depthAttachment.LoadAction = MTLLoadAction.Clear; depthAttachment.StoreAction = MTLStoreAction.DontCare; depthAttachment.ClearDepth = 1.0; } if (StencilPixelFormat != MTLPixelFormat.Invalid && (stencilTex == null || NeedUpdate (texture, stencilTex))) { var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (StencilPixelFormat, texture.Width, texture.Height, false); desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D; desc.SampleCount = SampleCount; stencilTex = device.CreateTexture (desc); MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment; stencilAttachment.Texture = stencilTex; stencilAttachment.LoadAction = MTLLoadAction.Clear; stencilAttachment.StoreAction = MTLStoreAction.DontCare; stencilAttachment.ClearStencil = 0; } }
public bool Finalize (IMTLDevice device) { if (MetalTexture != null) return true; UIImage image = UIImage.FromFile (path); if (image == null) return false; using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB ()) { if (colorSpace == null) return false; Width = image.CGImage.Width; Height = image.CGImage.Height; nuint width = (nuint)Width; nuint height = (nuint)Height; nuint rowBytes = width * 4; var context = new CGBitmapContext (IntPtr.Zero, (int)width, (int)height, 8, (int)rowBytes, colorSpace, CGImageAlphaInfo.PremultipliedLast); if (context == null) return false; var bounds = new CGRect (0f, 0f, width, height); context.ClearRect (bounds); // Vertical Reflect if (flip) { context.TranslateCTM (width, height); context.ScaleCTM (-1f, -1f); } context.DrawImage (bounds, image.CGImage); MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.RGBA8Unorm, width, height, false); if (texDesc == null) return false; MetalTexture = device.CreateTexture (texDesc); if (MetalTexture == null) { context.Dispose (); return false; } IntPtr pixels = context.Data; if (pixels != IntPtr.Zero) { var region = new MTLRegion (); region.Origin.X = 0; region.Origin.Y = 0; region.Size.Width = (nint)width; region.Size.Height = (nint)height; MetalTexture.ReplaceRegion (region, 0, pixels, rowBytes); } context.Dispose (); } return true; }
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); }
internal RenderTarget(GraphicsDevice graphicsDevice, IMTLTexture texture) : base(graphicsDevice) { Texture = texture; }
bool NeedUpdate (IMTLTexture texture, IMTLTexture textureToCompare) { bool doUpdate = false; doUpdate = (textureToCompare.Width != texture.Width) || (textureToCompare.Height != texture.Height) || (textureToCompare.SampleCount != SampleCount); return doUpdate; }