Пример #1
0
        static Texture2D ConvertFromBitmap(Bitmap image)
        {
            System.Drawing.Imaging.BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
                                        System.Drawing.Imaging.ImageLockMode.ReadWrite, image.PixelFormat);
            int bytes = data.Stride * image.Height;
            DataStream stream = new SlimDX.DataStream(bytes, true, true);
            stream.WriteRange(data.Scan0,bytes);
            stream.Position = 0;
            DataRectangle dRect = new SlimDX.DataRectangle(data.Stride, stream);

            SlimDX.DXGI.SampleDescription sampleDesc = new SlimDX.DXGI.SampleDescription();
            sampleDesc.Count = 1;
            sampleDesc.Quality = 0;

            Texture2DDescription texDesc = new Texture2DDescription()
            {
                ArraySize = 1,
                MipLevels = 1,
                SampleDescription = sampleDesc,
                Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm,
                CpuAccessFlags = CpuAccessFlags.Write,
                BindFlags = BindFlags.ShaderResource,
                Usage = ResourceUsage.Dynamic,
                Height = image.Height,
                Width = image.Width
            };

            image.UnlockBits(data);
            image.Dispose();

            return new Texture2D(RenderForm11.Device, texDesc, dRect);
        }
Пример #2
0
        /// <summary>
        /// Renders all of our geometry each frame.
        /// </summary>
        public void DrawTriangleList(SlimDX.Vector3 loc)
        {
            _SB.Capture();

            // Create the vertex buffer and fill with the triangle vertices.
            Vertices = new VertexBuffer(D3D.Device, 3 * D3D.Vertex.SizeBytes, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
            SlimDX.DataStream stream = Vertices.Lock(0, 0, LockFlags.None);
            stream.WriteRange(D3D.BuildVertexData());
            Vertices.Unlock();

            var worldMatrix = SlimDX.Matrix.Translation(loc);

            D3D.Device.SetTransform(TransformState.World, worldMatrix);

            D3D.Device.VertexFormat = D3D.Vertex.Format;

            // Render the vertex buffer.
            D3D.Device.SetStreamSource(0, Vertices, 0, D3D.Vertex.SizeBytes);

            //D3D.Device.DrawPrimitives(PrimitiveType.LineStrip, 0, 1);
            D3D.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

            if (Vertices != null)
            {
                Vertices.Dispose();
            }

            _SB.Apply();
        }
Пример #3
0
        /// <summary>
        /// Sets the data to 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 write to, if null the whole image is written to.</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 write and the texture do not match, the subimage
        /// dimensions are invalid, or if the total size to write and the total size in the texture do not match</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error writing to the texture.</exception>
        public override void SetData <T>(T[] data, int mipLevel, Math.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);
            SurfaceFormat format     = 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 for non-dynamic textures
            if (_usage == D3D.ResourceUsage.Default)
            {
                CreateStaging();
            }

            try {
                if (_usage == D3D.ResourceUsage.Default)
                {
                    SDX.DataRectangle dataRect = _staging.Map(mipLevel, D3D.MapMode.Write, D3D.MapFlags.None);
                    SDX.DataStream    ds       = dataRect.Data;
                    int row   = rect.Y;
                    int col   = rect.X;
                    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.WriteRange <T>(data, index, count);
                            break;
                        }
                        //Otherwise, copy the whole row and increment/decrement the index and count
                        ds.WriteRange <T>(data, index, actWidth);
                        index += actWidth;
                        count -= actWidth;
                    }
                    _staging.Unmap(mipLevel);

                    //Do resource copy
                    if (format == SurfaceFormat.DXT1 || format == SurfaceFormat.DXT3 || format == SurfaceFormat.DXT5)
                    {
                        _graphicsDevice.CopyResource(_staging, _texture2D);
                    }
                    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(_staging, mipLevel, region, _texture2D, mipLevel, col, row, 0);
                    }
                }
                else
                {
                    SDX.DataRectangle dataRect = _texture2D.Map(mipLevel, D3D.MapMode.WriteDiscard, D3D.MapFlags.None);
                    SDX.DataStream    ds       = dataRect.Data;
                    int row   = rect.Y;
                    int col   = rect.X;
                    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.WriteRange <T>(data, index, count);
                            break;
                        }
                        //Otherwise, copy the whole row and increment/decrement the index and count
                        ds.WriteRange <T>(data, index, actWidth);
                        index += actWidth;
                        count -= actWidth;
                    }
                    _texture2D.Unmap(mipLevel);
                }
            } catch (Exception e) {
                throw new TeslaException("Error writing to D3D10 Texture2D.", e);
            }
        }
Пример #4
0
        /// <summary>
        /// Sets 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 write and the texture do not match, the subimage
        /// dimensions are invalid, or if the total size to write and the total size in the texture do not match</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error writing to the texture.</exception>
        public override void SetData <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 for non-dynamic textures
            if (_usage == D3D.ResourceUsage.Default)
            {
                CreateStaging();
            }

            try {
                if (_usage == D3D.ResourceUsage.Default)
                {
                    SDX.DataBox    dataBox    = _staging.Map(mipLevel, D3D.MapMode.Write, D3D.MapFlags.None);
                    SDX.DataStream ds         = dataBox.Data;
                    int            row        = left;
                    int            col        = top;
                    int            slice      = front;
                    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.WriteRange <T>(data, index, count);
                                break;
                            }
                            //Otherwise, copy the whole row and increment/decrement the index and count
                            ds.WriteRange <T>(data, index, actWidth);
                            index += actWidth;
                            count -= actWidth;
                        }
                    }
                    _staging.Unmap(mipLevel);

                    //Do resource copy
                    if (base.Format == SurfaceFormat.DXT1 || base.Format == SurfaceFormat.DXT3 || base.Format == SurfaceFormat.DXT5)
                    {
                        _graphicsDevice.CopyResource(_staging, _texture3D);
                    }
                    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(_staging, mipLevel, region, _texture3D, mipLevel, col, row, slice);
                    }
                }
                else
                {
                    SDX.DataBox    dataBox    = _texture3D.Map(mipLevel, D3D.MapMode.Write, D3D.MapFlags.None);
                    SDX.DataStream ds         = dataBox.Data;
                    int            row        = left;
                    int            col        = top;
                    int            slice      = front;
                    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.WriteRange <T>(data, index, count);
                                break;
                            }
                            //Otherwise, copy the whole row and increment/decrement the index and count
                            ds.WriteRange <T>(data, index, actWidth);
                            index += actWidth;
                            count -= actWidth;
                        }
                    }
                    _texture3D.Unmap(mipLevel);
                }
            } catch (Exception e) {
                throw new TeslaException("Error writing to D3D10 Texture3D.", e);
            }
        }
        /// <summary>
        /// Sets the data from the array to 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 reading from.</param>
        /// <param name="elementCount">Number of elements to write.</param>
        public override void SetData <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);

            CheckTotalSize(format, ref formatSize, ref width, elemSize, elementCount);

            //Create staging
            if (_usage == D3D.ResourceUsage.Default)
            {
                CreateStaging();
            }

            try {
                if (_usage == D3D.ResourceUsage.Default)
                {
                    SDX.DataStream ds = _staging.Map(mipLevel, D3D.MapMode.Write, 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.WriteRange <T>(data, startIndex, actWidth);
                    _staging.Unmap(mipLevel);

                    //Copy from the staging to texture
                    if (format == SurfaceFormat.DXT1 || format == SurfaceFormat.DXT3 || format == SurfaceFormat.DXT5)
                    {
                        _graphicsDevice.CopyResource(_staging, _texture1D);
                    }
                    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(_staging, mipLevel, region, _texture1D, mipLevel, left, 0, 0);
                    }
                }
                else
                {
                    SDX.DataStream ds = _texture1D.Map(mipLevel, D3D.MapMode.WriteDiscard, 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.WriteRange <T>(data, startIndex, actWidth);
                    _texture1D.Unmap(mipLevel);
                }
            } catch (Exception e) {
                throw new TeslaException("Error writing to D3D10 Texture1D.", e);
            }
        }
        public void UpdateResource(IPluginOut ForPin, Device OnDevice)
        {
            //Called by the PluginHost every frame for every device. Therefore a plugin should only do
            //device specific operations here and still keep node specific calculations in the Evaluate call.

            try
            {
                Mesh mrty = FDeviceMeshes[OnDevice];
                if (update)
                    RemoveResource(OnDevice);
            }
            catch
            {
                update = true;
            }

            if (update)
            {
               // Device dev = Device.FromPointer(new IntPtr(OnDevice));
                try
                {
                    Mesh nuMesh = new Mesh(OnDevice, numIndices / 3, numVertsOut, MeshFlags.Dynamic | MeshFlags.WriteOnly, VertexFormat.PositionNormal);

                    sVx = nuMesh.LockVertexBuffer(LockFlags.Discard);
                    sIx = nuMesh.LockIndexBuffer(LockFlags.Discard);

                    unsafe
                    {
                        fixed (sVxBuffer* FixTemp = &VxBuffer[0])
                        {
                            IntPtr VxPointer = new IntPtr(FixTemp);
                            sVx.WriteRange(VxPointer, sizeof(sVxBuffer) * numVertsOut);
                        }
                        fixed (short* FixTemp = &IxBuffer[0])
                        {
                            IntPtr IxPointer = new IntPtr(FixTemp);
                            sIx.WriteRange(IxPointer, sizeof(short) * numIndices);
                        }
                    }

                    nuMesh.UnlockVertexBuffer();
                    nuMesh.UnlockIndexBuffer();

                    FDeviceMeshes.Add(OnDevice, nuMesh);
                }
                finally
                {
                    //dev.Dispose();
                    update = false;
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Writes data from the array to the index buffer.
        /// </summary>
        /// <typeparam name="T">The type of data in the index buffer - int or short.</typeparam>
        /// <param name="data">Array to copy the data from</param>
        /// <param name="startIndex">Starting index in the array at which to start copying from</param>
        /// <param name="elementCount">Number of indices to write</param>
        /// <param name="offsetInBytes">Offset from the start of the index buffer at which to start writing at</param>
        /// <param name="writeOptions">Write options, used only if this is a dynamic buffer. None, discard, no overwrite</param>
        /// <remarks>See implementors for exceptions that may occur.</remarks>
        public override void SetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes, DataWriteOptions writeOptions)
        {
            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 write will cause a buffer overflow.");
            }

            bool usesStaging = false;

            if (base.BufferUsage == ResourceUsage.Static || writeOptions == DataWriteOptions.None)
            {
                CreateStaging();
                usesStaging = true;
            }

            try {
                if (usesStaging)
                {
                    using (SDX.DataStream ds = _staging.Map(D3D.MapMode.Write, D3D.MapFlags.None)) {
                        ds.Position = offsetInBytes;
                        ds.WriteRange <T>(data, startIndex, elementCount);
                        _staging.Unmap();

                        //If we're writing to the entire IB just copy the whole thing
                        if (offsetInBytes == 0 && startIndex == 0 && dataSize == ibSize)
                        {
                            _graphicsDevice.CopyResource(_staging, _buffer);
                        }
                        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(_staging, 0, region, _buffer, 0, offsetInBytes, 0, 0);
                        }
                    }
                }
                else
                {
                    D3D.MapMode mode = (writeOptions == DataWriteOptions.Discard) ? D3D.MapMode.WriteDiscard : D3D.MapMode.WriteNoOverwrite;
                    using (SDX.DataStream ds = _buffer.Map(mode, D3D.MapFlags.None)) {
                        ds.Position = offsetInBytes;
                        ds.WriteRange <T>(data, startIndex, elementCount);
                        _buffer.Unmap();
                    }
                }
            } catch (Exception e) {
                throw new TeslaException("Error writing to D3D10 Buffer.", e);
            }
        }
Пример #8
0
        public static DX11VertexGeometry Text3d(DX11RenderContext device, string text, string fontName, float fontSize, float extrude, TextAlignment textAlignment, ParagraphAlignment paragraphAlignment)
        {
            //Dictionary<DX11RenderContext, DX11VertexGeometry> deviceDict = null;
            //if (TextGeometryCache.TryGetValue(text, out deviceDict))
            //{
            //    DX11VertexGeometry geom;
            //    if(deviceDict.TryGetValue(device, out geom))
            //    {
            //        return geom;
            //    }
            //}

            if (d2dFactory == null)
            {
                d2dFactory = new D2DFactory();
                dwFactory  = new DWriteFactory(SharpDX.DirectWrite.FactoryType.Shared);
            }

            TextFormat fmt = new TextFormat(dwFactory, fontName, fontSize);

            TextLayout tl = new TextLayout(dwFactory, text, fmt, 0.0f, .0f);

            tl.WordWrapping       = WordWrapping.NoWrap;
            tl.TextAlignment      = (SharpDX.DirectWrite.TextAlignment)textAlignment;
            tl.ParagraphAlignment = (SharpDX.DirectWrite.ParagraphAlignment)paragraphAlignment;

            OutlineRenderer renderer = new OutlineRenderer(d2dFactory);
            Extruder        ex       = new Extruder(d2dFactory);

            tl.Draw(renderer, 0.0f, 0.0f);

            var geo    = renderer.GetGeometry();
            var result = ex.GetVertices(geo, extrude).ToArray();

            renderer.Dispose();
            geo.Dispose();
            fmt.Dispose();
            tl.Dispose();

            Vector3 min = new Vector3(float.MaxValue);
            Vector3 max = new Vector3(float.MinValue);

            foreach (var pn in result)
            {
                min.X = pn.Position.X < min.X ? pn.Position.X : min.X;
                min.Y = pn.Position.Y < min.Y ? pn.Position.Y : min.Y;
                min.Z = pn.Position.Z < min.Z ? pn.Position.Z : min.Z;

                max.X = pn.Position.X > max.X ? pn.Position.X : max.X;
                max.Y = pn.Position.Y > max.Y ? pn.Position.Y : max.Y;
                max.Z = pn.Position.Z > max.Z ? pn.Position.Z : max.Z;
            }

            SlimDX.DataStream ds = new SlimDX.DataStream(result.Length * Pos3Norm3VertexSDX.VertexSize, true, true);
            ds.Position = 0;

            ds.WriteRange(result);

            ds.Position = 0;

            var vbuffer = new SlimDX.Direct3D11.Buffer(device.Device, ds, new SlimDX.Direct3D11.BufferDescription()
            {
                BindFlags      = SlimDX.Direct3D11.BindFlags.VertexBuffer,
                CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None,
                OptionFlags    = SlimDX.Direct3D11.ResourceOptionFlags.None,
                SizeInBytes    = (int)ds.Length,
                Usage          = SlimDX.Direct3D11.ResourceUsage.Default,
            });

            ds.Dispose();

            DX11VertexGeometry vg = new DX11VertexGeometry(device);

            vg.InputLayout    = Pos3Norm3VertexSDX.Layout;
            vg.Topology       = SlimDX.Direct3D11.PrimitiveTopology.TriangleList;
            vg.VertexBuffer   = vbuffer;
            vg.VertexSize     = Pos3Norm3VertexSDX.VertexSize;
            vg.VerticesCount  = result.Length;
            vg.HasBoundingBox = true;
            vg.BoundingBox    = new SlimDX.BoundingBox(new SlimDX.Vector3(min.X, min.Y, min.Z), new SlimDX.Vector3(max.X, max.Y, max.Z));


            //if(deviceDict != null)
            //{
            //    deviceDict[device] = vg;
            //}
            //else
            //{
            //    deviceDict = new Dictionary<DX11RenderContext, DX11VertexGeometry>();
            //    deviceDict[device] = vg;
            //    TextGeometryCache[text] = deviceDict;
            //}

            return(vg);
        }
        /// <summary>
        /// Sets the vertex data from an array source.
        /// </summary>
        /// <typeparam name="T">The type of data in the vertex buffer.</typeparam>
        /// <param name="data">Array that holds the vertex data</param>
        /// <param name="startIndex">Starting index of the element in the array at which to start copying from</param>
        /// <param name="elementCount">Number of elements to copy from the array</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>
        /// <param name="writeOptions">Writing options for the vertex buffer. None, discard, or no overwrite.</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 write will cause overflow.</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error writing to the buffer.</exception>
        public override void SetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes, int vertexStride, DataWriteOptions writeOptions)
        {
            if (_buffer == null || _buffer.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            //Throw an error if an invalid write options is specified
            if (base.BufferUsage == ResourceUsage.Static && writeOptions != DataWriteOptions.None)
            {
                throw new InvalidOperationException("Can only specify write options other than DataWriteOptions.None for dynamic vertex buffers.");
            }

            //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 ArgumentOutOfRangeException("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 write will cause in buffer overflow.");
            }

            //Create scratch buffer, if it hasn't been created already
            bool usesStaging = false;

            if (base.BufferUsage == ResourceUsage.Static || writeOptions == DataWriteOptions.None)
            {
                CreateStaging();
                usesStaging = true;
            }

            try {
                if (usesStaging)
                {
                    //If we're not going to be writing the entire vertex structure, we need to first
                    //copy the contents of the affected vertex data into the staging buffer
                    if (vertexStep != vertexStride)
                    {
                        //If we're going to be working with all the verts, no need to copy a subresource region
                        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.WriteRange <T>(data, startIndex, elementCount);
                        }
                        else
                        {
                            ds.Position = offsetInBytes;
                            int count = elementCount - 1;
                            int index = startIndex;
                            ds.Write <T>(data[index++]);
                            while (count > 0)
                            {
                                ds.Position += vertexStep;
                                ds.Write <T>(data[index]);
                                count--;
                                index++;
                            }
                        }
                        _staging.Unmap();

                        //If we're writing to the entire VB just copy the whole thing
                        if (offsetInBytes == 0 && startIndex == 0 && dataSize == vbSize)
                        {
                            _graphicsDevice.CopyResource(_staging, _buffer);
                        }
                        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(_staging, 0, region, _buffer, 0, offsetInBytes, 0, 0);
                        }
                    }
                    //Dynamic vertex buffers only
                }
                else
                {
                    D3D.MapMode mode = (writeOptions == DataWriteOptions.Discard) ? D3D.MapMode.WriteDiscard : D3D.MapMode.WriteNoOverwrite;
                    using (SDX.DataStream ds = _buffer.Map(mode, 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.WriteRange <T>(data, startIndex, elementCount);
                        }
                        else
                        {
                            ds.Position = offsetInBytes;
                            int count = elementCount - 1;
                            int index = startIndex;
                            ds.Write <T>(data[index++]);
                            while (count > 0)
                            {
                                ds.Position += vertexStep;
                                ds.Write <T>(data[index]);
                                count--;
                                index++;
                            }
                        }
                        _buffer.Unmap();
                    }
                }
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Buffer.", e);
            }
        }