示例#1
0
        internal override SharpDX.Direct3D11.Resource CreateTexture()
        {
            var description = new Texture2DDescription
            {
                Width             = size,
                Height            = size,
                MipLevels         = _levelCount,
                ArraySize         = 6, // A texture cube is a 2D texture array with 6 textures.
                Format            = SharpDXHelper.ToFormat(_format),
                BindFlags         = BindFlags.ShaderResource,
                CpuAccessFlags    = CpuAccessFlags.None,
                SampleDescription = { Count = 1, Quality = 0 },
                Usage             = ResourceUsage.Default,
                OptionFlags       = ResourceOptionFlags.TextureCube
            };

            if (_renderTarget)
            {
                description.BindFlags |= BindFlags.RenderTarget;
                if (_mipMap)
                {
                    description.OptionFlags |= ResourceOptionFlags.GenerateMipMaps;
                }
            }

            return(new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, description));
        }
示例#2
0
        private void PlatformGetData <T>(int level, int left, int top, int right, int bottom, int front, int back, T[] data, int startIndex, int elementCount)
            where T : struct
        {
            // Create a temp staging resource for copying the data.
            //
            // TODO: Like in Texture2D, we should probably be pooling these staging resources
            // and not creating a new one each time.
            //
            var desc = new Texture3DDescription
            {
                Width          = _width,
                Height         = _height,
                Depth          = _depth,
                MipLevels      = 1,
                Format         = SharpDXHelper.ToFormat(_format),
                BindFlags      = BindFlags.None,
                CpuAccessFlags = CpuAccessFlags.Read,
                Usage          = ResourceUsage.Staging,
                OptionFlags    = ResourceOptionFlags.None,
            };

            var d3dContext = GraphicsDevice._d3dContext;

            using (var stagingTex = new SharpDX.Direct3D11.Texture3D(GraphicsDevice._d3dDevice, desc))
            {
                lock (d3dContext)
                {
                    // Copy the data from the GPU to the staging texture.
                    d3dContext.CopySubresourceRegion(GetTexture(), level, new ResourceRegion(left, top, front, right, bottom, back), stagingTex, 0);

                    // Copy the data to the array.
                    DataStream stream = null;
                    try
                    {
                        var databox = d3dContext.MapSubresource(stagingTex, 0, MapMode.Read, MapFlags.None, out stream);

                        // Some drivers may add pitch to rows or slices.
                        // We need to copy each row separatly and skip trailing zeros.
                        var currentIndex  = startIndex;
                        var elementSize   = _format.GetSize();
                        var elementsInRow = right - left;
                        var rowsInSlice   = bottom - top;
                        for (var slice = front; slice < back; slice++)
                        {
                            for (var row = top; row < bottom; row++)
                            {
                                stream.ReadRange(data, currentIndex, elementsInRow);
                                stream.Seek(databox.RowPitch - (elementSize * elementsInRow), SeekOrigin.Current);
                                currentIndex += elementsInRow;
                            }
                            stream.Seek(databox.SlicePitch - (databox.RowPitch * rowsInSlice), SeekOrigin.Current);
                        }
                    }
                    finally
                    {
                        SharpDX.Utilities.Dispose(ref stream);
                    }
                }
            }
        }
示例#3
0
        internal override SharpDX.Direct3D11.Resource CreateTexture()
        {
            var description = new Texture3DDescription
            {
                Width          = width,
                Height         = height,
                Depth          = depth,
                MipLevels      = _levelCount,
                Format         = SharpDXHelper.ToFormat(_format),
                BindFlags      = BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.None,
                Usage          = ResourceUsage.Default,
                OptionFlags    = ResourceOptionFlags.None,
            };

            if (renderTarget)
            {
                description.BindFlags |= BindFlags.RenderTarget;
                if (mipMap)
                {
                    // Note: XNA 4 does not have a method Texture.GenerateMipMaps()
                    // because generation of mipmaps is not supported on the Xbox 360.
                    // TODO: New method Texture.GenerateMipMaps() required.
                    description.OptionFlags |= ResourceOptionFlags.GenerateMipMaps;
                }
            }

            return(new SharpDX.Direct3D11.Texture3D(GraphicsDevice._d3dDevice, description));
        }
示例#4
0
        protected internal virtual Texture2DDescription GetTexture2DDescription()
        {
            var desc = new Texture2DDescription();

            desc.Width             = width;
            desc.Height            = height;
            desc.MipLevels         = _levelCount;
            desc.ArraySize         = ArraySize;
            desc.Format            = SharpDXHelper.ToFormat(_format);
            desc.BindFlags         = BindFlags.ShaderResource;
            desc.CpuAccessFlags    = CpuAccessFlags.None;
            desc.SampleDescription = CreateSampleDescription();
            desc.Usage             = ResourceUsage.Default;
            desc.OptionFlags       = ResourceOptionFlags.None;

            if (_shared)
            {
                desc.OptionFlags |= ResourceOptionFlags.Shared;
            }

            if (_mipmap)
            {
                desc.OptionFlags |= ResourceOptionFlags.GenerateMipMaps;
                desc.BindFlags   |= BindFlags.RenderTarget;
            }

            return(desc);
        }
        private void PlatformConstruct(GraphicsDevice graphicsDevice, int width, int height, bool mipMap,
                                       DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage)
        {
            // Setup the multisampling description.
            var multisampleDesc = new SharpDX.DXGI.SampleDescription(1, 0);

            if (preferredMultiSampleCount > 1)
            {
                multisampleDesc.Count   = preferredMultiSampleCount;
                multisampleDesc.Quality = (int)StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            // Create a descriptor for the depth/stencil buffer.
            // Allocate a 2-D surface as the depth/stencil buffer.
            // Create a DepthStencil view on this surface to use on bind.
            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, new Texture2DDescription
            {
                Format = SharpDXHelper.ToFormat(preferredDepthFormat),
                ArraySize = 1,
                MipLevels = 1,
                Width = width,
                Height = height,
                SampleDescription = multisampleDesc,
                BindFlags = BindFlags.DepthStencil,
            }))
            {
                // Create the view for binding to the device.
                _depthStencilView = new DepthStencilView(graphicsDevice._d3dDevice, depthBuffer, new DepthStencilViewDescription()
                {
                    Format    = SharpDXHelper.ToFormat(preferredDepthFormat),
                    Dimension = DepthStencilViewDimension.Texture2D
                });
            }
        }
示例#6
0
        private void PlatformConstruct(GraphicsDevice graphicsDevice, int width, int height, bool mipMap,
                                       DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage, bool shared)
        {
            _msSampleDescription = GraphicsDevice.GetSupportedSampleDescription(SharpDXHelper.ToFormat(this.Format), this.MultiSampleCount);

            GenerateIfRequired();
        }
示例#7
0
        internal override SharpDX.Direct3D11.Resource CreateTexture()
		{
            // TODO: Move this to SetData() if we want to make Immutable textures!
            var desc = new SharpDX.Direct3D11.Texture2DDescription();
            desc.Width = width;
            desc.Height = height;
            desc.MipLevels = _levelCount;
            desc.ArraySize = 1;
            desc.Format = SharpDXHelper.ToFormat(_format);
            desc.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource;
            desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;
            desc.SampleDescription.Count = 1;
            desc.SampleDescription.Quality = 0;
            desc.Usage = SharpDX.Direct3D11.ResourceUsage.Default;
            desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;

            if (_renderTarget)
            {
                desc.BindFlags |= SharpDX.Direct3D11.BindFlags.RenderTarget;
                if (_mipmap)
                {
                    // Note: XNA 4 does not have a method Texture.GenerateMipMaps() 
                    // because generation of mipmaps is not supported on the Xbox 360.
                    // TODO: New method Texture.GenerateMipMaps() required.
                    desc.OptionFlags |= SharpDX.Direct3D11.ResourceOptionFlags.GenerateMipMaps;
                }
            }
            if (_shared)
                desc.OptionFlags |= SharpDX.Direct3D11.ResourceOptionFlags.Shared;

            return new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, desc);
        }
        private void PlatformConstruct(GraphicsDevice graphicsDevice, bool mipMap, SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage)
        {
            // Create one render target view per cube map face.
            _renderTargetViews = new RenderTargetView[6];
            for (int i = 0; i < _renderTargetViews.Length; i++)
            {
                var renderTargetViewDescription = new RenderTargetViewDescription
                {
                    Dimension      = RenderTargetViewDimension.Texture2DArray,
                    Format         = SharpDXHelper.ToFormat(preferredFormat),
                    Texture2DArray =
                    {
                        ArraySize       = 1,
                        FirstArraySlice = i,
                        MipSlice        = 0
                    }
                };

                _renderTargetViews[i] = new RenderTargetView(graphicsDevice._d3dDevice, GetTexture(), renderTargetViewDescription);
            }

            // If we don't need a depth buffer then we're done.
            if (preferredDepthFormat == DepthFormat.None)
            {
                return;
            }

            var sampleDescription = new SampleDescription(1, 0);

            if (preferredMultiSampleCount > 1)
            {
                sampleDescription.Count   = preferredMultiSampleCount;
                sampleDescription.Quality = (int)StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            var depthStencilDescription = new Texture2DDescription
            {
                Format            = SharpDXHelper.ToFormat(preferredDepthFormat),
                ArraySize         = 1,
                MipLevels         = 1,
                Width             = size,
                Height            = size,
                SampleDescription = sampleDescription,
                BindFlags         = BindFlags.DepthStencil,
            };

            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, depthStencilDescription))
            {
                var depthStencilViewDescription = new DepthStencilViewDescription
                {
                    Dimension = DepthStencilViewDimension.Texture2D,
                    Format    = SharpDXHelper.ToFormat(preferredDepthFormat),
                };
                _depthStencilView = new DepthStencilView(graphicsDevice._d3dDevice, depthBuffer, depthStencilViewDescription);
            }
        }
示例#9
0
 internal virtual void ResolveSubresource()
 {
     lock (GraphicsDevice._d3dContext)
     {
         GraphicsDevice._d3dContext.ResolveSubresource(
             GetMSTexture(),
             0,
             GetTexture(),
             0,
             SharpDXHelper.ToFormat(Format));
     }
 }
示例#10
0
 internal void ResolveSubresource()
 {
     lock (GraphicsDevice._d3dContext)
     {
         GraphicsDevice._d3dContext.ResolveSubresource(
             this._texture,
             0,
             _resolvedTexture._texture,
             0,
             SharpDXHelper.ToFormat(_format));
     }
 }
示例#11
0
        public Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format)
        {
            if (graphicsDevice == null)
            {
                throw new ArgumentNullException("graphicsDevice");
            }

            this.GraphicsDevice = graphicsDevice;
            this.width          = width;
            this.height         = height;
            this.depth          = depth;
            this.levelCount     = 1;

#if OPENGL
            this.glTarget = TextureTarget.Texture3D;

            GL.GenTextures(1, out this.glTexture);
            GraphicsExtensions.CheckGLError();

            GL.BindTexture(glTarget, glTexture);
            GraphicsExtensions.CheckGLError();

            format.GetGLFormat(out glInternalFormat, out glFormat, out glType);

            GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero);
            GraphicsExtensions.CheckGLError();

            if (mipMap)
            {
                throw new NotImplementedException("Texture3D does not yet support mipmaps.");
            }
#elif DIRECTX
            if (mipMap)
            {
                this.levelCount = CalculateMipLevels(width, height, depth);
            }

            var description = new Texture3DDescription
            {
                Width          = width,
                Height         = height,
                Depth          = depth,
                MipLevels      = levelCount,
                Format         = SharpDXHelper.ToFormat(format),
                BindFlags      = BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.None,
                Usage          = ResourceUsage.Default,
                OptionFlags    = ResourceOptionFlags.None,
            };

            _texture = new SharpDX.Direct3D11.Texture3D(graphicsDevice._d3dDevice, description);
#endif
        }
示例#12
0
        private unsafe void PlatformGetData(
            CubeMapFace cubeMapFace, int level, Rectangle rect, Span <byte> destination)
        {
            // Create a temp staging resource for copying the data.
            //
            // TODO: Like in Texture2D, we should probably be pooling these staging resources
            // and not creating a new one each time.

            var min       = Format.IsCompressedFormat() ? 4 : 1;
            var levelSize = Math.Max(Size >> level, min);

            var desc = new Texture2DDescription
            {
                Width             = levelSize,
                Height            = levelSize,
                MipLevels         = 1,
                ArraySize         = 1,
                Format            = SharpDXHelper.ToFormat(Format),
                SampleDescription = new SampleDescription(1, 0),
                BindFlags         = BindFlags.None,
                CpuAccessFlags    = CpuAccessFlags.Read,
                Usage             = ResourceUsage.Staging,
                OptionFlags       = ResourceOptionFlags.None,
            };

            var subresourceIndex = CalculateSubresourceIndex(cubeMapFace, level);
            var columns          = rect.Width;
            var rows             = rect.Height;
            var region           = new ResourceRegion(rect.Left, rect.Top, 0, rect.Right, rect.Bottom, 1);

            var d3dContext = GraphicsDevice._d3dContext;

            using (var stagingTex = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, desc))
            {
                lock (d3dContext)
                {
                    // Copy the data from the GPU to the staging texture.
                    d3dContext.CopySubresourceRegion(GetTexture(), subresourceIndex, region, stagingTex, 0);

                    var elementSize = Format.GetSize();
                    if (Format.IsCompressedFormat())
                    {
                        // for 4x4 block compression formats an element is one block, so elementsInRow
                        // and number of rows are 1/4 of number of pixels in width and height of the rectangle
                        columns /= 4;
                        rows    /= 4;
                    }

                    var box = d3dContext.MapSubresource(stagingTex, 0, MapMode.Read, MapFlags.None);
                    GraphicsDevice.CopyResourceTo(Format, box, columns, rows, destination);
                }
            }
        }
示例#13
0
        private void GenerateIfRequired()
        {
            if (_renderTargetView != null)
            {
                return;
            }

            // Create a view interface on the rendertarget to use on bind.
            _renderTargetView = new RenderTargetView(GraphicsDevice._d3dDevice, GetTexture());

            // If we don't need a depth buffer then we're done.
            if (DepthStencilFormat == DepthFormat.None)
            {
                return;
            }

            // Setup the multisampling description.
            var multisampleDesc = new SharpDX.DXGI.SampleDescription(1, 0);

            if (MultiSampleCount > 1)
            {
                multisampleDesc.Count   = MultiSampleCount;
                multisampleDesc.Quality = (int)StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            // Create a descriptor for the depth/stencil buffer.
            // Allocate a 2-D surface as the depth/stencil buffer.
            // Create a DepthStencil view on this surface to use on bind.
            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, new Texture2DDescription
            {
                Format = SharpDXHelper.ToFormat(DepthStencilFormat),
                ArraySize = 1,
                MipLevels = 1,
                Width = width,
                Height = height,
                SampleDescription = multisampleDesc,
                BindFlags = BindFlags.DepthStencil,
            }))
            {
                // Create the view for binding to the device.
                _depthStencilView = new DepthStencilView(GraphicsDevice._d3dDevice, depthBuffer,
                                                         new DepthStencilViewDescription()
                {
                    Format    = SharpDXHelper.ToFormat(DepthStencilFormat),
                    Dimension = DepthStencilViewDimension.Texture2D
                });
            }
        }
示例#14
0
        private int GetMaxMultiSampleCount(GraphicsDevice device)
        {
            var format        = SharpDXHelper.ToFormat(device.PresentationParameters.BackBufferFormat);
            var qualityLevels = 0;
            var maxLevel      = 32;

            while (maxLevel > 0)
            {
                qualityLevels = ((SharpDX.Direct3D11.Device)device.Handle).CheckMultisampleQualityLevels(format, maxLevel);
                if (qualityLevels > 0)
                {
                    break;
                }
                maxLevel /= 2;
            }
            return(maxLevel);
        }
        public RenderTarget3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage)
            : base(graphicsDevice, width, height, depth, mipMap, preferredFormat, true)
        {
            DepthStencilFormat = preferredDepthFormat;
            MultiSampleCount   = preferredMultiSampleCount;
            RenderTargetUsage  = usage;

            // If we don't need a depth buffer then we're done.
            if (preferredDepthFormat == DepthFormat.None)
            {
                return;
            }

#if DIRECTX
            // Setup the multisampling description.
            var multisampleDesc = new SharpDX.DXGI.SampleDescription(1, 0);
            if (preferredMultiSampleCount > 1)
            {
                multisampleDesc.Count   = preferredMultiSampleCount;
                multisampleDesc.Quality = (int)StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            // Create a descriptor for the depth/stencil buffer.
            // Allocate a 2-D surface as the depth/stencil buffer.
            // Create a DepthStencil view on this surface to use on bind.
            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, new Texture2DDescription
            {
                Format = SharpDXHelper.ToFormat(preferredDepthFormat),
                ArraySize = 1,
                MipLevels = 1,
                Width = width,
                Height = height,
                SampleDescription = multisampleDesc,
                BindFlags = BindFlags.DepthStencil,
            }))
            {
                // Create the view for binding to the device.
                _depthStencilView = new DepthStencilView(graphicsDevice._d3dDevice, depthBuffer, new DepthStencilViewDescription()
                {
                    Format    = SharpDXHelper.ToFormat(preferredDepthFormat),
                    Dimension = DepthStencilViewDimension.Texture2D
                });
            }
#endif // DIRECTX
        }
        private int GetMaxMultiSampleCount(GraphicsDevice device)
        {
            var format = SharpDXHelper.ToFormat(device.PresentationParameters.BackBufferFormat);
            // Find the maximum supported level starting with the game's requested multisampling level
            // and halving each time until reaching 0 (meaning no multisample support).
            var qualityLevels = 0;
            var maxLevel      = MultiSampleCountLimit;

            while (maxLevel > 0)
            {
                qualityLevels = device._d3dDevice.CheckMultisampleQualityLevels(format, maxLevel);
                if (qualityLevels > 0)
                {
                    break;
                }
                maxLevel /= 2;
            }
            return(maxLevel);
        }
        public SwapChainRenderTarget(
            GraphicsDevice graphicsDevice, IntPtr windowHandle,
            int width, int height, bool mipMap, SurfaceFormat surfaceFormat,
            DepthFormat depthFormat, int preferredMultiSampleCount,
            RenderTargetUsage usage, PresentInterval presentInterval) :

            base(graphicsDevice, width, height, mipMap, surfaceFormat,
                 depthFormat, preferredMultiSampleCount,
                 usage, SurfaceType.SwapChainRenderTarget)
        {
            var dxgiFormat = surfaceFormat == SurfaceFormat.Rgba32
                ? SharpDX.DXGI.Format.B8G8R8A8_UNorm : SharpDXHelper.ToFormat(surfaceFormat);

            var multisampleDesc = GraphicsDevice.GetSupportedSampleDescription(dxgiFormat, MultiSampleCount);

            _windowHandle   = windowHandle;
            PresentInterval = presentInterval;

            SwapChainRenderTargetConstruct(depthFormat, ref dxgiFormat, ref multisampleDesc);
        }
        private void SwapChainRenderTargetConstruct(
            DepthFormat depthFormat, ref Format dxgiFormat, ref SampleDescription multisampleDesc)
        {
            var backBuffer = CreateSwaipChainTexture(dxgiFormat, multisampleDesc);

            // Once the desired swap chain description is configured, it must
            // be created on the same adapter as our D3D Device
            var d3dDevice = GraphicsDevice._d3dDevice;

            // Create a view interface on the rendertarget to use on bind.
            _renderTargetViews = new[] { new RenderTargetView(d3dDevice, backBuffer) };

            // Get the rendertarget dimensions for later.
            var backBufferDesc = backBuffer.Description;
            var targetSize     = new Point(backBufferDesc.Width, backBufferDesc.Height);

            // Create the depth buffer if we need it.
            if (depthFormat != DepthFormat.None)
            {
                dxgiFormat = SharpDXHelper.ToFormat(depthFormat);

                // Allocate a 2-D surface as the depth/stencil buffer.
                var textureDescription = new Texture2DDescription()
                {
                    Format            = dxgiFormat,
                    ArraySize         = 1,
                    MipLevels         = 1,
                    Width             = targetSize.X,
                    Height            = targetSize.Y,
                    SampleDescription = multisampleDesc,
                    Usage             = ResourceUsage.Default,
                    BindFlags         = BindFlags.DepthStencil,
                };
                using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(d3dDevice, textureDescription))
                {
                    // Create a DepthStencil view on this surface to use on bind.
                    _depthStencilView = new DepthStencilView(d3dDevice, depthBuffer);
                }
            }
        }
        RenderTargetView IRenderTarget.GetRenderTargetView(int arraySlice)
        {
            if (arraySlice >= Depth)
            {
                throw new ArgumentOutOfRangeException("The arraySlice is out of range for this Texture3D.");
            }

            // Dispose the previous target.
            if (_currentSlice != arraySlice && _renderTargetView != null)
            {
                _renderTargetView.Dispose();
                _renderTargetView = null;
            }

            // Create the new target view interface.
            if (_renderTargetView == null)
            {
                _currentSlice = arraySlice;

                var desc = new RenderTargetViewDescription
                {
                    Format    = SharpDXHelper.ToFormat(_format),
                    Dimension = RenderTargetViewDimension.Texture3D,
                    Texture3D =
                    {
                        DepthSliceCount =         -1,
                        FirstDepthSlice = arraySlice,
                        MipSlice        =          0,
                    }
                };

                _renderTargetView = new RenderTargetView(GraphicsDevice._d3dDevice, GetTexture(), desc);
            }

            return(_renderTargetView);
        }
示例#20
0
 protected internal override SampleDescription CreateSampleDescription()
 {
     return(this.GraphicsDevice.GetSupportedSampleDescription
                (SharpDXHelper.ToFormat(this._format), this.MultiSampleCount));
 }
示例#21
0
        protected Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format, bool renderTarget)
        {
            if (graphicsDevice == null)
            {
                throw new ArgumentNullException("graphicsDevice");
            }

            this.GraphicsDevice = graphicsDevice;
            this.width          = width;
            this.height         = height;
            this.depth          = depth;
            this._levelCount    = 1;
            this._format        = format;

#if OPENGL
            this.glTarget = TextureTarget.Texture3D;

            GL.GenTextures(1, out this.glTexture);
            GraphicsExtensions.CheckGLError();

            GL.BindTexture(glTarget, glTexture);
            GraphicsExtensions.CheckGLError();

            format.GetGLFormat(out glInternalFormat, out glFormat, out glType);

            GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero);
            GraphicsExtensions.CheckGLError();

            if (mipMap)
            {
                throw new NotImplementedException("Texture3D does not yet support mipmaps.");
            }
#elif DIRECTX
            if (mipMap)
            {
                this._levelCount = CalculateMipLevels(width, height, depth);
            }

            var description = new Texture3DDescription
            {
                Width          = width,
                Height         = height,
                Depth          = depth,
                MipLevels      = _levelCount,
                Format         = SharpDXHelper.ToFormat(format),
                BindFlags      = BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.None,
                Usage          = ResourceUsage.Default,
                OptionFlags    = ResourceOptionFlags.None,
            };

            if (renderTarget)
            {
                description.BindFlags |= BindFlags.RenderTarget;
                if (mipMap)
                {
                    // Note: XNA 4 does not have a method Texture.GenerateMipMaps()
                    // because generation of mipmaps is not supported on the Xbox 360.
                    // TODO: New method Texture.GenerateMipMaps() required.
                    description.OptionFlags |= ResourceOptionFlags.GenerateMipMaps;
                }
            }

            _texture = new SharpDX.Direct3D11.Texture3D(graphicsDevice._d3dDevice, description);
#endif
        }
        private void PlatformGetData <T>(CubeMapFace cubeMapFace, int level, Rectangle rect, T[] data, int startIndex, int elementCount) where T : struct
        {
            // Create a temp staging resource for copying the data.
            //
            // TODO: Like in Texture2D, we should probably be pooling these staging resources
            // and not creating a new one each time.
            //
            var min       = _format.IsCompressedFormat() ? 4 : 1;
            var levelSize = Math.Max(size >> level, min);

            var desc = new Texture2DDescription
            {
                Width             = levelSize,
                Height            = levelSize,
                MipLevels         = 1,
                ArraySize         = 1,
                Format            = SharpDXHelper.ToFormat(_format),
                SampleDescription = new SampleDescription(1, 0),
                BindFlags         = BindFlags.None,
                CpuAccessFlags    = CpuAccessFlags.Read,
                Usage             = ResourceUsage.Staging,
                OptionFlags       = ResourceOptionFlags.None,
            };

            var d3dContext = GraphicsDevice._d3dContext;

            using (var stagingTex = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, desc))
            {
                lock (d3dContext)
                {
                    // Copy the data from the GPU to the staging texture.
                    var subresourceIndex = CalculateSubresourceIndex(cubeMapFace, level);
                    var elementsInRow    = rect.Width;
                    var rows             = rect.Height;
                    var region           = new ResourceRegion(rect.Left, rect.Top, 0, rect.Right, rect.Bottom, 1);
                    d3dContext.CopySubresourceRegion(GetTexture(), subresourceIndex, region, stagingTex, 0);

                    // Copy the data to the array.
                    DataStream stream = null;
                    try
                    {
                        var databox = d3dContext.MapSubresource(stagingTex, 0, MapMode.Read, MapFlags.None, out stream);

                        var elementSize = _format.GetSize();
                        if (_format.IsCompressedFormat())
                        {
                            // for 4x4 block compression formats an element is one block, so elementsInRow
                            // and number of rows are 1/4 of number of pixels in width and height of the rectangle
                            elementsInRow /= 4;
                            rows          /= 4;
                        }
                        var rowSize = elementSize * elementsInRow;
                        if (rowSize == databox.RowPitch)
                        {
                            stream.ReadRange(data, startIndex, elementCount);
                        }
                        else
                        {
                            // Some drivers may add pitch to rows.
                            // We need to copy each row separatly and skip trailing zeros.
                            stream.Seek(0, SeekOrigin.Begin);

                            var elementSizeInByte = ReflectionHelpers.SizeOf <T> .Get();

                            for (var row = 0; row < rows; row++)
                            {
                                int i;
                                for (i = row * rowSize / elementSizeInByte; i < (row + 1) * rowSize / elementSizeInByte; i++)
                                {
                                    data[i + startIndex] = stream.Read <T>();
                                }

                                if (i >= elementCount)
                                {
                                    break;
                                }

                                stream.Seek(databox.RowPitch - rowSize, SeekOrigin.Current);
                            }
                        }
                    }
                    finally
                    {
                        SharpDX.Utilities.Dispose(ref stream);
                    }
                }
            }
        }
示例#23
0
		public void GetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
        {
            if (data == null || data.Length == 0)
                throw new ArgumentException("data cannot be null");
            if (data.Length < startIndex + elementCount)
                throw new ArgumentException("The data passed has a length of " + data.Length + " but " + elementCount + " pixels have been requested.");

#if IOS

            // Reading back a texture from GPU memory is unsupported
            // in OpenGL ES 2.0 and no work around has been implemented.           
            throw new NotSupportedException("OpenGL ES 2.0 does not support texture reads.");

#elif ANDROID

            Rectangle r;
            if (rect != null)
            {
                r = rect.Value;
            }
            else
            {
                r = new Rectangle(0, 0, Width, Height);
            }
            			
			// Get the Color values
			if (typeof(T) == typeof(uint))
			{
				Color[] colors = new Color[elementCount];
				GetData<Color>(level, rect, colors, startIndex, elementCount);
				uint[] final = data as uint[];
				for (int i = 0; i < final.Length; i++)
				{
					final[i] = (uint)
					(
						// use correct xna byte order (and remember to convert it yourself as needed)
						colors[i].A << 24 |
						colors[i].B << 16 |
						colors[i].G << 8 |
						colors[i].R
					);
				}
			}
            // Get the Color values
            else if ((typeof(T) == typeof(Color)))
            {
				byte[] imageInfo = GetTextureData(0);

                int rWidth = r.Width;
                int rHeight = r.Height;
                
                // Loop through and extract the data but we need to load it 
                var dataRowColOffset = 0;
                var sz = 0;
                var pixelOffset = 0;
                for (int y = r.Top; y < rHeight; y++)
                {
                    for (int x = r.Left; x < rWidth; x++)
                    {
                        var result = new Color(0, 0, 0, 0);
                        dataRowColOffset = ((y * r.Width) + x);
                        switch (Format)
                        {
                            case SurfaceFormat.Color: //kTexture2DPixelFormat_RGBA8888
                            case SurfaceFormat.Dxt3:
                                sz = 4;
                                pixelOffset = dataRowColOffset * sz;
                                result.R = imageInfo[pixelOffset];
                                result.G = imageInfo[pixelOffset + 1];
                                result.B = imageInfo[pixelOffset + 2];
                                result.A = imageInfo[pixelOffset + 3];
                                break;
                            case SurfaceFormat.Bgra4444: //kTexture2DPixelFormat_RGBA4444
                                //								sz = 2;
                                //								pos = ((y * imageSize.Width) + x) * sz;
                                //								pixelOffset = new IntPtr (imageData.ToInt64 () + pos);
                                //	
                                //								Marshal.Copy (pixelOffset, pixel, 0, 4);	
                                //	
                                //								result.R = pixel [0];
                                //								result.G = pixel [1];
                                //								result.B = pixel [2];
                                //								result.A = pixel [3];
                                sz = 2;
                                pixelOffset = dataRowColOffset * sz;
                                result.R = imageInfo[pixelOffset];
                                result.G = imageInfo[pixelOffset + 1];
                                result.B = imageInfo[pixelOffset + 2];
                                result.A = imageInfo[pixelOffset + 3];
                                break;
                            case SurfaceFormat.Bgra5551: //kTexture2DPixelFormat_RGB5A1
                                //								sz = 2;
                                //								pos = ((y * imageSize.Width) + x) * sz;
                                //								pixelOffset = new IntPtr (imageData.ToInt64 () + pos);
                                //								Marshal.Copy (pixelOffset, pixel, 0, 4);	
                                //	
                                //								result.R = pixel [0];
                                //								result.G = pixel [1];
                                //								result.B = pixel [2];
                                //								result.A = pixel [3];
                                sz = 2;
                                pixelOffset = dataRowColOffset * sz;
                                result.R = imageInfo[pixelOffset];
                                result.G = imageInfo[pixelOffset + 1];
                                result.B = imageInfo[pixelOffset + 2];
                                result.A = imageInfo[pixelOffset + 3];
                                break;
                            case SurfaceFormat.Alpha8:  // kTexture2DPixelFormat_A8 
                                //								sz = 1;
                                //								pos = ((y * imageSize.Width) + x) * sz;
                                //								pixelOffset = new IntPtr (imageData.ToInt64 () + pos);								
                                //								Marshal.Copy (pixelOffset, pixel, 0, 4);	
                                //	
                                //								result.A = pixel [0];
                                sz = 1;
                                pixelOffset = dataRowColOffset * sz;
                                result.A = imageInfo[pixelOffset];
                                break;
                            default:
                                throw new NotSupportedException("Texture format");
                        }
                        data[dataRowColOffset] = (T)(object)result;
                    }                    
                }
            }
            else
            {
                throw new NotImplementedException("GetData not implemented for type.");
            }
#elif PSM
            Rectangle r;
            if (rect.HasValue)
            {
                r = rect.Value;
            }
            else
            {
                r = new Rectangle(0, 0, Width, Height);
            }
            
            int rWidth = r.Width;
            int rHeight = r.Height;
            
            var sz = 4;         
            
            // Loop through and extract the data but we need to load it 
            var dataRowColOffset = 0;
            
            var pixelOffset = 0;
            var result = new Color(0, 0, 0, 0);
            
            byte[] imageInfo = new byte[(rWidth * rHeight) * sz];
            
            ImageRect old_scissor = GraphicsDevice.Context.GetScissor();
            ImageRect old_viewport = GraphicsDevice.Context.GetViewport();
            FrameBuffer old_frame_buffer = GraphicsDevice.Context.GetFrameBuffer();

            ColorBuffer color_buffer = new ColorBuffer(rWidth, rHeight, PixelFormat.Rgba);
            FrameBuffer frame_buffer = new FrameBuffer();
            frame_buffer.SetColorTarget(color_buffer);
             
            GraphicsDevice.Context.SetFrameBuffer(frame_buffer);

            GraphicsDevice.Context.SetTexture(0, this._texture2D);
            GraphicsDevice.Context.ReadPixels(imageInfo, PixelFormat.Rgba, 0, 0, rWidth, rHeight);

            GraphicsDevice.Context.SetFrameBuffer(old_frame_buffer);
            GraphicsDevice.Context.SetScissor(old_scissor);
            GraphicsDevice.Context.SetViewport(old_viewport);
            
            for (int y = r.Top; y < rHeight; y++)
            {
                for (int x = r.Left; x < rWidth; x++)
                {
                    dataRowColOffset = ((y * r.Width) + x);
                    
                    pixelOffset = dataRowColOffset * sz;
                    result.R = imageInfo[pixelOffset];
                    result.G = imageInfo[pixelOffset + 1];
                    result.B = imageInfo[pixelOffset + 2];
                    result.A = imageInfo[pixelOffset + 3];
                    
                    data[dataRowColOffset] = (T)(object)result;
                }
            }

#elif DIRECTX

            // Create a temp staging resource for copying the data.
            // 
            // TODO: We should probably be pooling these staging resources
            // and not creating a new one each time.
            //
            var desc = new SharpDX.Direct3D11.Texture2DDescription();
            desc.Width = width;
            desc.Height = height;
            desc.MipLevels = 1;
            desc.ArraySize = 1;
            desc.Format = SharpDXHelper.ToFormat(_format);
            desc.BindFlags = SharpDX.Direct3D11.BindFlags.None;
            desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Read;
            desc.SampleDescription.Count = 1;
            desc.SampleDescription.Quality = 0;
            desc.Usage = SharpDX.Direct3D11.ResourceUsage.Staging;
            desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;

		    var d3dContext = GraphicsDevice._d3dContext;
            using (var stagingTex = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, desc))
                lock (d3dContext)
                {
                    // Copy the data from the GPU to the staging texture.
                    int elementsInRow;
                    int rows;
                    if (rect.HasValue)
                    {
                        elementsInRow = rect.Value.Width;
                        rows = rect.Value.Height;
                        d3dContext.CopySubresourceRegion(GetTexture(), level, new SharpDX.Direct3D11.ResourceRegion(rect.Value.Left, rect.Value.Top, 0, rect.Value.Right, rect.Value.Bottom, 1), stagingTex, 0, 0, 0, 0);
                    }
                    else
                    {
                        elementsInRow = width;
                        rows = height;
                        d3dContext.CopySubresourceRegion(GetTexture(), level, null, stagingTex, 0, 0, 0, 0);
                    }

                    // Copy the data to the array.
                    SharpDX.DataStream stream;
                    var databox = d3dContext.MapSubresource(stagingTex, 0, SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out stream);

                    // Some drivers may add pitch to rows.
                    // We need to copy each row separatly and skip trailing zeros.
                    var currentIndex = startIndex;
                    var elementSize = SharpDX.Utilities.SizeOf<T>();
                    for (var row = 0; row < rows; row++)
                    {
                        stream.ReadRange(data, currentIndex, elementsInRow);
                        stream.Seek(databox.RowPitch - (elementSize * elementsInRow), SeekOrigin.Current);
                        currentIndex += elementsInRow;
                    }
                    stream.Dispose();
                }

#else

			GL.BindTexture(TextureTarget.Texture2D, this.glTexture);

			if (glFormat == (GLPixelFormat)All.CompressedTextureFormats) {
				throw new NotImplementedException();
			} else {
				if (rect.HasValue) {
					var temp = new T[this.width*this.height];
					GL.GetTexImage(TextureTarget.Texture2D, level, this.glFormat, this.glType, temp);
					int z = 0, w = 0;

					for(int y= rect.Value.Y; y < rect.Value.Y+ rect.Value.Height; y++) {
						for(int x=rect.Value.X; x < rect.Value.X + rect.Value.Width; x++) {
							data[z*rect.Value.Width+w] = temp[(y*width)+x];
							w++;
						}
						z++;
					}
				} else {
					GL.GetTexImage(TextureTarget.Texture2D, level, this.glFormat, this.glType, data);
				}
			}

#endif
        }
示例#24
0
        public RenderTarget2D(GraphicsDevice graphicsDevice, int width, int height, bool mipMap, SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage)
            : base(graphicsDevice, width, height, mipMap, preferredFormat, true)
        {
            DepthStencilFormat = preferredDepthFormat;
            MultiSampleCount   = preferredMultiSampleCount;
            RenderTargetUsage  = usage;

#if DIRECTX
            // Create a view interface on the rendertarget to use on bind.
            _renderTargetView = new SharpDX.Direct3D11.RenderTargetView(graphicsDevice._d3dDevice, _texture);
#endif

            // If we don't need a depth buffer then we're done.
            if (preferredDepthFormat == DepthFormat.None)
            {
                return;
            }

#if DIRECTX
            // Setup the multisampling description.
            var multisampleDesc = new SharpDX.DXGI.SampleDescription(1, 0);
            if (preferredMultiSampleCount > 1)
            {
                multisampleDesc.Count   = preferredMultiSampleCount;
                multisampleDesc.Quality = (int)SharpDX.Direct3D11.StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            // Create a descriptor for the depth/stencil buffer.
            // Allocate a 2-D surface as the depth/stencil buffer.
            // Create a DepthStencil view on this surface to use on bind.
            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, new SharpDX.Direct3D11.Texture2DDescription()
            {
                Format = SharpDXHelper.ToFormat(preferredDepthFormat),
                ArraySize = 1,
                MipLevels = 1,
                Width = width,
                Height = height,
                SampleDescription = multisampleDesc,
                BindFlags = SharpDX.Direct3D11.BindFlags.DepthStencil,
            }))

                // Create the view for binding to the device.
                _depthStencilView = new SharpDX.Direct3D11.DepthStencilView(graphicsDevice._d3dDevice, depthBuffer,
                                                                            new SharpDX.Direct3D11.DepthStencilViewDescription()
                {
                    Format    = SharpDXHelper.ToFormat(preferredDepthFormat),
                    Dimension = SharpDX.Direct3D11.DepthStencilViewDimension.Texture2D
                });
#elif OPENGL
#if GLES
            GL.GenRenderbuffers(1, ref glDepthStencilBuffer);
#else
            GL.GenRenderbuffers(1, out glDepthStencilBuffer);
#endif
            GraphicsExtensions.CheckGLError();
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, this.glDepthStencilBuffer);
            GraphicsExtensions.CheckGLError();
            var glDepthStencilFormat = GLDepthComponent16;
            switch (preferredDepthFormat)
            {
            case DepthFormat.Depth16: glDepthStencilFormat = GLDepthComponent16; break;

            case DepthFormat.Depth24: glDepthStencilFormat = GLDepthComponent24; break;

            case DepthFormat.Depth24Stencil8: glDepthStencilFormat = GLDepth24Stencil8; break;
            }
            GL.RenderbufferStorage(GLRenderbuffer, glDepthStencilFormat, this.width, this.height);
            GraphicsExtensions.CheckGLError();
#endif
        }
        public SwapChainRenderTarget(GraphicsDevice graphicsDevice,
                                     IntPtr windowHandle,
                                     int width,
                                     int height,
                                     bool mipMap,
                                     SurfaceFormat surfaceFormat,
                                     DepthFormat depthFormat,
                                     int preferredMultiSampleCount,
                                     RenderTargetUsage usage,
                                     PresentInterval presentInterval)
            : base(
                graphicsDevice,
                width,
                height,
                mipMap,
                surfaceFormat,
                depthFormat,
                preferredMultiSampleCount,
                usage,
                SurfaceType.SwapChainRenderTarget)
        {
            var dxgiFormat = surfaceFormat == SurfaceFormat.Color
                             ? SharpDX.DXGI.Format.B8G8R8A8_UNorm
                             : SharpDXHelper.ToFormat(surfaceFormat);

            var multisampleDesc = new SampleDescription(1, 0);

            if (preferredMultiSampleCount > 1)
            {
                multisampleDesc.Count   = preferredMultiSampleCount;
                multisampleDesc.Quality = (int)StandardMultisampleQualityLevels.StandardMultisamplePattern;
            }

            var desc = new SwapChainDescription()
            {
                ModeDescription =
                {
                    Format  = dxgiFormat,
                    Scaling = DisplayModeScaling.Stretched,
                    Width   = width,
                    Height  = height,
                },

                OutputHandle      = windowHandle,
                SampleDescription = multisampleDesc,
                Usage             = Usage.RenderTargetOutput,
                BufferCount       = 2,
                SwapEffect        = SharpDXHelper.ToSwapEffect(presentInterval),
                IsWindowed        = true,
            };

            PresentInterval = presentInterval;

            // Once the desired swap chain description is configured, it must
            // be created on the same adapter as our D3D Device
            var d3dDevice = graphicsDevice._d3dDevice;

            // First, retrieve the underlying DXGI Device from the D3D Device.
            // Creates the swap chain
            using (var dxgiDevice = d3dDevice.QueryInterface <SharpDX.DXGI.Device1>())
                using (var dxgiAdapter = dxgiDevice.Adapter)
                    using (var dxgiFactory = dxgiAdapter.GetParent <Factory1>())
                    {
                        _swapChain = new SwapChain(dxgiFactory, dxgiDevice, desc);
                    }

            // Obtain the backbuffer for this window which will be the final 3D rendertarget.
            var backBuffer = SharpDX.Direct3D11.Resource.FromSwapChain <SharpDX.Direct3D11.Texture2D>(_swapChain, 0);

            // Create a view interface on the rendertarget to use on bind.
            _renderTargetViews = new[] { new RenderTargetView(d3dDevice, backBuffer) };

            // Get the rendertarget dimensions for later.
            var backBufferDesc = backBuffer.Description;
            var targetSize     = new Point(backBufferDesc.Width, backBufferDesc.Height);

            _texture = backBuffer;

            // Create the depth buffer if we need it.
            if (depthFormat != DepthFormat.None)
            {
                dxgiFormat = SharpDXHelper.ToFormat(depthFormat);

                // Allocate a 2-D surface as the depth/stencil buffer.
                using (
                    var depthBuffer = new SharpDX.Direct3D11.Texture2D(d3dDevice,
                                                                       new Texture2DDescription()
                {
                    Format = dxgiFormat,
                    ArraySize = 1,
                    MipLevels = 1,
                    Width = targetSize.X,
                    Height = targetSize.Y,
                    SampleDescription = multisampleDesc,
                    Usage = ResourceUsage.Default,
                    BindFlags = BindFlags.DepthStencil,
                }))

                    // Create a DepthStencil view on this surface to use on bind.
                    _depthStencilView = new DepthStencilView(d3dDevice, depthBuffer);
            }
        }
示例#26
0
        protected Texture2D(GraphicsDevice graphicsDevice, int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared)
		{
            if (graphicsDevice == null)
                throw new ArgumentNullException("Graphics Device Cannot Be Null");

            this.GraphicsDevice = graphicsDevice;
            this.width = width;
            this.height = height;
            this._format = format;
            this._levelCount = mipmap ? CalculateMipLevels(width, height) : 1;

            // Texture will be assigned by the swap chain.
		    if (type == SurfaceType.SwapChainRenderTarget)
		        return;

#if DIRECTX
            // TODO: Move this to SetData() if we want to make Immutable textures!
            var desc = new SharpDX.Direct3D11.Texture2DDescription();
            desc.Width = width;
            desc.Height = height;
            desc.MipLevels = _levelCount;
            desc.ArraySize = 1;
            desc.Format = SharpDXHelper.ToFormat(format);
            desc.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource;
            desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;
            desc.SampleDescription.Count = 1;
            desc.SampleDescription.Quality = 0;
            desc.Usage = SharpDX.Direct3D11.ResourceUsage.Default;
            desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;

            if (type == SurfaceType.RenderTarget)
            {
                desc.BindFlags |= SharpDX.Direct3D11.BindFlags.RenderTarget;
                if (mipmap)
                {
                    // Note: XNA 4 does not have a method Texture.GenerateMipMaps() 
                    // because generation of mipmaps is not supported on the Xbox 360.
                    // TODO: New method Texture.GenerateMipMaps() required.
                    desc.OptionFlags |= SharpDX.Direct3D11.ResourceOptionFlags.GenerateMipMaps;
                }
            }

            if (shared)
                desc.OptionFlags |= SharpDX.Direct3D11.ResourceOptionFlags.Shared;

            _texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, desc);

#elif PSM
            PixelBufferOption option = PixelBufferOption.None;
            if (type == SurfaceType.RenderTarget)
			    option = PixelBufferOption.Renderable;
            _texture2D = new Sce.PlayStation.Core.Graphics.Texture2D(width, height, mipmap, PSSHelper.ToFormat(format),option);
#else

            this.glTarget = TextureTarget.Texture2D;
            
            Threading.BlockOnUIThread(() =>
            {
                // Store the current bound texture.
                var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                GenerateGLTextureIfRequired();

                format.GetGLFormat(out glInternalFormat, out glFormat, out glType);

                if (glFormat == (GLPixelFormat)All.CompressedTextureFormats)
                {
                    var imageSize = 0;
                    switch (format)
                    {
                        case SurfaceFormat.RgbPvrtc2Bpp:
                        case SurfaceFormat.RgbaPvrtc2Bpp:
                            imageSize = (Math.Max(this.width, 8) * Math.Max(this.height, 8) * 2 + 7) / 8;
                            break;
                        case SurfaceFormat.RgbPvrtc4Bpp:
                        case SurfaceFormat.RgbaPvrtc4Bpp:
                            imageSize = (Math.Max(this.width, 16) * Math.Max(this.height, 8) * 4 + 7) / 8;
                            break;
                        case SurfaceFormat.Dxt1:
                        case SurfaceFormat.Dxt1a:
                        case SurfaceFormat.Dxt3:
                        case SurfaceFormat.Dxt5:
                            imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * format.Size();
                            break;
                        default:
                            throw new NotImplementedException();
                    }

                    GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, glInternalFormat,
                                            this.width, this.height, 0,
                                            imageSize, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0,
#if IOS || ANDROID
                        (int)glInternalFormat,
#else				           
					    glInternalFormat,
#endif
                        this.width, this.height, 0,
                        glFormat, glType, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }

                // Restore the bound texture.
                GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                GraphicsExtensions.CheckGLError();
            });
#endif
        }
示例#27
0
        private void GenerateIfRequired()
        {
            if (_renderTargetViews != null)
            {
                return;
            }

            var viewTex = MultiSampleCount > 1 ? GetMSTexture() : GetTexture();

            // Create a view interface on the rendertarget to use on bind.
            if (ArraySize > 1)
            {
                _renderTargetViews = new RenderTargetView[ArraySize];
                for (var i = 0; i < ArraySize; i++)
                {
                    var renderTargetViewDescription = new RenderTargetViewDescription();
                    if (MultiSampleCount > 1)
                    {
                        renderTargetViewDescription.Dimension = RenderTargetViewDimension.Texture2DMultisampledArray;
                        renderTargetViewDescription.Texture2DMSArray.ArraySize       = 1;
                        renderTargetViewDescription.Texture2DMSArray.FirstArraySlice = i;
                    }
                    else
                    {
                        renderTargetViewDescription.Dimension = RenderTargetViewDimension.Texture2DArray;
                        renderTargetViewDescription.Texture2DArray.ArraySize       = 1;
                        renderTargetViewDescription.Texture2DArray.FirstArraySlice = i;
                        renderTargetViewDescription.Texture2DArray.MipSlice        = 0;
                    }
                    _renderTargetViews[i] = new RenderTargetView(
                        GraphicsDevice._d3dDevice, viewTex, renderTargetViewDescription);
                }
            }
            else
            {
                _renderTargetViews = new[] { new RenderTargetView(GraphicsDevice._d3dDevice, viewTex) };
            }

            // If we don't need a depth buffer then we're done.
            if (DepthStencilFormat == DepthFormat.None)
            {
                return;
            }

            // The depth stencil view's multisampling configuration must strictly
            // match the texture's multisampling configuration.  Ignore whatever parameters
            // were provided and use the texture's configuration so that things are
            // guarenteed to work.
            var multisampleDesc = _msSampleDescription;

            // Create a descriptor for the depth/stencil buffer.
            // Allocate a 2-D surface as the depth/stencil buffer.
            // Create a DepthStencil view on this surface to use on bind.
            using (var depthBuffer = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, new Texture2DDescription
            {
                Format = SharpDXHelper.ToFormat(DepthStencilFormat),
                ArraySize = 1,
                MipLevels = 1,
                Width = Width,
                Height = Height,
                SampleDescription = multisampleDesc,
                BindFlags = BindFlags.DepthStencil,
            }))
            {
                // Create the view for binding to the device.
                _depthStencilView = new DepthStencilView(GraphicsDevice._d3dDevice, depthBuffer,
                                                         new DepthStencilViewDescription()
                {
                    Format    = SharpDXHelper.ToFormat(DepthStencilFormat),
                    Dimension = MultiSampleCount > 1 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D
                });
            }
        }
示例#28
0
		internal Texture2D(GraphicsDevice graphicsDevice, int width, int height, bool mipmap, SurfaceFormat format, bool renderTarget)
		{
            if (graphicsDevice == null)
                throw new ArgumentNullException("Graphics Device Cannot Be Null");

            this.GraphicsDevice = graphicsDevice;
            this.width = width;
            this.height = height;
            this.format = format;
            this.levelCount = 1;

            if (mipmap)
            {
                int size = Math.Max(this.width, this.height);
                while (size > 1)
                {
                    size = size / 2;
                    this.levelCount++;
                }
            }

#if DIRECTX

            // TODO: Move this to SetData() if we want to make Immutable textures!
            var desc = new SharpDX.Direct3D11.Texture2DDescription();
            desc.Width = width;
            desc.Height = height;
            desc.MipLevels = levelCount;
            desc.ArraySize = 1;
            desc.Format = SharpDXHelper.ToFormat(format);
            desc.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource;
            desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None;
            desc.SampleDescription.Count = 1;
            desc.SampleDescription.Quality = 0;
            desc.Usage = SharpDX.Direct3D11.ResourceUsage.Default;
            desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;

            if (renderTarget)
                desc.BindFlags |= SharpDX.Direct3D11.BindFlags.RenderTarget;

            _texture = new SharpDX.Direct3D11.Texture2D(graphicsDevice._d3dDevice, desc);

#elif PSM
			_texture2D = new Sce.PlayStation.Core.Graphics.Texture2D(width, height, mipmap, PSSHelper.ToFormat(format));
#else

            this.glTarget = TextureTarget.Texture2D;
            
            Threading.BlockOnUIThread(() =>
            {
                // Store the current bound texture.
                var prevTexture = GraphicsExtensions.GetBoundTexture2D();

                GenerateGLTextureIfRequired();

                format.GetGLFormat(out glInternalFormat, out glFormat, out glType);

                if (glFormat == (GLPixelFormat)All.CompressedTextureFormats)
                {
                    var imageSize = 0;
                    switch (format)
                    {
                        case SurfaceFormat.RgbPvrtc2Bpp:
                        case SurfaceFormat.RgbaPvrtc2Bpp:
                            imageSize = (Math.Max(this.width, 8) * Math.Max(this.height, 8) * 2 + 7) / 8;
                            break;
                        case SurfaceFormat.RgbPvrtc4Bpp:
                        case SurfaceFormat.RgbaPvrtc4Bpp:
                            imageSize = (Math.Max(this.width, 16) * Math.Max(this.height, 8) * 4 + 7) / 8;
                            break;
                        case SurfaceFormat.Dxt1:
                            imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * 8 * 1;
                            break;
                        case SurfaceFormat.Dxt3:
                        case SurfaceFormat.Dxt5:
                            imageSize = ((this.width + 3) / 4) * ((this.height + 3) / 4) * 16 * 1;
                            break;
                        default:
                            throw new NotImplementedException();
                    }

                    GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, glInternalFormat,
                                            this.width, this.height, 0,
                                            imageSize, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0,
#if IOS || ANDROID
                        (int)glInternalFormat,
#else				           
					    glInternalFormat,
#endif
                        this.width, this.height, 0,
                        glFormat, glType, IntPtr.Zero);
                    GraphicsExtensions.CheckGLError();
                }

                // Restore the bound texture.
                GL.BindTexture(TextureTarget.Texture2D, prevTexture);
                GraphicsExtensions.CheckGLError();
            });
#endif
        }
示例#29
0
        /// <summary>
        /// Gets a copy of 3D texture data, specifying a mipmap level, source box, start index, and number of elements.
        /// </summary>
        /// <typeparam name="T">The type of the elements in the array.</typeparam>
        /// <param name="level">Mipmap level.</param>
        /// <param name="left">Position of the left side of the box on the x-axis.</param>
        /// <param name="top">Position of the top of the box on the y-axis.</param>
        /// <param name="right">Position of the right side of the box on the x-axis.</param>
        /// <param name="bottom">Position of the bottom of the box on the y-axis.</param>
        /// <param name="front">Position of the front of the box on the z-axis.</param>
        /// <param name="back">Position of the back of the box on the z-axis.</param>
        /// <param name="data">Array of data.</param>
        /// <param name="startIndex">Index of the first element to get.</param>
        /// <param name="elementCount">Number of elements to get.</param>
        public void GetData <T>(int level, int left, int top, int right, int bottom, int front, int back, T[] data, int startIndex, int elementCount) where T : struct
        {
            if (data == null || data.Length == 0)
            {
                throw new ArgumentException("data cannot be null");
            }
            if (data.Length < startIndex + elementCount)
            {
                throw new ArgumentException("The data passed has a length of " + data.Length + " but " + elementCount + " pixels have been requested.");
            }

            // Disallow negative box size
            if ((left < 0 || left >= right) ||
                (top < 0 || top >= bottom) ||
                (front < 0 || front >= back))
            {
                throw new ArgumentException("Neither box size nor box position can be negative");
            }
#if IOS
            // Reading back a texture from GPU memory is unsupported
            // in OpenGL ES 2.0 and no work around has been implemented.
            throw new NotSupportedException("OpenGL ES 2.0 does not support texture reads.");
#elif ANDROID
            throw new NotImplementedException();
#elif PSM
            throw new NotImplementedException();
#elif DIRECTX
            // Create a temp staging resource for copying the data.
            //
            // TODO: Like in Texture2D, we should probably be pooling these staging resources
            // and not creating a new one each time.
            //
            var desc = new Texture3DDescription
            {
                Width          = width,
                Height         = height,
                Depth          = depth,
                MipLevels      = 1,
                Format         = SharpDXHelper.ToFormat(_format),
                BindFlags      = BindFlags.None,
                CpuAccessFlags = CpuAccessFlags.Read,
                Usage          = ResourceUsage.Staging,
                OptionFlags    = ResourceOptionFlags.None,
            };

            var d3dContext = GraphicsDevice._d3dContext;
            using (var stagingTex = new SharpDX.Direct3D11.Texture3D(GraphicsDevice._d3dDevice, desc))
            {
                lock (d3dContext)
                {
                    // Copy the data from the GPU to the staging texture.
                    d3dContext.CopySubresourceRegion(GetTexture(), level, new ResourceRegion(left, top, front, right, bottom, back), stagingTex, 0);

                    // Copy the data to the array.
                    DataStream stream;
                    var        databox = d3dContext.MapSubresource(stagingTex, 0, MapMode.Read, MapFlags.None, out stream);

                    // Some drivers may add pitch to rows or slices.
                    // We need to copy each row separatly and skip trailing zeros.
                    var currentIndex  = startIndex;
                    var elementSize   = SharpDX.Utilities.SizeOf <T>();
                    var elementsInRow = right - left;
                    var rowsInSlice   = bottom - top;
                    for (var slice = front; slice < back; slice++)
                    {
                        for (var row = top; row < bottom; row++)
                        {
                            stream.ReadRange(data, currentIndex, elementsInRow);
                            stream.Seek(databox.RowPitch - (elementSize * elementsInRow), SeekOrigin.Current);
                            currentIndex += elementsInRow;
                        }
                        stream.Seek(databox.SlicePitch - (databox.RowPitch * rowsInSlice), SeekOrigin.Current);
                    }
                    stream.Dispose();
                }
            }
#else
            throw new NotImplementedException();
#endif
        }
示例#30
0
		public void GetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
        {
#if IOS 
			throw new NotImplementedException();
#elif ANDROID
			if (data == null)
            {
                throw new ArgumentException("data cannot be null");
            }

            if (data.Length < startIndex + elementCount)
            {
                throw new ArgumentException("The data passed has a length of " + data.Length + " but " + elementCount + " pixels have been requested.");
            }

            Rectangle r;
            if (rect != null)
            {
                r = rect.Value;
            }
            else
            {
                r = new Rectangle(0, 0, Width, Height);
            }
            			
			// Get the Color values
			if (typeof(T) == typeof(uint))
			{
				Color[] colors = new Color[elementCount];
				GetData<Color>(level, rect, colors, startIndex, elementCount);
				uint[] final = data as uint[];
				for (int i = 0; i < final.Length; i++)
				{
					final[i] = (uint)
					(
						colors[i].R << 24 |
						colors[i].G << 16 |
						colors[i].B << 8 |
						colors[i].A
					);
				}
			}
            // Get the Color values
            else if ((typeof(T) == typeof(Color)))
            {
				byte[] imageInfo = GetTextureData(0);

                int rWidth = r.Width;
                int rHeight = r.Height;
                
                // Loop through and extract the data but we need to load it 
                var dataRowColOffset = 0;
                var sz = 0;
                var pixelOffset = 0;
                for (int y = r.Top; y < rHeight; y++)
                {
                    for (int x = r.Left; x < rWidth; x++)
                    {
                        var result = new Color(0, 0, 0, 0);
                        dataRowColOffset = ((y * r.Width) + x);
                        switch (Format)
                        {
                            case SurfaceFormat.Color: //kTexture2DPixelFormat_RGBA8888
                            case SurfaceFormat.Dxt3:
                                sz = 4;
                                pixelOffset = dataRowColOffset * sz;
                                result.R = imageInfo[pixelOffset];
                                result.G = imageInfo[pixelOffset + 1];
                                result.B = imageInfo[pixelOffset + 2];
                                result.A = imageInfo[pixelOffset + 3];
                                break;
                            case SurfaceFormat.Bgra4444: //kTexture2DPixelFormat_RGBA4444
                                //								sz = 2;
                                //								pos = ((y * imageSize.Width) + x) * sz;
                                //								pixelOffset = new IntPtr (imageData.ToInt64 () + pos);
                                //	
                                //								Marshal.Copy (pixelOffset, pixel, 0, 4);	
                                //	
                                //								result.R = pixel [0];
                                //								result.G = pixel [1];
                                //								result.B = pixel [2];
                                //								result.A = pixel [3];
                                sz = 2;
                                pixelOffset = dataRowColOffset * sz;
                                result.R = imageInfo[pixelOffset];
                                result.G = imageInfo[pixelOffset + 1];
                                result.B = imageInfo[pixelOffset + 2];
                                result.A = imageInfo[pixelOffset + 3];
                                break;
                            case SurfaceFormat.Bgra5551: //kTexture2DPixelFormat_RGB5A1
                                //								sz = 2;
                                //								pos = ((y * imageSize.Width) + x) * sz;
                                //								pixelOffset = new IntPtr (imageData.ToInt64 () + pos);
                                //								Marshal.Copy (pixelOffset, pixel, 0, 4);	
                                //	
                                //								result.R = pixel [0];
                                //								result.G = pixel [1];
                                //								result.B = pixel [2];
                                //								result.A = pixel [3];
                                sz = 2;
                                pixelOffset = dataRowColOffset * sz;
                                result.R = imageInfo[pixelOffset];
                                result.G = imageInfo[pixelOffset + 1];
                                result.B = imageInfo[pixelOffset + 2];
                                result.A = imageInfo[pixelOffset + 3];
                                break;
                            case SurfaceFormat.Alpha8:  // kTexture2DPixelFormat_A8 
                                //								sz = 1;
                                //								pos = ((y * imageSize.Width) + x) * sz;
                                //								pixelOffset = new IntPtr (imageData.ToInt64 () + pos);								
                                //								Marshal.Copy (pixelOffset, pixel, 0, 4);	
                                //	
                                //								result.A = pixel [0];
                                sz = 1;
                                pixelOffset = dataRowColOffset * sz;
                                result.A = imageInfo[pixelOffset];
                                break;
                            default:
                                throw new NotSupportedException("Texture format");
                        }
                        data[dataRowColOffset] = (T)(object)result;
                    }                    
                }
            }
            else
            {
                throw new NotImplementedException("GetData not implemented for type.");
            }
#elif PSM
            throw new NotImplementedException();
#elif DIRECTX

            // Create a temp staging resource for copying the data.
            // 
            // TODO: We should probably be pooling these staging resources
            // and not creating a new one each time.
            //
            var desc = new SharpDX.Direct3D11.Texture2DDescription();
            desc.Width = width;
            desc.Height = height;
            desc.MipLevels = 1;
            desc.ArraySize = 1;
            desc.Format = SharpDXHelper.ToFormat(format);
            desc.BindFlags = SharpDX.Direct3D11.BindFlags.None;
            desc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Read;
            desc.SampleDescription.Count = 1;
            desc.SampleDescription.Quality = 0;
            desc.Usage = SharpDX.Direct3D11.ResourceUsage.Staging;
            desc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None;

		    var d3dContext = GraphicsDevice._d3dContext;
            using (var stagingTex = new SharpDX.Direct3D11.Texture2D(GraphicsDevice._d3dDevice, desc))
                lock (d3dContext)
                {
                    // Copy the data from the GPU to the staging texture.
                    if (rect.HasValue)
                    {
                        // TODO: Need to deal with subregion copies!
                        throw new NotImplementedException();
                    }
                    else
                        d3dContext.CopySubresourceRegion(_texture, level, null, stagingTex, 0, 0, 0, 0);

                    // Copy the data to the array.
                    SharpDX.DataStream stream;
                    d3dContext.MapSubresource(stagingTex, 0, SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out stream);
                    stream.ReadRange(data, startIndex, elementCount);
                    stream.Dispose();
                }

#else

			GL.BindTexture(TextureTarget.Texture2D, this.glTexture);

			if (rect.HasValue) {
				throw new NotImplementedException();
			}

			if (glFormat == (GLPixelFormat)All.CompressedTextureFormats) {
				throw new NotImplementedException();
			} else {
				GL.GetTexImage(TextureTarget.Texture2D, level, this.glFormat, this.glType, data);
			}

#endif
        }