예제 #1
0
        /// <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);
            }
        }
예제 #2
0
 /// <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);
 }