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(); } } } }
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 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; }