using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace BansheeEngine { /// /// Pixel formats usable by images, textures and render surfaces. /// public enum PixelFormat // Note: Must match C++ enum PixelFormat { /// /// 8-bit pixel format, all bits red. /// R8 = 1, /// /// 2 byte pixel format, 1 byte red, 1 byte green. /// R8G8 = 2, /// /// 24-bit pixel format, 8 bits for red, green and blue. /// R8G8B8 = 3, /// /// 32-bit pixel format, 8 bits for red, green, blue and alpha. /// R8G8B8A8 = 8, /// /// DXT1/BC1 format containing opaque RGB or 1-bit alpha RGB. 4 bits per pixel. /// BC1 = 13, /// /// DXT3/BC2 format containing RGB with premultiplied alpha. 4 bits per pixel. /// BC1a = 14, /// /// DXT3/BC2 format containing RGB with explicit alpha. 8 bits per pixel. /// BC2 = 15, /// /// DXT5/BC2 format containing RGB with explicit alpha. 8 bits per pixel. Better alpha gradients than BC2. /// BC3 = 16, /// /// One channel compressed format. 4 bits per pixel. /// BC4 = 17, /// /// Two channel compressed format. 8 bits per pixel. /// BC5 = 18, /// /// Format storing RGB in half (16-bit) floating point format usable for HDR. 8 bits per pixel. /// BC6H = 19, /// /// Format storing RGB with optional alpha channel. Similar to BC1/BC2/BC3 formats but with higher quality and /// higher decompress overhead. 8 bits per pixel. /// BC7 = 20, /// /// 16-bit pixel format, 16 bits (float) for red. /// Float16_R = 21, /// /// 32-bit, 2-channel s10e5 floating point pixel format, 16-bit red, 16-bit green. /// Float16_RG = 22, /// /// 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue. /// Float16_RGB = 23, /// /// 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits /// (float) for alpha. /// Float16_RGBA = 24, /// /// 32-bit pixel format, 32 bits (float) for red. /// Float32_R = 25, /// /// 64-bit, 2-channel floating point pixel format, 32-bit red, 32-bit green. /// Float32_RG = 26, /// /// 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue. /// Float32_RGB = 27, /// /// 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, /// 32 bits (float) for alpha. /// Float32_RGBA = 28, /// /// Depth stencil format, 32bit depth, 8bit stencil + 24 unused. /// D32_S8X24 = 29, /// /// Depth stencil fomrat, 24bit depth + 8bit stencil. /// D24S8 = 30, /// /// Depth format, 32bits. /// D32 = 31, /// /// Depth format, 16bits. /// D16 = 32 }; /// /// A buffer describing a volume (3D), image (2D) or line (1D) of pixels in memory. Pixels are stored as a succession /// of "depth" slices, each containing "height" rows of "width" pixels. /// public sealed class PixelData : ScriptObject { /// /// Width, height and depth of the pixels this object is capable of holding. /// public PixelVolume Extents { get { PixelVolume volume; Internal_GetExtents(mCachedPtr, out volume); return volume; } } /// /// Format of the pixels in the buffer. /// public PixelFormat Format { get { PixelFormat format; Internal_GetFormat(mCachedPtr, out format); return format; } } /// /// Returns number of bytes per a row of pixels. /// public int RawRowPitch { get { int rowPitch; Internal_GetRowPitch(mCachedPtr, out rowPitch); return rowPitch; } } /// /// Returns number of bytes per a 2D slice/plane of pixels. /// public int RawSlicePitch { get { int slicePitch; Internal_GetSlicePitch(mCachedPtr, out slicePitch); return slicePitch; } } /// /// Returns total number of bytes used by all the pixels. /// public int RawSize { get { int size; Internal_GetSize(mCachedPtr, out size); return size; } } /// /// Checks are the pixels in the buffer consecutive. If this is false then the buffer has padding and you should /// check and when accessing it directly. /// public bool RawIsConsecutive { get { bool isConsecutive; Internal_GetIsConsecutive(mCachedPtr, out isConsecutive); return isConsecutive; } } /// /// Constructor for internal use by the runtime. /// private PixelData() { } /// /// Creates a new pixel data buffer capable of storing the specified amount of pixels. /// /// Width, height and depth determining number of pixels to store. /// Format of individual pixels. public PixelData(PixelVolume volume, PixelFormat format = PixelFormat.R8G8B8A8) { Internal_CreateInstance(this, volume, format); } /// /// Creates a new 2D pixel data buffer capable of storing the specified amount of pixels. /// /// Number of pixels in each row. /// Number of pixels in each column. /// Format of individual pixels. public PixelData(int width, int height, PixelFormat format = PixelFormat.R8G8B8A8) { Internal_CreateInstance(this, new PixelVolume(0, 0, width, height), format); } /// /// Creates a new 3D pixel data buffer capable of storing the specified amount of pixels. /// /// Number of pixels in each row. /// Number of pixels in each column. /// Number of 2D slices. /// Format of individual pixels. public PixelData(int width, int height, int depth, PixelFormat format = PixelFormat.R8G8B8A8) { Internal_CreateInstance(this, new PixelVolume(0, 0, 0, width, height, depth), format); } /// /// Returns a pixel at the specified location in the buffer. /// /// X coordinate of the pixel. /// Y coordinate of the pixel. /// Z coordinate of the pixel. /// Value of the pixel, or undefined value if coordinates are out of range. public Color GetPixel(int x, int y, int z = 0) { Color pixel; Internal_GetPixel(mCachedPtr, x, y, z, out pixel); return pixel; } /// /// Sets a pixel at the specified location in the buffer. /// /// Color of the pixel to set. /// X coordinate of the pixel. /// Y coordinate of the pixel. /// Z coordinate of the pixel. public void SetPixel(Color color, int x, int y, int z = 0) { Internal_SetPixel(mCachedPtr, x, y, z, color); } /// /// Returns values of all pixels. /// /// All pixels in the buffer ordered consecutively. Pixels are stored as a succession of "depth" slices, /// each containing "height" rows of "width" pixels. public Color[] GetPixels() { Color[] pixels; Internal_GetPixels(mCachedPtr, out pixels); return pixels; } /// /// Sets all pixels in the buffer. Caller must ensure that number of pixels match the extends of the buffer. /// /// All pixels to set ordered consecutively. Pixels are stored as a succession of "depth" /// slices, each containing "height" rows of "width" pixels. public void SetPixels(Color[] pixels) { Internal_SetPixels(mCachedPtr, pixels); } /// /// Returns all pixels in the buffer as raw bytes. /// /// Raw pixel bytes. It is up to the caller to interpret the pixel format and account for potential /// row and slice pitch values. public byte[] GetRawPixels() { byte[] pixels; Internal_GetRawPixels(mCachedPtr, out pixels); return pixels; } /// /// Sets all pixels in the buffer as raw bytes. /// /// Raw pixel bytes. It is up to the caller to set the proper pixel format and account for /// potential row and slice pitch values. public void SetRawPixels(byte[] pixels) { Internal_SetRawPixels(mCachedPtr, pixels); } [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_CreateInstance(PixelData instance, PixelVolume volume, PixelFormat format); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetPixel(IntPtr thisPtr, int x, int y, int z, out Color value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_SetPixel(IntPtr thisPtr, int x, int y, int z, Color value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetPixels(IntPtr thisPtr, out Color[] value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_SetPixels(IntPtr thisPtr, Color[] value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetRawPixels(IntPtr thisPtr, out byte[] value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_SetRawPixels(IntPtr thisPtr, byte[] value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetExtents(IntPtr thisPtr, out PixelVolume value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetFormat(IntPtr thisPtr, out PixelFormat value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetRowPitch(IntPtr thisPtr, out int value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetSlicePitch(IntPtr thisPtr, out int value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetSize(IntPtr thisPtr, out int value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_GetIsConsecutive(IntPtr thisPtr, out bool value); } /// /// Represents a 3D region of pixels used for referencing pixel data. /// [StructLayout(LayoutKind.Sequential)] public struct PixelVolume // Note: Must match C++ class PixelVolume { private int left, top, right, bottom, front, back; /// /// Returns the left border of the pixel region (minimal X). /// public int Left { get { return left; } } /// /// Returns the right border of the pixel region (maximal X). /// public int Right { get { return right; } } /// /// Returns the top border of the pixel region (minimal Y). /// public int Top { get { return top; } } /// /// Returns the bottom border of the pixel region (maximal Y). /// public int Bottom { get { return bottom; } } /// /// Returns the front border of the pixel region (minimal Z). /// public int Front { get { return front; } } /// /// Returns the back border of the pixel region (maximal Z). /// public int Back { get { return back; } } /// /// Returns the number of pixels between right and left borders of the volume. /// public int Width { get { return right - left; } } /// /// Returns the number of pixels between bottom and top borders of the volume. /// public int Height { get { return bottom - top; } } /// /// Returns the number of pixels between back and front borders of the volume. /// public int Depth { get { return back - front; } } /// /// Creates a new 2D region. /// /// Left border of the region. /// Top border of the region. /// Right border of the region. Must be larger than left border. /// Bottom border of the region. Must be larger than top border. public PixelVolume(int left, int top, int right, int bottom) { this.left = left; this.right = right; this.top = top; this.bottom = bottom; this.front = 0; this.back = 1; } /// /// Creates a new 3D region. /// /// Left border of the region. /// Top border of the region. /// Front border of the region. /// Right border of the region. Must be larger than left border. /// Bottom border of the region. Must be larger than top border. /// Back border of the region. Must be larger than back border. public PixelVolume(int left, int top, int front, int right, int bottom, int back) { this.left = left; this.right = right; this.top = top; this.bottom = bottom; this.front = front; this.back = back; } }; }