예제 #1
0
        private void PlatformSetData <T>(int level, Rectangle?rect, T[] data, int startIndex, int elementCount) where T : struct
        {
            var elementSizeInByte = Marshal.SizeOf(typeof(T));
            var dataHandle        = GCHandle.Alloc(data, GCHandleType.Pinned);

            // Use try..finally to make sure dataHandle is freed in case of an error
            try
            {
                var startBytes = startIndex * elementSizeInByte;
                var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);
                int x, y, w, h;
                if (rect.HasValue)
                {
                    x = rect.Value.X;
                    y = rect.Value.Y;
                    w = rect.Value.Width;
                    h = rect.Value.Height;
                }
                else
                {
                    x = 0;
                    y = 0;
                    w = Math.Max(width >> level, 1);
                    h = Math.Max(height >> level, 1);

                    // For DXT textures the width and height of each level is a multiple of 4.
                    // OpenGL only: The last two mip levels require the width and height to be
                    // passed as 2x2 and 1x1, but there needs to be enough data passed to occupy
                    // a 4x4 block.
                    // Ref: http://www.mentby.com/Group/mac-opengl/issue-with-dxt-mipmapped-textures.html
                    if (_format == SurfaceFormat.Dxt1 ||
                        _format == SurfaceFormat.Dxt1a ||
                        _format == SurfaceFormat.Dxt3 ||
                        _format == SurfaceFormat.Dxt5)
                    {
                        w = (w + 3) & ~3;
                        h = (h + 3) & ~3;
                    }
                }

                var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top    = y;
                region.Front  = 0;
                region.Back   = 1;
                region.Bottom = y + h;
                region.Left   = x;
                region.Right  = x + w;

                // TODO: We need to deal with threaded contexts here!
                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                    d3dContext.UpdateSubresource(box, GetTexture(), level, region);
            }
            finally
            {
                dataHandle.Free();
            }
        }
예제 #2
0
        private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            GenerateIfRequired();

            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                {
                    var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None);
                    SharpDX.Utilities.Write(IntPtr.Add(dataBox.DataPointer, offsetInBytes), data, startIndex,
                                            elementCount);
                    d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var elementSizeInBytes = ReflectionHelpers.SizeOf <T> .Get();

                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    var startBytes = startIndex * elementSizeInBytes;
                    var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                    var box = new SharpDX.DataBox(dataPtr, elementCount * elementSizeInBytes, 0);

                    var region = new SharpDX.Direct3D11.ResourceRegion();
                    region.Top    = 0;
                    region.Front  = 0;
                    region.Back   = 1;
                    region.Bottom = 1;
                    region.Left   = offsetInBytes;
                    region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                    // TODO: We need to deal with threaded contexts here!
                    var d3dContext = GraphicsDevice._d3dContext;
                    lock (d3dContext)
                        d3dContext.UpdateSubresource(box, _buffer, 0, region);
                }
                finally
                {
                    dataHandle.Free();
                }
            }
        }
예제 #3
0
        public void CopyFromGpuTexture2D(Point2 destination, GpuTexture2D source, Rectangle region)
        {
            if (region.Right - region.Left == 0 || region.Bottom - region.Top == 0)
            {
                return;
            }

            var resourceRegion = new SharpDX.Direct3D11.ResourceRegion(
                region.Left, region.Top, 0,
                region.Right, region.Bottom, 1);

            GpuDevice.ImmediateContext.CopySubresourceRegion(source.mResource, 0, resourceRegion,
                                                             mResource, 0, destination.X, destination.Y);
        }
예제 #4
0
        public byte[] GetPixelBytes(int left, int top, int width, int height)
        {
            if (width <= 0 || height <= 0)
            {
                return(new byte[] { });
            }
            var device      = _texture.Device;
            var description =
                new SharpDX.Direct3D11.Texture2DDescription()
            {
                Width             = width,
                Height            = height,
                Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                ArraySize         = 1,
                MipLevels         = 1,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                Usage             = SharpDX.Direct3D11.ResourceUsage.Staging,
                BindFlags         = SharpDX.Direct3D11.BindFlags.None,
                CpuAccessFlags    = SharpDX.Direct3D11.CpuAccessFlags.Read,
                OptionFlags       = SharpDX.Direct3D11.ResourceOptionFlags.None
            };

            byte[] result = new byte[width * height * 4];
            using (var staging = new SharpDX.Direct3D11.Texture2D(device, description))
            {
                var textureWidth  = _texture.Description.Width;
                var textureHeight = _texture.Description.Height;
                var srcX0         = Math.Max(0, left);
                var srcY0         = Math.Max(0, top);
                var srcX1         = Math.Min(textureWidth, Math.Max(0, left + width));
                var srcY1         = Math.Min(textureHeight, Math.Max(0, top + height));
                if (srcX1 <= srcX0 || srcY1 <= srcY0)
                {
                    return(new byte[] { });
                }
                var region = new SharpDX.Direct3D11.ResourceRegion(srcX0, srcY0, 0, srcX1, srcY1, 1);
                var dstX0  = Math.Max(0, -left);
                var dstY0  = Math.Max(0, -top);
                device.ImmediateContext.CopySubresourceRegion(_texture, 0, region, staging, 0, dstX0, dstY0);
                var box = device.ImmediateContext.MapSubresource(
                    staging, 0, SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None);
                for (int i = 0; i < height; ++i)
                {
                    Marshal.Copy(box.DataPointer + i * box.RowPitch, result, i * width * 4, width * 4);
                }
                device.ImmediateContext.UnmapSubresource(staging, 0);
            }
            return(result);
        }
        private unsafe void PlatformSetData(
            int byteOffset, ReadOnlySpan <byte> source, SetDataOptions options)
        {
            GenerateIfRequired();

            if (IsDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                {
                    var box = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None);

                    int dstBytes = Capacity * ElementType.TypeSize();
                    var dst      = new Span <byte>((void *)(box.DataPointer + byteOffset), dstBytes);
                    source.CopyTo(dst);

                    d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var region = new SharpDX.Direct3D11.ResourceRegion
                {
                    Top    = 0,
                    Front  = 0,
                    Back   = 1,
                    Bottom = 1,
                    Left   = byteOffset,
                    Right  = byteOffset + source.Length
                };

                // TODO: We need to deal with threaded contexts here!
                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                {
                    ref var mutableData = ref MemoryMarshal.GetReference(source);
                    d3dContext.UpdateSubresource(ref mutableData, _buffer, 0, source.Length, 0, region);
                }
            }
        public SurfaceWithInfo WaitForNewFrame()
        {
            // Let's get a fresh one.
            _currentFrame?.Dispose();
            _frameEvent.Reset();

            var signaledEvent = _events[WaitHandle.WaitAny(_events)];

            if (signaledEvent == _closedEvent)
            {
                Cleanup();
                return(null);
            }

            var result = new SurfaceWithInfo();

            //System.Diagnostics.Debug.WriteLine("Using _currentFrame");
            result.SystemRelativeTime = _currentFrame.SystemRelativeTime;
            //System.Diagnostics.Debug.WriteLine("Done using _currentFrame");
            //result.Surface = _currentFrame.Surface; return result;
            using (var multithreadLock = new MultithreadLock(_multithread))
                using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(_currentFrame.Surface))
                {
                    var description = sourceTexture.Description;
                    description.Usage          = SharpDX.Direct3D11.ResourceUsage.Default;
                    description.BindFlags      = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget;
                    description.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;
                    description.OptionFlags    = SharpDX.Direct3D11.ResourceOptionFlags.None;

                    using (var copyTexture = new SharpDX.Direct3D11.Texture2D(_d3dDevice, description))
                    {
                        var width  = Math.Clamp(_currentFrame.ContentSize.Width, 0, _currentFrame.Surface.Description.Width);
                        var height = Math.Clamp(_currentFrame.ContentSize.Height, 0, _currentFrame.Surface.Description.Height);

                        var region = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, width, height, 1);

                        _d3dDevice.ImmediateContext.CopyResource(_blankTexture, copyTexture);
                        _d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, copyTexture, 0);
                        result.Surface = Direct3D11Helpers.CreateDirect3DSurfaceFromSharpDXTexture(copyTexture);
                    }
                }

            return(result);
        }
예제 #7
0
        public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion?sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }

            var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?();

            if (sourecRegion.HasValue)
            {
                var value = sourecRegion.Value;
                nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back);
            }

            NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ);
        }
예제 #8
0
        public SurfaceWithInfo WaitForNewFrame()
        {
            // Let's get a fresh one.
            this.currentFrame?.Dispose();
            this.frameEvent.Reset();

            var signaledEvent = this.events[WaitHandle.WaitAny(this.events)];

            if (signaledEvent == this.closedEvent)
            {
                this.CleanupItem();
                return(null);
            }

            using var multithreadLock = new MultithreadLock(this.multithread);
            using var sourceTexture   = Direct3D11Helper.CreateSharpDXTexture2D(this.currentFrame.Surface);
            var description = sourceTexture.Description;

            description.Usage          = SharpDX.Direct3D11.ResourceUsage.Default;
            description.BindFlags      = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget;
            description.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;
            description.OptionFlags    = SharpDX.Direct3D11.ResourceOptionFlags.None;

            using var copyTexture = new SharpDX.Direct3D11.Texture2D(this.d3dDevice, description);
            var width  = Math.Clamp(this.currentFrame.ContentSize.Width, 0, this.currentFrame.Surface.Description.Width);
            var height = Math.Clamp(this.currentFrame.ContentSize.Height, 0, this.currentFrame.Surface.Description.Height);

            var region = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, width, height, 1);

            this.d3dDevice.ImmediateContext.CopyResource(blankTexture, copyTexture);
            this.d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, copyTexture, 0);
            var result = new SurfaceWithInfo
            {
                SystemRelativeTime = this.currentFrame.SystemRelativeTime,
                Surface            = Direct3D11Helper.CreateDirect3DSurfaceFromSharpDXTexture(copyTexture)
            };

            return(result);
        }
예제 #9
0
        public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (destination == null) throw new ArgumentNullException("destination");

            var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?();

            if (sourecRegion.HasValue)
            {
                var value = sourecRegion.Value;
                nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back);
            }

            NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ);
        }
예제 #10
0
        protected void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data is null");
            }
            if (data.Length < (startIndex + elementCount))
            {
                throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested.");
            }

            var bufferSize = VertexCount * VertexDeclaration.VertexStride;

            if ((vertexStride > bufferSize) || (vertexStride < VertexDeclaration.VertexStride))
            {
                throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested.");
            }

#if !PSS
            var elementSizeInBytes = Marshal.SizeOf(typeof(T));
#endif

#if DIRECTX
            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                SharpDX.DataStream stream;
                lock (graphicsDevice._d3dContext)
                {
                    graphicsDevice._d3dContext.MapSubresource(
                        _buffer,
                        mode,
                        SharpDX.Direct3D11.MapFlags.None,
                        out stream);

                    stream.Position = offsetInBytes;
                    stream.WriteRange(data, startIndex, elementCount);

                    graphicsDevice._d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                var startBytes = startIndex * elementSizeInBytes;
                var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                var box = new SharpDX.DataBox(dataPtr, 1, 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top    = 0;
                region.Front  = 0;
                region.Back   = 1;
                region.Bottom = 1;
                region.Left   = offsetInBytes;
                region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                lock (graphicsDevice._d3dContext)
                    graphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region);

                dataHandle.Free();
            }
#elif PSS
            if (_vertexArray == null)
            {
                _vertexArray = new T[VertexCount];
            }
            Array.Copy(data, offsetInBytes / vertexStride, _vertexArray, startIndex, elementCount);
#else
            Threading.BlockOnUIThread(() =>
            {
                var sizeInBytes = elementSizeInBytes * elementCount;
                GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
                GraphicsExtensions.CheckGLError();

                if (options == SetDataOptions.Discard)
                {
                    // By assigning NULL data to the buffer this gives a hint
                    // to the device to discard the previous content.
                    GL.BufferData(BufferTarget.ArrayBuffer,
                                  (IntPtr)bufferSize,
                                  IntPtr.Zero,
                                  _isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw);
                    GraphicsExtensions.CheckGLError();
                }

                GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)sizeInBytes, data);
                GraphicsExtensions.CheckGLError();
            });
#endif
        }
예제 #11
0
        private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options, int bufferSize, int elementSizeInBytes) where T : struct
        {
            GenerateIfRequired();

            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                {
                    var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None);
                    if (vertexStride == elementSizeInBytes)
                    {
                        SharpDX.Utilities.Write(dataBox.DataPointer + offsetInBytes, data, startIndex, elementCount);
                    }
                    else
                    {
                        for (int i = 0; i < elementCount; i++)
                        {
                            SharpDX.Utilities.Write(dataBox.DataPointer + offsetInBytes + i * vertexStride, data, startIndex + i, 1);
                        }
                    }

                    d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    var startBytes = startIndex * elementSizeInBytes;
                    var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                    var d3dContext = GraphicsDevice._d3dContext;

                    if (vertexStride == elementSizeInBytes)
                    {
                        var box = new SharpDX.DataBox(dataPtr, elementCount * elementSizeInBytes, 0);

                        var region = new SharpDX.Direct3D11.ResourceRegion();
                        region.Top    = 0;
                        region.Front  = 0;
                        region.Back   = 1;
                        region.Bottom = 1;
                        region.Left   = offsetInBytes;
                        region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                        lock (d3dContext)
                            d3dContext.UpdateSubresource(box, _buffer, 0, region);
                    }
                    else
                    {
                        // Copy the buffer to a staging resource, so that any elements we don't write to will still be correct.
                        var stagingDesc = _buffer.Description;
                        stagingDesc.BindFlags      = SharpDX.Direct3D11.BindFlags.None;
                        stagingDesc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Read | SharpDX.Direct3D11.CpuAccessFlags.Write;
                        stagingDesc.Usage          = SharpDX.Direct3D11.ResourceUsage.Staging;
                        stagingDesc.OptionFlags    = SharpDX.Direct3D11.ResourceOptionFlags.None;
                        using (var stagingBuffer = new SharpDX.Direct3D11.Buffer(GraphicsDevice._d3dDevice, stagingDesc))
                        {
                            lock (d3dContext)
                            {
                                d3dContext.CopyResource(_buffer, stagingBuffer);

                                // Map the staging resource to a CPU accessible memory
                                var box = d3dContext.MapSubresource(stagingBuffer, 0, SharpDX.Direct3D11.MapMode.Read,
                                                                    SharpDX.Direct3D11.MapFlags.None);

                                for (int i = 0; i < elementCount; i++)
                                {
                                    SharpDX.Utilities.CopyMemory(
                                        box.DataPointer + i * vertexStride + offsetInBytes,
                                        dataPtr + i * elementSizeInBytes, elementSizeInBytes);
                                }

                                // Make sure that we unmap the resource in case of an exception
                                d3dContext.UnmapSubresource(stagingBuffer, 0);

                                // Copy back from staging resource to real buffer.
                                d3dContext.CopyResource(stagingBuffer, _buffer);
                            }
                        }
                    }
                }
                finally
                {
                    dataHandle.Free();
                }
            }
        }
예제 #12
0
파일: Texture2D.cs 프로젝트: bjarkeeck/GCGJ
        public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct 
        {
            if (data == null)
				throw new ArgumentNullException("data");

#if OPENGL
            Threading.BlockOnUIThread(() =>
            {
#endif
#if !PSM
                var elementSizeInByte = Marshal.SizeOf(typeof(T));
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                // Use try..finally to make sure dataHandle is freed in case of an error
                try
                {
                    var startBytes = startIndex * elementSizeInByte;
                    var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);
#endif
                    int x, y, w, h;
                    if (rect.HasValue)
                    {
                        x = rect.Value.X;
                        y = rect.Value.Y;
                        w = rect.Value.Width;
                        h = rect.Value.Height;
                    }
                    else
                    {
                        x = 0;
                        y = 0;
                        w = Math.Max(width >> level, 1);
                        h = Math.Max(height >> level, 1);

                        // For DXT textures the width and height of each level is a multiple of 4.
                        // OpenGL only: The last two mip levels require the width and height to be 
                        // passed as 2x2 and 1x1, but there needs to be enough data passed to occupy 
                        // a 4x4 block. 
                        // Ref: http://www.mentby.com/Group/mac-opengl/issue-with-dxt-mipmapped-textures.html 
                        if (_format == SurfaceFormat.Dxt1 ||
                            _format == SurfaceFormat.Dxt1a ||
                            _format == SurfaceFormat.Dxt3 ||
                            _format == SurfaceFormat.Dxt5)
                        {
#if DIRECTX
                            w = (w + 3) & ~3;
                            h = (h + 3) & ~3;
#else
                            if (w > 4)
                                w = (w + 3) & ~3;
                            if (h > 4)
                                h = (h + 3) & ~3;
#endif
                        }
                    }

#if DIRECTX
                    var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0);

                    var region = new SharpDX.Direct3D11.ResourceRegion();
                    region.Top = y;
                    region.Front = 0;
                    region.Back = 1;
                    region.Bottom = y + h;
                    region.Left = x;
                    region.Right = x + w;

                    // TODO: We need to deal with threaded contexts here!
                    var d3dContext = GraphicsDevice._d3dContext;
                    lock (d3dContext)
						d3dContext.UpdateSubresource(box, GetTexture(), level, region);

#elif PSM
                    _texture2D.SetPixels(level, data, _texture2D.Format, startIndex, 0, x, y, w, h);
#elif OPENGL

                    // Store the current bound texture.
                    var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                    GenerateGLTextureIfRequired();

                    GL.BindTexture(TextureTarget.Texture2D, this.glTexture);
                    GraphicsExtensions.CheckGLError();
                    if (glFormat == (GLPixelFormat)All.CompressedTextureFormats)
                    {
                        if (rect.HasValue)
                        {
                            GL.CompressedTexSubImage2D(TextureTarget.Texture2D,
                                level, x, y, w, h,
#if GLES
                                glInternalFormat,
#else
                                glFormat,
#endif
                                data.Length - startBytes, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        else
                        {
                            GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, data.Length - startBytes, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                    }
                    else
                    {
                        // Set pixel alignment to match texel size in bytes
                        GL.PixelStore(PixelStoreParameter.UnpackAlignment, GraphicsExtensions.Size(this.Format));
                        if (rect.HasValue)
                        {
                            GL.TexSubImage2D(TextureTarget.Texture2D, level,
                                            x, y, w, h,
                                            glFormat, glType, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        else
                        {
                            GL.TexImage2D(TextureTarget.Texture2D, level,
#if GLES
                                (int)glInternalFormat,
#else
                                glInternalFormat,
#endif
                                w, h, 0, glFormat, glType, dataPtr);
                            GraphicsExtensions.CheckGLError();
                        }
                        // Return to default pixel alignment
                        GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
                    }

#if !ANDROID
                    GL.Finish();
                    GraphicsExtensions.CheckGLError();
#endif
                    // Restore the bound texture.
                    GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                    GraphicsExtensions.CheckGLError();

#endif // OPENGL

#if !PSM
                }
                finally
                {
                    dataHandle.Free();
                }
#endif

#if OPENGL
#if !ANDROID
                // Required to make sure that any texture uploads on a thread are completed
                // before the main thread tries to use the texture.
                GL.Finish();
#endif
            });
#endif
        }
예제 #13
0
파일: Texture2D.cs 프로젝트: vnoob/MonoGame
        public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct 
        {
            if (data == null)
				throw new ArgumentNullException("data");

#if OPENGL
            Threading.BlockOnUIThread(() =>
            {
#endif
#if !PSM
                var elementSizeInByte = Marshal.SizeOf(typeof(T));
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                var startBytes = startIndex * elementSizeInByte;
                var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);
#endif
                int x, y, w, h;
                if (rect.HasValue)
                {
                    x = rect.Value.X;
                    y = rect.Value.Y;
                    w = rect.Value.Width;
                    h = rect.Value.Height;
                }
                else
                {
                    x = 0;
                    y = 0;
                    w = Math.Max(width >> level, 1);
                    h = Math.Max(height >> level, 1);
                }

#if DIRECTX

                var box = new SharpDX.DataBox(dataPtr, GetPitch(w), 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top = y;
                region.Front = 0;
                region.Back = 1;
                region.Bottom = y + h;
                region.Left = x;
                region.Right = x + w;

                // TODO: We need to deal with threaded contexts here!
                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                    d3dContext.UpdateSubresource(box, _texture, level, region);

#elif PSM
                _texture2D.SetPixels(level, data, _texture2D.Format, startIndex, 0, x, y, w, h);


#elif OPENGL

                // Store the current bound texture.
                var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                GenerateGLTextureIfRequired();

                GL.BindTexture(TextureTarget.Texture2D, this.glTexture);
                GraphicsExtensions.CheckGLError();
                if (glFormat == (GLPixelFormat)All.CompressedTextureFormats)
                {
                    if (rect.HasValue)
                    {
                        GL.CompressedTexSubImage2D(TextureTarget.Texture2D,
                                                    level, x, y, w, h,
#if GLES
                                                    glInternalFormat,
#else
                                                    glFormat,
#endif
                                                    data.Length - startBytes, dataPtr);
                        GraphicsExtensions.CheckGLError();
                    }
                    else
                    {
                        GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, data.Length - startBytes, dataPtr);
                        GraphicsExtensions.CheckGLError();
                    }
                }
                else
                {
                    // Set pixel alignment to match texel size in bytes
                    GL.PixelStore(PixelStoreParameter.UnpackAlignment, GraphicsExtensions.Size(this.Format));
                    if (rect.HasValue)
                    {
                        GL.TexSubImage2D(TextureTarget.Texture2D, level,
                                        x, y, w, h,
                                        glFormat, glType, dataPtr);
                        GraphicsExtensions.CheckGLError();
                    }
                    else
                    {
                        GL.TexImage2D(TextureTarget.Texture2D, level,
#if GLES
                                  (int)glInternalFormat,
#else
                                  glInternalFormat,
#endif
                                  w, h, 0, glFormat, glType, dataPtr);
                        GraphicsExtensions.CheckGLError();
                    }
                    // Return to default pixel alignment
                    GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
                }

#if !ANDROID
                GL.Finish();
                GraphicsExtensions.CheckGLError();
#endif
                // Restore the bound texture.
                GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                GraphicsExtensions.CheckGLError();

#endif // OPENGL

#if !PSM
                dataHandle.Free();
#endif

#if OPENGL
#if !ANDROID
                // Required to make sure that any texture uploads on a thread are completed
                // before the main thread tries to use the texture.
                GL.Finish();
#endif
            });
#endif
        }
예제 #14
0
        protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data is null");
            }
            if (data.Length < (startIndex + elementCount))
            {
                throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested.");
            }

#if DIRECTX
            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                SharpDX.DataStream stream;
                lock (graphicsDevice._d3dContext)
                {
                    graphicsDevice._d3dContext.MapSubresource(
                        _buffer,
                        mode,
                        SharpDX.Direct3D11.MapFlags.None,
                        out stream);

                    stream.Position = offsetInBytes;
                    stream.WriteRange(data, startIndex, elementCount);

                    graphicsDevice._d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var elementSizeInBytes = Marshal.SizeOf(typeof(T));
                var dataHandle         = GCHandle.Alloc(data, GCHandleType.Pinned);
                var startBytes         = startIndex * elementSizeInBytes;
                var dataPtr            = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                var box = new SharpDX.DataBox(dataPtr, 1, 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top    = 0;
                region.Front  = 0;
                region.Back   = 1;
                region.Bottom = 1;
                region.Left   = offsetInBytes;
                region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                // TODO: We need to deal with threaded contexts here!
                lock (graphicsDevice._d3dContext)
                    graphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region);

                dataHandle.Free();
            }
#elif PSS
            if (typeof(T) == typeof(ushort))
            {
                Array.Copy(data, offsetInBytes / sizeof(ushort), _buffer, startIndex, elementCount);
            }
            else
            {
                throw new NotImplementedException("PSS Currently only supports ushort (SixteenBits) index elements");
                //Something like as follows probably works if you really need this, but really just make a ushort array!

                /*
                 * int indexOffset = offsetInBytes / sizeof(T);
                 * for (int i = 0; i < elementCount; i++)
                 *  _buffer[i + startIndex] = (ushort)(object)data[i + indexOffset];
                 */
            }
#else
            Threading.BlockOnUIThread(() =>
            {
                var elementSizeInByte = Marshal.SizeOf(typeof(T));
                var sizeInBytes       = elementSizeInByte * elementCount;
                var dataHandle        = GCHandle.Alloc(data, GCHandleType.Pinned);
                var dataPtr           = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInByte);
                var bufferSize        = IndexCount * (IndexElementSize == IndexElementSize.SixteenBits ? 2 : 4);

                GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
                GraphicsExtensions.CheckGLError();

                if (options == SetDataOptions.Discard)
                {
                    // By assigning NULL data to the buffer this gives a hint
                    // to the device to discard the previous content.
                    GL.BufferData(BufferTarget.ElementArrayBuffer,
                                  (IntPtr)bufferSize,
                                  IntPtr.Zero,
                                  _isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw);
                    GraphicsExtensions.CheckGLError();
                }

                GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)sizeInBytes, dataPtr);
                GraphicsExtensions.CheckGLError();

                dataHandle.Free();
            });
#endif
        }
예제 #15
0
        private async void MainToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            // Select what we want to capture
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                // Get a temporary file to save our gif to
                var file = await GetTempFileAsync();

                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    // Get the various d3d objects we'll need
                    var d3dDevice = Direct3D11Helpers.CreateSharpDXDevice(_device);

                    // Create our encoder
                    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, stream);

                    // Write the application block
                    // http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
                    var containerProperties = encoder.BitmapContainerProperties;
                    await containerProperties.SetPropertiesAsync(new[]
                    {
                        new KeyValuePair <string, BitmapTypedValue>("/appext/application", new BitmapTypedValue(PropertyValue.CreateUInt8Array(Encoding.ASCII.GetBytes("NETSCAPE2.0")), PropertyType.UInt8Array)),
                        // The first value is the size of the block, which is the fixed value 3.
                        // The second value is the looping extension, which is the fixed value 1.
                        // The third and fourth values comprise an unsigned 2-byte integer (little endian).
                        //     The value of 0 means to loop infinitely.
                        // The final value is the block terminator, which is the fixed value 0.
                        new KeyValuePair <string, BitmapTypedValue>("/appext/data", new BitmapTypedValue(PropertyValue.CreateUInt8Array(new byte[] { 3, 1, 0, 0, 0 }), PropertyType.UInt8Array)),
                    });

                    // Setup Windows.Graphics.Capture
                    var itemSize  = item.Size;
                    var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
                        _device,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        1,
                        itemSize);
                    var session = framePool.CreateCaptureSession(item);

                    // We need a blank texture (background) and a texture that will hold the frame we'll be encoding
                    var description = new SharpDX.Direct3D11.Texture2DDescription
                    {
                        Width             = itemSize.Width,
                        Height            = itemSize.Height,
                        MipLevels         = 1,
                        ArraySize         = 1,
                        Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                        SampleDescription = new SharpDX.DXGI.SampleDescription()
                        {
                            Count   = 1,
                            Quality = 0
                        },
                        Usage          = SharpDX.Direct3D11.ResourceUsage.Default,
                        BindFlags      = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget,
                        CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
                        OptionFlags    = SharpDX.Direct3D11.ResourceOptionFlags.None
                    };
                    var gifTexture       = new SharpDX.Direct3D11.Texture2D(d3dDevice, description);
                    var renderTargetView = new SharpDX.Direct3D11.RenderTargetView(d3dDevice, gifTexture);

                    // Encode frames as they arrive. Because we created our frame pool using
                    // Direct3D11CaptureFramePool::CreateFreeThreaded, this lambda will fire on a different thread
                    // than our current one. If you'd like the callback to fire on your thread, create the frame pool
                    // using Direct3D11CaptureFramePool::Create and make sure your thread has a DispatcherQueue and you
                    // are pumping messages.
                    TimeSpan lastTimeStamp = TimeSpan.MinValue;
                    var      frameCount    = 0;
                    framePool.FrameArrived += async(s, a) =>
                    {
                        using (var frame = s.TryGetNextFrame())
                        {
                            var contentSize = frame.ContentSize;
                            var timeStamp   = frame.SystemRelativeTime;
                            using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(frame.Surface))
                            {
                                var width  = Math.Clamp(contentSize.Width, 0, itemSize.Width);
                                var height = Math.Clamp(contentSize.Height, 0, itemSize.Height);

                                var region = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, width, height, 1);

                                d3dDevice.ImmediateContext.ClearRenderTargetView(renderTargetView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 1));
                                d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, gifTexture, 0);
                            }

                            if (lastTimeStamp == TimeSpan.MinValue)
                            {
                                lastTimeStamp = timeStamp;
                            }
                            var timeStampDelta = timeStamp - lastTimeStamp;
                            lastTimeStamp = timeStamp;
                            var milliseconds = timeStampDelta.TotalMilliseconds;
                            // Use 10ms units
                            var frameDelay = milliseconds / 10;

                            if (frameCount > 0)
                            {
                                await encoder.GoToNextFrameAsync();
                            }

                            // Write our frame delay
                            await encoder.BitmapProperties.SetPropertiesAsync(new[]
                            {
                                new KeyValuePair <string, BitmapTypedValue>("/grctlext/Delay", new BitmapTypedValue(PropertyValue.CreateUInt16((ushort)frameDelay), PropertyType.UInt16)),
                            });

                            // Write the frame to our image
                            var gifSurface = Direct3D11Helpers.CreateDirect3DSurfaceFromSharpDXTexture(gifTexture);
                            var copy       = await SoftwareBitmap.CreateCopyFromSurfaceAsync(gifSurface);

                            encoder.SetSoftwareBitmap(copy);
                            frameCount++;
                        }
                    };

                    session.StartCapture();

                    await _semaphore.WaitAsync();

                    session.Dispose();
                    framePool.Dispose();
                    await Task.Delay(1000);

                    await encoder.FlushAsync();

                    var newFile = await PickGifAsync();

                    if (newFile == null)
                    {
                        await file.DeleteAsync();

                        return;
                    }
                    await file.MoveAndReplaceAsync(newFile);

                    await Launcher.LaunchFileAsync(newFile);
                }
            }
        }
예제 #16
0
        protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data is null");
            }
            if (data.Length < (startIndex + elementCount))
            {
                throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested.");
            }
#if !PORTABLE
#if DIRECTX
            GenerateIfRequired();

            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                {
                    var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None);
                    SharpDX.Utilities.Write(IntPtr.Add(dataBox.DataPointer, offsetInBytes), data, startIndex,
                                            elementCount);
                    d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var elementSizeInBytes = Marshal.SizeOf(typeof(T));
                var dataHandle         = GCHandle.Alloc(data, GCHandleType.Pinned);
                var startBytes         = startIndex * elementSizeInBytes;
                var dataPtr            = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                var box = new SharpDX.DataBox(dataPtr, 1, 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top    = 0;
                region.Front  = 0;
                region.Back   = 1;
                region.Bottom = 1;
                region.Left   = offsetInBytes;
                region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                // TODO: We need to deal with threaded contexts here!
                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                    d3dContext.UpdateSubresource(box, _buffer, 0, region);

                dataHandle.Free();
            }
#elif PSM
            if (typeof(T) == typeof(ushort))
            {
                Array.Copy(data, offsetInBytes / sizeof(ushort), _buffer, startIndex, elementCount);
            }
            else
            {
                throw new NotImplementedException("PSS Currently only supports ushort (SixteenBits) index elements");
                //Something like as follows probably works if you really need this, but really just make a ushort array!

                /*
                 * int indexOffset = offsetInBytes / sizeof(T);
                 * for (int i = 0; i < elementCount; i++)
                 *  _buffer[i + startIndex] = (ushort)(object)data[i + indexOffset];
                 */
            }
#else
            if (Threading.IsOnUIThread())
            {
                BufferData(offsetInBytes, data, startIndex, elementCount, options);
            }
            else
            {
                Threading.BlockOnUIThread(() => BufferData(offsetInBytes, data, startIndex, elementCount, options));
            }
#endif
#endif
        }
예제 #17
0
        protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data is null");
            }
            if (data.Length < (startIndex + elementCount))
            {
                throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested.");
            }

            var bufferSize = VertexCount * VertexDeclaration.VertexStride;

            if ((vertexStride > bufferSize) || (vertexStride < VertexDeclaration.VertexStride))
            {
                throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested.");
            }

#if !PSM
            var elementSizeInBytes = Marshal.SizeOf(typeof(T));
#endif

#if DIRECTX
            GenerateIfRequired();

            if (_isDynamic)
            {
                // We assume discard by default.
                var mode = SharpDX.Direct3D11.MapMode.WriteDiscard;
                if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite)
                {
                    mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite;
                }

                var d3dContext = GraphicsDevice._d3dContext;
                lock (d3dContext)
                {
                    var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None);
                    SharpDX.Utilities.Write(IntPtr.Add(dataBox.DataPointer, offsetInBytes), data, startIndex,
                                            elementCount);
                    d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                var startBytes = startIndex * elementSizeInBytes;
                var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                var box = new SharpDX.DataBox(dataPtr, 1, 0);

                var region = new SharpDX.Direct3D11.ResourceRegion();
                region.Top    = 0;
                region.Front  = 0;
                region.Back   = 1;
                region.Bottom = 1;
                region.Left   = offsetInBytes;
                region.Right  = offsetInBytes + (elementCount * elementSizeInBytes);

                lock (GraphicsDevice._d3dContext)
                    GraphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region);

                dataHandle.Free();
            }
#elif PSM
            if (_vertexArray == null)
            {
                _vertexArray = new T[VertexCount];
            }
            Array.Copy(data, offsetInBytes / vertexStride, _vertexArray, startIndex, elementCount);
#else
            if (Threading.IsOnUIThread())
            {
                SetBufferData(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options);
            }
            else
            {
                Threading.BlockOnUIThread(() => SetBufferData(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options));
            }
#endif
        }