/// <summary> /// create host visible linear image without command from path /// </summary> public static Image Load(Device dev, string path, VkFormat format = VkFormat.Undefined, bool reserveSpaceForMipmaps = true, VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, VkImageTiling tiling = VkImageTiling.Linear, VkImageType imageType = VkImageType.Image2D, VkImageUsageFlags usage = VkImageUsageFlags.Sampled) { if (format == VkFormat.Undefined) { format = DefaultTextureFormat; } int width, height, channels; IntPtr imgPtr = Stb.Load(path, out width, out height, out channels, 4); if (imgPtr == IntPtr.Zero) { throw new Exception($"File not found: {path}."); } long size = width * height * 4; uint mipLevels = reserveSpaceForMipmaps ? (uint)Math.Floor(Math.Log(Math.Max(width, height))) + 1 : 1; Image img = new Image(dev, format, usage, memoryProps, (uint)width, (uint)height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels); img.Map(); unsafe { System.Buffer.MemoryCopy(imgPtr.ToPointer(), img.MappedData.ToPointer(), size, size); } img.Unmap(); Stb.FreeImage(imgPtr); return(img); }
/// <summary> /// create host visible linear image without command from data pointed by IntPtr pointer containing full image file (jpg, png,...) /// </summary> public static Image Load(Device dev, IntPtr bitmap, ulong bitmapByteCount, VkImageUsageFlags usage = VkImageUsageFlags.TransferSrc, VkFormat format = VkFormat.Undefined, VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, VkImageTiling tiling = VkImageTiling.Linear, bool generateMipmaps = false, VkImageType imageType = VkImageType.Image2D) { if (format == VkFormat.Undefined) { format = DefaultTextureFormat; } int width, height, channels; IntPtr imgPtr = Stb.Load(bitmap, (int)bitmapByteCount, out width, out height, out channels, 4); if (imgPtr == IntPtr.Zero) { throw new Exception($"STBI image loading error."); } uint mipLevels = generateMipmaps ? (uint)Math.Floor(Math.Log(Math.Max(width, height))) + 1 : 1; if (generateMipmaps) { usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst); } long size = width * height * 4; Image img = new Image(dev, format, usage, memoryProps, (uint)width, (uint)height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels); img.Map(); unsafe { System.Buffer.MemoryCopy(imgPtr.ToPointer(), img.MappedData.ToPointer(), size, size); } img.Unmap(); Stb.FreeImage(imgPtr); return(img); }
/// <summary> /// Load bitmap into Image with stagging and mipmap generation if necessary /// and usage. /// </summary> public static Image Load(Device dev, Queue staggingQ, CommandPool staggingCmdPool, string path, VkFormat format = VkFormat.Undefined, VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.DeviceLocal, VkImageTiling tiling = VkImageTiling.Optimal, bool generateMipmaps = true, VkImageType imageType = VkImageType.Image2D, VkImageUsageFlags usage = VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst) { if (format == VkFormat.Undefined) { format = DefaultTextureFormat; } int width, height, channels; IntPtr imgPtr = Stb.Load(path, out width, out height, out channels, 4); if (imgPtr == IntPtr.Zero) { throw new Exception($"File not found: {path}."); } uint mipLevels = generateMipmaps ? (uint)Math.Floor(Math.Log(Math.Max(width, height))) + 1 : 1; if (tiling == VkImageTiling.Optimal) { usage |= VkImageUsageFlags.TransferDst; } if (generateMipmaps) { usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst); } Image img = new Image(dev, format, usage, memoryProps, (uint)width, (uint)height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels); img.load(staggingQ, staggingCmdPool, imgPtr, generateMipmaps); Stb.FreeImage(imgPtr); return(img); }