using System;
using RefreshCS;
namespace MoonWorks.Graphics
{
///
/// A container for pixel data.
///
public class Texture : GraphicsResource
{
public uint Width { get; }
public uint Height { get; }
public uint Depth { get; }
public TextureFormat Format { get; }
public bool IsCube { get; }
public uint LevelCount { get; }
public SampleCount SampleCount { get; }
public TextureUsageFlags UsageFlags { get; }
protected override Action QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture;
///
/// Loads a PNG from a file path.
/// NOTE: You can queue as many of these as you want on to a command buffer but it MUST be submitted!
///
///
///
///
///
public static Texture LoadPNG(GraphicsDevice device, CommandBuffer commandBuffer, string filePath)
{
var pixels = Refresh.Refresh_Image_Load(
filePath,
out var width,
out var height,
out var channels
);
var byteCount = (uint) (width * height * channels);
TextureCreateInfo textureCreateInfo;
textureCreateInfo.Width = (uint) width;
textureCreateInfo.Height = (uint) height;
textureCreateInfo.Depth = 1;
textureCreateInfo.Format = TextureFormat.R8G8B8A8;
textureCreateInfo.IsCube = false;
textureCreateInfo.LevelCount = 1;
textureCreateInfo.SampleCount = SampleCount.One;
textureCreateInfo.UsageFlags = TextureUsageFlags.Sampler;
var texture = new Texture(device, textureCreateInfo);
commandBuffer.SetTextureData(texture, pixels, byteCount);
Refresh.Refresh_Image_Free(pixels);
return texture;
}
public unsafe static void SavePNG(string path, int width, int height, byte[] pixels)
{
fixed (byte* ptr = &pixels[0])
{
Refresh.Refresh_Image_SavePNG(path, width, height, (IntPtr) ptr);
}
}
///
/// Creates a 2D texture.
///
/// An initialized GraphicsDevice.
/// The width of the texture.
/// The height of the texture.
/// The format of the texture.
/// Specifies how the texture will be used.
/// Specifies the multisample count.
/// Specifies the number of mip levels.
public static Texture CreateTexture2D(
GraphicsDevice device,
uint width,
uint height,
TextureFormat format,
TextureUsageFlags usageFlags,
SampleCount sampleCount = SampleCount.One,
uint levelCount = 1
)
{
var textureCreateInfo = new TextureCreateInfo
{
Width = width,
Height = height,
Depth = 1,
IsCube = false,
SampleCount = sampleCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, textureCreateInfo);
}
///
/// Creates a 3D texture.
///
/// An initialized GraphicsDevice.
/// The width of the texture.
/// The height of the texture.
/// The depth of the texture.
/// The format of the texture.
/// Specifies how the texture will be used.
/// Specifies the multisample count.
/// Specifies the number of mip levels.
public static Texture CreateTexture3D(
GraphicsDevice device,
uint width,
uint height,
uint depth,
TextureFormat format,
TextureUsageFlags usageFlags,
SampleCount sampleCount = SampleCount.One,
uint levelCount = 1
)
{
var textureCreateInfo = new TextureCreateInfo
{
Width = width,
Height = height,
Depth = depth,
IsCube = false,
SampleCount = sampleCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, textureCreateInfo);
}
///
/// Creates a cube texture.
///
/// An initialized GraphicsDevice.
/// The length of one side of the cube.
/// The format of the texture.
/// Specifies how the texture will be used.
/// Specifies the multisample count.
/// Specifies the number of mip levels.
public static Texture CreateTextureCube(
GraphicsDevice device,
uint size,
TextureFormat format,
TextureUsageFlags usageFlags,
SampleCount sampleCount = SampleCount.One,
uint levelCount = 1
)
{
var textureCreateInfo = new TextureCreateInfo
{
Width = size,
Height = size,
Depth = 1,
IsCube = true,
SampleCount = sampleCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, textureCreateInfo);
}
///
/// Creates a new texture using a TextureCreateInfo struct.
///
/// An initialized GraphicsDevice.
/// The parameters to use when creating the texture.
public Texture(
GraphicsDevice device,
in TextureCreateInfo textureCreateInfo
) : base(device)
{
Handle = Refresh.Refresh_CreateTexture(
device.Handle,
textureCreateInfo.ToRefreshTextureCreateInfo()
);
Format = textureCreateInfo.Format;
Width = textureCreateInfo.Width;
Height = textureCreateInfo.Height;
Depth = textureCreateInfo.Depth;
IsCube = textureCreateInfo.IsCube;
SampleCount = textureCreateInfo.SampleCount;
LevelCount = textureCreateInfo.LevelCount;
SampleCount = textureCreateInfo.SampleCount;
UsageFlags = textureCreateInfo.UsageFlags;
}
}
}