/// <summary> /// Function to copy (or update in-place) a line with opaque alpha substituion (if required). /// </summary> /// <param name="src">The pointer to the source data.</param> /// <param name="srcPitch">The pitch of the source data.</param> /// <param name="dest">The pointer to the destination data.</param> /// <param name="destPitch">The pitch of the destination data.</param> /// <param name="format">Format of the destination buffer.</param> /// <param name="bitFlags">Image bit conversion control flags.</param> /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception> /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception> /// <remarks>Use this method to copy a single scanline of an image and (optionally) set an opaque constant alpha value.</remarks> protected unsafe void CopyScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags) { if (src == null) { throw new ArgumentNullException("src"); } if (dest == null) { throw new ArgumentNullException("dest"); } if (format == BufferFormat.Unknown) { throw new ArgumentException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, BufferFormat.Unknown), "format"); } int size = (src == dest) ? destPitch : (srcPitch.Min(destPitch)); if ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) { // Do a straight copy. switch (format) { case BufferFormat.R32G32B32A32: case BufferFormat.R32G32B32A32_Float: case BufferFormat.R32G32B32A32_UInt: case BufferFormat.R32G32B32A32_Int: { uint alpha = (format == BufferFormat.R32G32B32_Float) ? 0x3F800000 : ((format == BufferFormat.R32G32B32_Int) ? 0x7FFFFFFF : 0xFFFFFFFF); var srcPtr = (uint *)src; var destPtr = (uint *)dest; for (int i = 0; i < size; i += 16) { // If not in-place copy, then copy from the source. if (src != dest) { *destPtr = *srcPtr; srcPtr += 4; } *destPtr += 3; *(destPtr++) = alpha; } } return; case BufferFormat.R16G16B16A16: case BufferFormat.R16G16B16A16_Float: case BufferFormat.R16G16B16A16_UIntNormal: case BufferFormat.R16G16B16A16_UInt: case BufferFormat.R16G16B16A16_IntNormal: case BufferFormat.R16G16B16A16_Int: { ushort alpha = 0xFFFF; switch (format) { case BufferFormat.R16G16B16A16_Float: alpha = 0x3C00; break; case BufferFormat.R16G16B16A16_Int: case BufferFormat.R16G16B16A16_IntNormal: alpha = 0x7FFF; break; } var srcPtr = (ushort *)src; var destPtr = (ushort *)dest; for (int i = 0; i < size; i += 8) { // If not in-place copy, then copy from the source. if (src != dest) { *destPtr = *srcPtr; srcPtr += 4; } *destPtr += 3; *(destPtr++) = alpha; } } return; case BufferFormat.R10G10B10A2: case BufferFormat.R10G10B10A2_UIntNormal: case BufferFormat.R10G10B10A2_UInt: case BufferFormat.R10G10B10_XR_BIAS_A2_UIntNormal: { var srcPtr = (uint *)src; var destPtr = (uint *)dest; for (int i = 0; i < size; i += 4) { // If not in-place copy, then copy from the source. if (src != dest) { *destPtr = (*srcPtr) & 0x3FFFFFFF; srcPtr++; } *destPtr |= 0xC0000000; destPtr++; } } return; case BufferFormat.R8G8B8A8: case BufferFormat.R8G8B8A8_UIntNormal: case BufferFormat.R8G8B8A8_UIntNormal_sRGB: case BufferFormat.R8G8B8A8_UInt: case BufferFormat.R8G8B8A8_IntNormal: case BufferFormat.R8G8B8A8_Int: case BufferFormat.B8G8R8A8_UIntNormal: case BufferFormat.B8G8R8A8: case BufferFormat.B8G8R8A8_UIntNormal_sRGB: { uint alpha = ((format == BufferFormat.R8G8B8A8_Int) || (format == BufferFormat.R8G8B8A8_IntNormal)) ? 0x7F000000 : 0xFF000000; var srcPtr = (uint *)src; var destPtr = (uint *)dest; for (int i = 0; i < size; i += 4) { // If not in-place copy, then copy from the source. if (src != dest) { *destPtr = (*srcPtr) & 0xFFFFFF; srcPtr++; } *destPtr |= alpha; destPtr++; } } return; case BufferFormat.B5G5R5A1_UIntNormal: { var srcPtr = (ushort *)src; var destPtr = (ushort *)dest; for (int i = 0; i < size; i += 2) { // If not in-place copy, then copy from the source. if (src != dest) { *(destPtr++) = (ushort)((*srcPtr++) | 0x8000); } else { *(destPtr++) |= 0x8000; } } } return; case BufferFormat.A8_UIntNormal: DirectAccess.FillMemory(dest, 0xFF, size); return; } } // Copy if not doing an in-place update. if (dest != src) { DirectAccess.MemoryCopy(dest, src, size); } }
/// <summary> /// Function to fill with a specific /// </summary> /// <param name="destination">Desintaiont pointer to zero out.</param> /// <param name="fillValue">Value to fill the memory with.</param> /// <param name="size">Amount of memory to fill.</param> /// <remarks>Since a pointer doesn't have a size associated with it, care must be taken to not overstep the bounds of the data pointed at by the pointer.</remarks> public static void FillMemory(this IntPtr destination, byte fillValue, int size) { DirectAccess.FillMemory(destination, fillValue, size); }