public override void UpdateSubResource(GorgonImageBuffer buffer,
                                        Rectangle destRect,
                                        int destArrayIndex      = 0,
                                        int destMipLevel        = 0,
                                        GorgonGraphics deferred = null)
 {
     throw new NotSupportedException(Resources.GORGFX_DEPTH_OPERATION_NOT_SUPPORTED);
 }
Exemple #2
0
 /// <summary>
 /// Function to clip a bitmap.
 /// </summary>
 /// <param name="bitmap">Bitmap to clip.</param>
 /// <param name="buffer">Buffer containing clipped data.</param>
 private void ClipBitmap(WIC.BitmapSource bitmap, GorgonImageBuffer buffer)
 {
     using (var clipper = new WIC.BitmapClipper(Factory))
     {
         clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width,
                                                     buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height));
         clipper.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
     }
 }
Exemple #3
0
 /// <summary>
 /// Function to copy data from the CPU to the texture on the GPU.
 /// </summary>
 /// <param name="buffer">A buffer containing the image data to copy.</param>
 /// <param name="destBox">A 3D box that will specify the region that will receive the data.</param>
 /// <param name="destArrayIndex">[Optional] The array index that will receive the data.</param>
 /// <param name="destMipLevel">[Optional] The mip map level that will receive the data.</param>
 /// <param name="deferred">[Optional] A deferred graphics context used to copy the data.</param>
 /// <exception cref="System.InvalidOperationException">Thrown when the texture is dynamic or immutable.
 /// <para>-or-</para>
 /// <para>Thrown when the texture is multisampled.</para>
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="destArrayIndex"/> or the <paramref name="destMipLevel"/> is less than 0 or greater than/equal to the
 /// number of array indices or mip levels in the texture.</exception>
 /// <remarks>
 /// Use this to copy data into a texture with a usage of staging or default.  If the <paramref name="destBox"/> values are larger than the dimensions of the texture, then the data will be clipped.
 /// <para>Passing NULL (Nothing in VB.Net) to the <paramref name="destArrayIndex"/> and/or the <paramref name="destMipLevel"/> parameters will use the first array index and/or mip map level.</para>
 /// <para>This method will not work with depth/stencil textures or with textures that have multisampling applied.</para>
 /// <para>If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net) then the immediate context will be used.  If this method is called from multiple threads, then a deferred context should be passed for each thread that is
 /// accessing the sub resource.</para>
 /// </remarks>
 public void UpdateSubResource(GorgonImageBuffer buffer,
                               GorgonBox destBox,
                               int destArrayIndex      = 0,
                               int destMipLevel        = 0,
                               GorgonGraphics deferred = null)
 {
     OnUpdateSubResource(buffer,
                         destBox,
                         destArrayIndex,
                         destMipLevel,
                         deferred);
 }
Exemple #4
0
        /// <summary>
        /// Function to create a WIC bitmap from a Gorgon image buffer.
        /// </summary>
        /// <param name="buffer">Image buffer containing the image data to convert.</param>
        /// <returns>The WIC bitmap.</returns>
        public WIC.Bitmap CreateWICBitmapFromImageBuffer(GorgonImageBuffer buffer)
        {
            var pointer = new DX.DataRectangle(buffer.Data.BasePointer, buffer.PitchInformation.RowPitch);

            Guid bitmapFormat = GetGUID(buffer.Format);

            if (bitmapFormat == Guid.Empty)
            {
                throw new GorgonException(GorgonResult.FormatNotSupported,
                                          string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, buffer.Format));
            }

            return(new WIC.Bitmap(Factory,
                                  buffer.Width,
                                  buffer.Height,
                                  bitmapFormat,
                                  pointer,
                                  pointer.Pitch * buffer.Height));
        }
Exemple #5
0
 /// <summary>
 /// Function to copy data from the CPU to the texture on the GPU.
 /// </summary>
 /// <param name="buffer">A buffer containing the image data to copy.</param>
 /// <param name="destRect">A rectangle that will specify the region that will receive the data.</param>
 /// <param name="destArrayIndex">[Optional] The array index that will receive the data.</param>
 /// <param name="destMipLevel">[Optional] The mip map level that will receive the data.</param>
 /// <param name="deferred">[Optional] A deferred graphics context used to copy the data.</param>
 /// <exception cref="System.InvalidOperationException">Thrown when the texture is dynamic or immutable.
 /// <para>-or-</para>
 /// <para>Thrown when the texture is multisampled.</para>
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="destArrayIndex"/> or the <paramref name="destMipLevel"/> is less than 0 or greater than/equal to the
 /// number of array indices or mip levels in the texture.</exception>
 /// <remarks>
 /// Use this to copy data into a texture with a usage of staging or default.  If the <paramref name="destRect"/> values are larger than the dimensions of the texture, then the data will be clipped.
 /// <para>Passing NULL (Nothing in VB.Net) to the <paramref name="destArrayIndex"/> and/or the <paramref name="destMipLevel"/> parameters will use the first array index and/or mip map level.</para>
 /// <para>This method will not work with depth/stencil textures or with textures that have multisampling applied.</para>
 /// <para>If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net) then the immediate context will be used.  If this method is called from multiple threads, then a deferred context should be passed for each thread that is
 /// accessing the sub resource.</para>
 /// </remarks>
 public virtual void UpdateSubResource(GorgonImageBuffer buffer,
                                       Rectangle destRect,
                                       int destArrayIndex      = 0,
                                       int destMipLevel        = 0,
                                       GorgonGraphics deferred = null)
 {
     OnUpdateSubResource(buffer,
                         new GorgonBox
     {
         Front  = 0,
         Depth  = 1,
         Left   = destRect.Left,
         Width  = destRect.Width,
         Top    = destRect.Top,
         Height = destRect.Height
     },
                         destArrayIndex,
                         destMipLevel,
                         deferred);
 }
Exemple #6
0
 /// <summary>
 /// Function to copy data from the CPU to the texture on the GPU.
 /// </summary>
 /// <param name="buffer">A buffer containing the image data to copy.</param>
 /// <param name="destRange">A start and end range value that will specify the region that will receive the data.</param>
 /// <param name="destArrayIndex">[Optional] The array index that will receive the data.</param>
 /// <param name="destMipLevel">[Optional] The mip map level that will receive the data.</param>
 /// <param name="deferred">[Optional] A deferred graphics context used to copy the data.</param>
 /// <exception cref="System.InvalidOperationException">Thrown when the texture is dynamic or immutable.
 /// <para>-or-</para>
 /// <para>Thrown when the texture is multisampled.</para>
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="destArrayIndex"/> or the <paramref name="destMipLevel"/> is less than 0 or greater than/equal to the
 /// number of array indices or mip levels in the texture.</exception>
 /// <remarks>
 /// Use this to copy data into a texture with a usage of staging or default.  If the <paramref name="destRange"/> values are larger than the dimensions of the texture, then the data will be clipped.
 /// <para>Passing NULL (Nothing in VB.Net) to the <paramref name="destArrayIndex"/> and/or the <paramref name="destMipLevel"/> parameters will use the first array index and/or mip map level.</para>
 /// <para>This method will not work with depth/stencil textures or with textures that have multisampling applied.</para>
 /// <para>If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net) then the immediate context will be used.  If this method is called from multiple threads, then a deferred context should be passed for each thread that is
 /// accessing the sub resource.</para>
 /// </remarks>
 public virtual void UpdateSubResource(GorgonImageBuffer buffer,
                                       GorgonRange destRange,
                                       int destArrayIndex      = 0,
                                       int destMipLevel        = 0,
                                       GorgonGraphics deferred = null)
 {
     OnUpdateSubResource(buffer,
                         new GorgonBox
     {
         Front  = 0,
         Depth  = 1,
         Left   = destRange.Minimum,
         Width  = destRange.Maximum,
         Top    = 0,
         Height = 1
     },
                         destArrayIndex,
                         destMipLevel,
                         deferred);
 }
Exemple #7
0
        /// <summary>
        /// Function to copy the image buffer data from this buffer into another.
        /// </summary>
        /// <param name="buffer">The buffer to copy into.</param>
        /// <param name="sourceRegion">[Optional] The region in the source to copy.</param>
        /// <param name="destX">[Optional] Horizontal offset in the destination buffer.</param>
        /// <param name="destY">[Optional] Vertical offset in the destination buffer.</param>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="buffer" /> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="buffer" /> is not the same format as this buffer.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the source region does not fit within the bounds of this buffer.</exception>
        /// <remarks>
        /// This method will copy the contents of this buffer into another buffer and will provide clipping to handle cases where the buffer or <paramref name="sourceRegion" /> is mismatched with the
        /// destination size.
        /// <para>Users may define an area on this buffer to copy by specifying the <paramref name="sourceRegion" /> parameter.  If NULL (Nothing in VB.Net) is passed to this parameter, then the
        /// entire buffer will be copied to the destination.</para><para>An offset into the destination buffer may also be specified to relocate the data copied from this buffer into the destination.  Clipping will be applied if the offset pushes the
        /// source data outside of the boundaries of the destination buffer.</para><para>The destination buffer must be the same format as the source buffer.  If it is not, then an exception will be thrown.</para>
        /// <para>The <paramref name="buffer"/> parameter must not be the same as the this buffer.  An exception will be thrown if an attempt to copy this buffer into itself is made.</para>
        /// <para>If the source region does not fit within the bounds of this buffer, then an exception will be thrown.</para>
        /// </remarks>
        public unsafe void CopyTo(GorgonImageBuffer buffer, Rectangle?sourceRegion = null, int destX = 0, int destY = 0)
        {
            var       sourceBufferDims = new Rectangle(0, 0, Width, Height);
            Rectangle srcRegion        = sourceRegion != null ? sourceRegion.Value : sourceBufferDims;

            if ((buffer == null) ||
                (buffer.Data == null) ||
                (buffer.Data.Length == 0))
            {
                throw new ArgumentNullException("buffer");
            }

            if ((buffer == this) ||
                (buffer.Data.UnsafePointer == Data.UnsafePointer))
            {
                throw new ArgumentException(Resources.GORGFX_IMAGE_BUFFER_CANT_BE_SAME, "buffer");
            }

            if (buffer.Format != Format)
            {
                throw new ArgumentException(Resources.GORGFX_IMAGE_MUST_BE_SAME_FORMAT, "buffer");
            }

            if (!sourceBufferDims.Contains(srcRegion))
            {
                throw new ArgumentOutOfRangeException("sourceRegion");
            }

            // If we try to place this image outside of the target buffer, then do nothing.
            if ((destX >= buffer.Width) ||
                (destY >= buffer.Height))
            {
                return;
            }

            // Adjust in case we're trying to move off the target.
            if (destX < 0)
            {
                srcRegion.X     -= destX;
                srcRegion.Width += destX;
                destX            = 0;
            }

            if (destY < 0)
            {
                srcRegion.Y      -= destY;
                srcRegion.Height += destY;
                destY             = 0;
            }

            // Ensure that the regions actually fit within their respective buffers.
            srcRegion = Rectangle.FromLTRB(srcRegion.X.Max(0), srcRegion.Y.Max(0), srcRegion.Right.Min(Width), srcRegion.Bottom.Min(Height));
            Rectangle dstRegion = Rectangle.FromLTRB(destX, destY, (destX + buffer.Width).Min(buffer.Width), (destY + buffer.Height).Min(buffer.Height));

            // If the source/dest region is empty, then we have nothing to copy.
            if ((srcRegion.IsEmpty) ||
                (dstRegion.IsEmpty) ||
                (dstRegion.Right < 0) ||
                (dstRegion.Bottom < 0))
            {
                return;
            }

            // If the buffers are identical in dimensions and have no offset, then just do a straight copy.
            if (srcRegion == dstRegion)
            {
                DirectAccess.MemoryCopy(buffer.Data.UnsafePointer, Data.UnsafePointer, (int)Data.Length);
                return;
            }

            // Find out how many bytes each pixel occupies.
            int dataSize = PitchInformation.RowPitch / Width;

            int srcLineSize = dataSize * srcRegion.Width;               // Number of source bytes/scanline.
            var srcData     = ((byte *)Data.UnsafePointer) + (srcRegion.Y * PitchInformation.RowPitch) + (srcRegion.X * dataSize);

            int dstLineSize = dataSize * dstRegion.Width;               // Number of dest bytes/scanline.
            var dstData     = ((byte *)buffer.Data.UnsafePointer) + (dstRegion.Y * buffer.PitchInformation.RowPitch) + (dstRegion.X * dataSize);

            // Get the smallest line size.
            int minLineSize = dstLineSize.Min(srcLineSize);
            int minHeight   = dstRegion.Height.Min(srcRegion.Height);

            // Finally, copy our data.
            for (int i = 0; i < minHeight; ++i)
            {
                DirectAccess.MemoryCopy(dstData, srcData, minLineSize);

                srcData += PitchInformation.RowPitch;
                dstData += buffer.PitchInformation.RowPitch;
            }
        }
Exemple #8
0
        /// <summary>
        /// Function to create a WIC bitmap from a System.Drawing.Image object.
        /// </summary>
        /// <param name="bitmap">WIC bitmap to copy to our image data.</param>
        /// <param name="filter">Filter used to scale the image.</param>
        /// <param name="ditherFlags">Flags used to dither the image.</param>
        /// <param name="buffer">Buffer for holding the image data.</param>
        /// <param name="clip">TRUE to clip the data, FALSE to scale it.</param>
        public void AddWICBitmapToImageData(WIC.Bitmap bitmap, ImageFilter filter, ImageDithering ditherFlags, GorgonImageBuffer buffer, bool clip)
        {
            Guid conversionFormat = GetGUID(buffer.Format);
            bool needsResize      = (buffer.Width != bitmap.Size.Width) || (buffer.Height != bitmap.Size.Height);

            if (conversionFormat == Guid.Empty)
            {
                throw new GorgonException(GorgonResult.FormatNotSupported,
                                          string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, buffer.Format));
            }

            // Turn off filtering if we're not resizing.
            if (!needsResize)
            {
                filter = ImageFilter.Point;
            }

            // If the pixel format of the bitmap is not the same as our
            // conversion format, then we need to convert the image.
            if (bitmap.PixelFormat != conversionFormat)
            {
                ConvertFormat(bitmap.PixelFormat, conversionFormat, (WIC.BitmapDitherType)ditherFlags, (WIC.BitmapInterpolationMode)filter, bitmap, null, 0, buffer, needsResize, clip);
            }
            else
            {
                // Just dump without converting because our formats are equal.
                if ((!needsResize) || (!ResizeBitmap(bitmap, (WIC.BitmapInterpolationMode)filter, buffer, clip)))
                {
                    bitmap.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Function to clip or scale the bitmap up or down to the size of the buffer.
        /// </summary>
        /// <param name="bitmap">Bitmap to scale.</param>
        /// <param name="filter">Filtering to apply to the scaled bitmap.</param>
        /// <param name="buffer">Buffer to receive the scaled bitmap.</param>
        /// <param name="clip">TRUE to clip, FALSE to scale.</param>
        /// <returns>TRUE if clipping/scaling was performed, FALSE if not.</returns>
        private bool ResizeBitmap(WIC.BitmapSource bitmap, WIC.BitmapInterpolationMode filter, GorgonImageBuffer buffer, bool clip)
        {
            if (!clip)
            {
                using (var scaler = new WIC.BitmapScaler(Factory))
                {
                    scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter);
                    scaler.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
                }

                return(true);
            }

            if ((buffer.Width >= bitmap.Size.Width) && (buffer.Height >= bitmap.Size.Height))
            {
                return(false);
            }

            ClipBitmap(bitmap, buffer);
            return(true);
        }
Exemple #10
0
        /// <summary>
        /// Function to convert the format of a bitmap into the format of the buffer.
        /// </summary>
        /// <param name="sourceFormat">Format to convert from.</param>
        /// <param name="destFormat">Format to convert into.</param>
        /// <param name="dithering">Dithering to apply.</param>
        /// <param name="filter">Filtering to apply to scaled bitmaps.</param>
        /// <param name="bitmap">Bitmap to convert.</param>
        /// <param name="bitmapPalette">Palette for the bitmap.</param>
        /// <param name="alphaValue">Value of pixel to consider transparent.</param>
        /// <param name="buffer">Buffer holding the converted data.</param>
        /// <param name="scale">TRUE to scale when converting, FALSE to keep at original size.</param>
        /// <param name="clip">TRUE to perform clipping, FALSE to keep at original size.</param>
        private void ConvertFormat(Guid sourceFormat, Guid destFormat, WIC.BitmapDitherType dithering,
                                   WIC.BitmapInterpolationMode filter, WIC.BitmapSource bitmap,
                                   WIC.Palette bitmapPalette, int alphaValue,
                                   GorgonImageBuffer buffer, bool scale, bool clip)
        {
            WIC.BitmapSource source       = bitmap;
            double           alphaPercent = alphaValue / 255.0;
            var paletteType = WIC.BitmapPaletteType.Custom;

            // If we have a palette, then confirm that the dithering method is valid.
            if (bitmapPalette != null)
            {
                // Do not apply dithering if we're using
                // a custom palette and request ordered dithering.
                switch (dithering)
                {
                case WIC.BitmapDitherType.Ordered4x4:
                case WIC.BitmapDitherType.Ordered8x8:
                case WIC.BitmapDitherType.Ordered16x16:
                    if (bitmapPalette.TypeInfo == WIC.BitmapPaletteType.Custom)
                    {
                        dithering = WIC.BitmapDitherType.None;
                    }
                    break;
                }
                paletteType = bitmapPalette.TypeInfo;
            }

            try
            {
                // Create a scaler if need one.
                if ((scale) && (!clip))
                {
                    var scaler = new WIC.BitmapScaler(Factory);
                    scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter);
                    source = scaler;
                }

                // Create a clipper if we want to clip and the image needs resizing.
                if ((clip) && (scale) && ((buffer.Width < bitmap.Size.Width) || (buffer.Height < bitmap.Size.Height)))
                {
                    var clipper = new WIC.BitmapClipper(Factory);
                    clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width,
                                                                buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height));
                    source = clipper;
                }

                using (var converter = new WIC.FormatConverter(Factory))
                {
                    if (!converter.CanConvert(sourceFormat, destFormat))
                    {
                        throw new GorgonException(GorgonResult.FormatNotSupported,
                                                  string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, buffer.Format));
                    }

                    converter.Initialize(source, destFormat, dithering, bitmapPalette, alphaPercent, paletteType);

                    if (!scale)
                    {
                        int rowPitch   = (GetBitsPerPixel(destFormat) * bitmap.Size.Width + 7) / 8;
                        int slicePitch = rowPitch * bitmap.Size.Height;

                        if ((rowPitch != buffer.PitchInformation.RowPitch) || (slicePitch != buffer.PitchInformation.SlicePitch))
                        {
                            throw new GorgonException(GorgonResult.CannotWrite, Resources.GORGFX_IMAGE_PITCH_TOO_SMALL);
                        }
                    }
                    converter.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
                }
            }
            finally
            {
                if (source != bitmap)
                {
                    source.Dispose();
                }
            }
        }