Example #1
0
        /// <summary>
        /// Reads data from the index buffer into the array.
        /// </summary>
        /// <typeparam name="T">The type of data in the index buffer - int or short.</typeparam>
        /// <param name="data">Array to write the data to</param>
        /// <param name="startIndex">Starting index in the array at which to start writing to</param>
        /// <param name="elementCount">Number of indices to read</param>
        /// <param name="offsetInBytes">Offset from the start of the index buffer at which to start copying from</param>
        /// <remarks>See implementors for exceptions that may occur.</remarks>
        public override void GetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes)
        {
            if (_buffer == null || _buffer.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            //Throws null or out of range exception
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);

            int numBytes = MemoryHelper.SizeOf <T>();

            int ibSize   = base.IndexCount * ((base.IndexFormat == IndexFormat.SixteenBits) ? 2 : 4);
            int dataSize = elementCount * numBytes;

            if (offsetInBytes < 0 || offsetInBytes > ibSize)
            {
                throw new ArgumentOutOfRangeException("offsetInBytes", "Byte offset is out of range.");
            }

            if ((offsetInBytes + dataSize) > ibSize)
            {
                throw new ArgumentOutOfRangeException("data", "Byte offset and the number of elements to read will cause a buffer overflow.");
            }

            CreateStaging();

            try {
                //If we're reading from the entire VB just copy the whole thing
                if (offsetInBytes == 0 && startIndex == 0 && dataSize == ibSize)
                {
                    _graphicsDevice.CopyResource(_buffer, _staging);
                }
                else
                {
                    D3D.ResourceRegion region = new D3D.ResourceRegion();
                    region.Left  = offsetInBytes;
                    region.Right = offsetInBytes + dataSize;
                    region.Front = region.Top = 0;
                    region.Back  = region.Bottom = 1;
                    _graphicsDevice.CopySubresourceRegion(_buffer, 0, region, _staging, 0, offsetInBytes, 0, 0);
                }

                using (SDX.DataStream ds = _staging.Map(D3D.MapMode.Read, D3D.MapFlags.None)) {
                    ds.Position = offsetInBytes;
                    ds.ReadRange <T>(data, startIndex, elementCount);
                    _staging.Unmap();
                }
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Buffer.", e);
            }
        }
Example #2
0
        /// <summary>
        /// Gets the data from the texture.
        /// </summary>
        /// <typeparam name="T">Type of data in the array.</typeparam>
        /// <param name="data">Array of data.</param>
        /// <param name="mipLevel">Mip map level to access.</param>
        /// <param name="subimage">Rectangle representing a sub-image of the 2D texture to read from, if null the whole image is read from.</param>
        /// <param name="startIndex">Starting index in the array to start writing to.</param>
        /// <param name="elementCount">Number of elements to read.</param>
        /// <exception cref="System.ArgumentException">Thrown if the format byte size of the type to read and the texture do not match, the subimage
        /// dimensions are invalid, or if the total size to read and the total size in the texture do not match</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error reading from the texture.</exception>
        public override void GetData <T>(T[] data, int mipLevel, Rectangle?subimage, int startIndex, int elementCount)
        {
            if (_texture2D == null || _texture2D.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (mipLevel < 0 || mipLevel >= _mipCount)
            {
                throw new ArgumentOutOfRangeException("mipLevel", String.Format("Mip level is out of range. Must be between 0 and {0}.", _mipCount.ToString()));
            }

            //Throws null or out of range exception
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);

            int formatSize = D3D10Helper.FormatSize(base.Format);
            int elemSize   = MemoryHelper.SizeOf <T>();

            CheckSizes(formatSize, elemSize);

            //Calc subresource dimensions
            int width  = (int)MathHelper.Max(1, base.Width >> mipLevel);
            int height = (int)MathHelper.Max(1, base.Height >> mipLevel);

            //Get the dimensions, if its null we copy the whole texture
            Rectangle rect;

            if (subimage.HasValue)
            {
                rect = subimage.Value;
                CheckRectangle(rect, ref width, ref height);
            }
            else
            {
                rect = new Rectangle(0, 0, width, height);
            }

            CheckTotalSize(base.Format, ref formatSize, ref width, ref height, elemSize, elementCount);

            //Create staging
            CreateStaging();

            try {
                int row = rect.Y;
                int col = rect.X;

                //Do resource copy
                if (base.Format == SurfaceFormat.DXT1 || base.Format == SurfaceFormat.DXT3 || base.Format == SurfaceFormat.DXT5)
                {
                    _graphicsDevice.CopyResource(_texture2D, _staging);
                }
                else
                {
                    D3D.ResourceRegion region = new D3D.ResourceRegion();
                    region.Left   = col;
                    region.Right  = col + width;
                    region.Top    = row;
                    region.Bottom = row + height;
                    region.Front  = 0;
                    region.Back   = 1;
                    _graphicsDevice.CopySubresourceRegion(_texture2D, mipLevel, region, _staging, mipLevel, col, row, 0);
                }

                SDX.DataRectangle dataRect = _staging.Map(mipLevel, D3D.MapMode.Read, D3D.MapFlags.None);
                SDX.DataStream    ds       = dataRect.Data;
                int pitch = dataRect.Pitch;

                int index = startIndex;
                int count = elementCount;

                //Compute the actual number of elements based on the format size and the element size we're copying the bytes into
                int actWidth = (int)MathHelper.Floor(width * (formatSize / elemSize));
                //Go row by row
                for (int i = row; i < height; i++)
                {
                    //Set the position
                    ds.Position = (i * pitch) + (col * formatSize);
                    //Break if we've run out of elements or on the very last row that isn't complete
                    if (count <= 0)
                    {
                        break;
                    }
                    else if (count < actWidth)
                    {
                        ds.ReadRange <T>(data, index, count);
                        break;
                    }
                    //Otherwise, copy the whole row and increment/decrement the index and count
                    ds.ReadRange <T>(data, index, actWidth);
                    index += actWidth;
                    count -= actWidth;
                }
                _staging.Unmap(mipLevel);
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Texture2D.", e);
            }
        }
Example #3
0
        /// <summary>
        /// Gets the data from the texture.
        /// </summary>
        /// <typeparam name="T">Type of data in the array</typeparam>
        /// <param name="data">The array of data</param>
        /// <param name="mipLevel">Mip map level to read from</param>
        /// <param name="left">Right-most width position in the texture at which to acess. (0 or greater)</param>
        /// <param name="right">Right-most width position in the texture at which to acess. (width or less)</param>
        /// <param name="top">Top-most height position in the texture at which to acess. (0 or greater)</param>
        /// <param name="bottom">Bottom-most height position in the texture at which to acess. (height or less)</param>
        /// <param name="front">Front-most depth position in the texture at which to acess. (0 or greater)</param>
        /// <param name="back">Back-most depth position in the texture at which to acess. (depth or less)</param>
        /// <param name="startIndex">Starting index in the array to start reading from.</param>
        /// <param name="elementCount">Number of elements to write.</param>
        /// <exception cref="System.ArgumentException">Thrown if the format byte size of the type to read and the texture do not match, the subimage
        /// dimensions are invalid, or if the total size to read and the total size in the texture do not match</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error reading from the texture.</exception>
        public override void GetData <T>(T[] data, int mipLevel, int left, int right, int top, int bottom, int front, int back, int startIndex, int elementCount)
        {
            if (_texture3D == null || _texture3D.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (mipLevel < 0 || mipLevel >= _mipCount)
            {
                throw new ArgumentOutOfRangeException("mipLevel", String.Format("Mip level is out of range. Must be between 0 and {0}.", _mipCount.ToString()));
            }

            //Throws null or out of range exception
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);

            int formatSize = D3D10Helper.FormatSize(base.Format);
            int elemSize   = MemoryHelper.SizeOf <T>();

            CheckSizes(formatSize, elemSize);

            //Calc subresource dimensions
            int width  = (int)MathHelper.Max(1, base.Width >> mipLevel);
            int height = (int)MathHelper.Max(1, base.Height >> mipLevel);
            int depth  = (int)MathHelper.Max(1, base.Depth >> mipLevel);

            //Ensure box dimensions
            CheckBox(left, right, top, bottom, front, back, ref width, ref height, ref depth);

            CheckTotalSize(base.Format, ref formatSize, ref width, ref height, ref depth, elemSize, elementCount);

            //Create staging
            CreateStaging();

            try {
                int row   = left;
                int col   = top;
                int slice = front;

                //Do resource copy
                if (base.Format == SurfaceFormat.DXT1 || base.Format == SurfaceFormat.DXT3 || base.Format == SurfaceFormat.DXT5)
                {
                    _graphicsDevice.CopyResource(_texture3D, _staging);
                }
                else
                {
                    D3D.ResourceRegion region = new D3D.ResourceRegion();
                    region.Left   = col;
                    region.Right  = right;
                    region.Top    = row;
                    region.Bottom = bottom;
                    region.Front  = slice;
                    region.Back   = back;
                    _graphicsDevice.CopySubresourceRegion(_texture3D, mipLevel, region, _staging, mipLevel, col, row, slice);
                }

                SDX.DataBox    dataBox    = _staging.Map(mipLevel, D3D.MapMode.Read, D3D.MapFlags.None);
                SDX.DataStream ds         = dataBox.Data;
                int            rowPitch   = dataBox.RowPitch;
                int            slicePitch = dataBox.SlicePitch;
                int            index      = startIndex;
                int            count      = elementCount;

                //Compute the actual number of elements based on the format size and the element size we're copying the bytes into
                int actWidth = (int)MathHelper.Floor(width * (formatSize / elemSize));
                //Go slice by slice
                for (int k = slice; k < back; k++)
                {
                    //Go row by row
                    for (int i = row; i < bottom; i++)
                    {
                        //Set the position
                        ds.Position = (k * slicePitch) + (i * rowPitch) + (col * formatSize);
                        //Break if we've run out of elements or on the very last row that isn't complete
                        if (count <= 0)
                        {
                            break;
                        }
                        else if (count < actWidth)
                        {
                            ds.ReadRange <T>(data, index, count);
                            break;
                        }
                        //Otherwise, copy the whole row and increment/decrement the index and count
                        ds.ReadRange <T>(data, index, actWidth);
                        index += actWidth;
                        count -= actWidth;
                    }
                }
                _staging.Unmap(mipLevel);
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Texture3D.", e);
            }
        }
        /// <summary>
        /// Gets the back buffer data.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="subimage">The rectangle representing the sub-image. Null value means to grab the whole back buffer.</param>
        /// <param name="data">The data.</param>
        /// <param name="startIndex">The starting index in the array.</param>
        /// <param name="elementCount">The number of eleemnts to read</param>
        public override void GetBackBufferData <T>(Rectangle?subimage, T[] data, int startIndex, int elementCount)
        {
            if (_backBuffer.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            //Throws null or out of range exception
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);

            //Calc subresource dimensions
            int width  = _presentParams.BackBufferWidth;
            int height = _presentParams.BackBufferHeight;

            //Get the dimensions, if its null we copy the whole texture
            Rectangle rect;

            if (subimage.HasValue)
            {
                rect = subimage.Value;
                CheckRectangle(rect, width, height);
            }
            else
            {
                rect = new Rectangle(0, 0, width, height);
            }

            if (elementCount > rect.Width * rect.Height)
            {
                throw new ArgumentOutOfRangeException("elementCount", "Number of elements to read is larger than contained in the specified subimage.");
            }

            //Create staging
            CreateStaging();

            try {
                int row        = rect.Y;
                int col        = rect.X;
                int rectWidth  = rect.Width;
                int rectHeight = rect.Height;

                //Do resource copy
                if (row == 0 && col == 0 && rectWidth == width && rectHeight == height)
                {
                    _graphicsDevice.CopyResource(_backBuffer, _staging);
                }
                else
                {
                    D3D.ResourceRegion region = new D3D.ResourceRegion();
                    region.Left   = col;
                    region.Right  = col + rectWidth;
                    region.Top    = row;
                    region.Bottom = row + rectHeight;
                    region.Front  = 0;
                    region.Back   = 1;
                    _graphicsDevice.CopySubresourceRegion(_backBuffer, 0, region, _staging, 0, col, row, 0);
                }

                SDX.DataRectangle dataRect = _staging.Map(0, D3D.MapMode.Read, D3D.MapFlags.None);
                SDX.DataStream    ds       = dataRect.Data;
                int elemSize   = MemoryHelper.SizeOf <T>();
                int formatSize = D3D10Helper.FormatSize(_presentParams.BackBufferFormat);
                int pitch      = dataRect.Pitch;

                int index = startIndex;
                int count = elementCount;

                //Compute the actual number of elements based on the format size and the element size we're copying the bytes into
                int actWidth = (int)MathHelper.Floor(rectWidth * (formatSize / elemSize));
                //Go row by row
                for (int i = row; i < height; i++)
                {
                    //Set the position
                    ds.Position = (i * pitch) + (col * formatSize);
                    //Break if we've run out of elements or on the very last row that isn't complete
                    if (count <= 0)
                    {
                        break;
                    }
                    else if (count < actWidth)
                    {
                        ds.ReadRange <T>(data, index, count);
                        break;
                    }
                    //Otherwise, copy the whole row and increment/decrement the index and count
                    ds.ReadRange <T>(data, index, actWidth);
                    index += actWidth;
                    count -= actWidth;
                }
                _staging.Unmap(0);
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Texture2D.", e);
            }
        }
        /// <summary>
        /// Gets the data from the texture.
        /// </summary>
        /// <typeparam name="T">Type of data in the array.</typeparam>
        /// <param name="data">Array of data</param>
        /// <param name="mipLevel">Mip map level to access</param>
        /// <param name="left">The left-most position in the 1D texture at which to access.</param>
        /// <param name="right">The right-most position in the 1D texture at which to acess.</param>
        /// <param name="startIndex">Starting index in the array to start writing to.</param>
        /// <param name="elementCount">Number of elements to read.</param>
        public override void GetData <T>(T[] data, int mipLevel, int left, int right, int startIndex, int elementCount)
        {
            if (_texture1D.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (mipLevel < 0 || mipLevel >= _mipCount)
            {
                throw new ArgumentOutOfRangeException("mipLevel", String.Format("Mip level is out of range. Must be between 0 and {0}.", _mipCount.ToString()));
            }

            //Throws null or out of range exception
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);
            SurfaceFormat format = base.Format;


            int formatSize = D3D10Helper.FormatSize(format);
            int elemSize   = MemoryHelper.SizeOf <T>();

            CheckSizes(formatSize, elemSize);

            //Calc subresource dimensions
            int width = (int)MathHelper.Max(1, base.Width >> mipLevel);

            //Check the line
            CheckLine(ref width, left, right);

            //Check the total size - fixes up the proper sizes if we're using a compression format
            CheckTotalSize(format, ref formatSize, ref width, elemSize, elementCount);

            //Create staging
            CreateStaging();

            try {
                //Copy from the texture to staging
                if (format == SurfaceFormat.DXT1 || format == SurfaceFormat.DXT3 || format == SurfaceFormat.DXT5)
                {
                    _graphicsDevice.CopyResource(_texture1D, _staging);
                }
                else
                {
                    D3D.ResourceRegion region = new D3D.ResourceRegion();
                    region.Left   = left;
                    region.Right  = right;
                    region.Top    = 0;
                    region.Bottom = 1;
                    region.Front  = 0;
                    region.Back   = 1;
                    _graphicsDevice.CopySubresourceRegion(_texture1D, mipLevel, region, _staging, mipLevel, left, 0, 0);
                }
                SDX.DataStream ds = _staging.Map(mipLevel, D3D.MapMode.Read, D3D.MapFlags.None);

                //Compute the actual number of elements based on the format size and the element size we're copying the bytes into
                int actWidth = (int)MathHelper.Floor(width * (formatSize / elemSize));

                //Read data
                ds.Position = left * formatSize;
                ds.ReadRange <T>(data, startIndex, actWidth);

                _staging.Unmap(mipLevel);
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Texture2D.", e);
            }
        }
        /// <summary>
        /// Gets the data from the vertex buffer and copies it into specified array.
        /// </summary>
        /// <typeparam name="T">The type of data in the vertex buffer.</typeparam>
        /// <param name="data">Array to copy contents to from the vertex buffer into</param>
        /// <param name="startIndex">Index of the element in the array at each to start writing to</param>
        /// <param name="elementCount">Number of elements to copy</param>
        /// <param name="offsetInBytes">Offset in bytes from the beginning of the vertex buffer to the data.</param>
        /// <param name="vertexStride">Size of an element in bytes</param>
        /// <exception cref="System.ObjectDisposedException">Thrown if Dispose() has been called.</exception>
        /// <exception cref="System.InvalidOperationException">Thrown if the write options are incompatible with the resource usage of the buffer.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the data's vertex stride is too small, the offset in bytes is out of range,
        /// or the byte offset and number of elements to read will cause overflow.</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error reading from the buffer.</exception>
        public override void GetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes, int vertexStride)
        {
            if (_buffer == null || _buffer.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            //Check if array bounds are out of range
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);

            VertexDeclaration vertexDecl = base.VertexDeclaration;
            int vertexCount = base.VertexCount;

            int vbSize     = vertexCount * vertexDecl.VertexStride;
            int elemSize   = MemoryHelper.SizeOf <T>();
            int dataSize   = elementCount * elemSize;
            int vertexStep = vertexStride;

            if (vertexStride != 0)
            {
                vertexStep -= elemSize;
                if (vertexStep < 0)
                {
                    throw new ArgumentException("vertexStride", "Vertex stride is too small for requested data size.");
                }
                //If we get this far, we need to make sure the actual bytes we're going to look at matches up,
                //since we can grab specific parts of a vertex and not the whole thing
                if (elementCount > 1)
                {
                    dataSize = ((elementCount - 1) * vertexStep) + dataSize;
                }
            }

            //Prevent overflow out of range errors
            if ((offsetInBytes < 0) || (offsetInBytes > vbSize))
            {
                throw new ArgumentOutOfRangeException("offsetInBytes", "Byte offset is out of range.");
            }

            if ((offsetInBytes + dataSize) > vbSize)
            {
                throw new ArgumentOutOfRangeException("data", "Byte offset and elements to read will cause in buffer overflow.");
            }

            //Create scratch buffer, if it hasn't been created already
            CreateStaging();

            try {
                //If we're reading from the entire VB just copy the whole thing
                if (offsetInBytes == 0 && startIndex == 0 && vertexCount == data.Length)
                {
                    _graphicsDevice.CopyResource(_buffer, _staging);
                }
                else
                {
                    D3D.ResourceRegion region = new D3D.ResourceRegion();
                    region.Left  = offsetInBytes;
                    region.Right = offsetInBytes + dataSize;
                    region.Front = region.Top = 0;
                    region.Back  = region.Bottom = 1;
                    _graphicsDevice.CopySubresourceRegion(_buffer, 0, region, _staging, 0, offsetInBytes, 0, 0);
                }

                using (SDX.DataStream ds = _staging.Map(D3D.MapMode.Read, D3D.MapFlags.None)) {
                    //If the step is zero, that means we're dealing with the entire vertex and not a subset of it
                    if (vertexStep == 0)
                    {
                        ds.Position = offsetInBytes;
                        ds.ReadRange <T>(data, startIndex, elementCount);
                    }
                    else
                    {
                        ds.Position = offsetInBytes;
                        int count = elementCount - 1;
                        int index = startIndex;
                        data[index++] = ds.Read <T>();
                        while (count > 0)
                        {
                            ds.Position += vertexStep;
                            data[index]  = ds.Read <T>();
                            count--;
                            index++;
                        }
                    }
                    _staging.Unmap();
                }
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Buffer.", e);
            }
        }