【问题标题】:Texture2d from Byte array Sharpdx来自字节数组 Sharpdx 的 Texture2d
【发布时间】:2020-09-30 02:46:37
【问题描述】:

我是 C#、SharpDX 和 Directx 新手。请原谅我的无知。我正在跟进一个旧帖子:Exception of Texture2D.FromMemory() in SharpDX code。很有帮助。

我的目标:

  1. 从软件位图构建 Texture2d。
  2. 使纹理可用于 HLSL。

我接近它的方式:

  1. 使用 IMemoryBufferByteAccess,我能够检索到字节的指针和 Frame 的总容量。从上一篇文章来看,我似乎需要使用 DataRectangle 来指向字节数组。
  2. 有 2 个具有不同描述符的纹理 - Texture1 (_staging_texture) - 无绑定标志、cpu 写入和读取权限、使用 - 暂存。我用指向字节数组的数据矩形创建了这个纹理。 Texture2 (_final_texture) - 着色器绑定标志,无 cpu 访问权限,用法 - 默认。这个纹理最终将提供给着色器。目的是使用从 Texture1 到 Texture2 的 copyResource 函数。

下面,我复制我未打磨的代码以供参考:

               bitmap = latestFrame.SoftwareBitmap;
                Windows.Graphics.Imaging.BitmapBuffer bitmapBuffer= bitmap.LockBuffer(Windows.Graphics.Imaging.BitmapBufferAccessMode.Read);
                Windows.Foundation.IMemoryBufferReference bufferReference = bitmapBuffer.CreateReference();
                var staging_descriptor = new Texture2DDescription
                {
                    Width = Width,
                    Height = Height,
                    MipLevels = 1,
                    ArraySize = 1,
                    Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                    Usage = ResourceUsage.Staging,
                    BindFlags = BindFlags.None,
                    CpuAccessFlags = CpuAccessFlags.Read | CpuAccessFlags.Write,
                    OptionFlags = ResourceOptionFlags.None
                };
                var final_descriptor = new Texture2DDescription
                {
                    Width = Width,
                    Height = Height,
                    MipLevels = 1,
                    ArraySize = 1,
                    Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                    Usage = ResourceUsage.Default,
                    BindFlags = BindFlags.ShaderResource,
                    CpuAccessFlags = CpuAccessFlags.None,
                    OptionFlags = ResourceOptionFlags.None
                };

                var dataRectangle = new SharpDX.DataRectangle();
                unsafe
                {
                    byte* dataInBytes;
                    uint capacityInBytes;
                    ((InteropStatics.IMemoryBufferByteAccess)bufferReference).GetBuffer(out dataInBytes, out capacityInBytes);                    
                    dataRectangle.DataPointer = (IntPtr)dataInBytes;
                    dataRectangle.Pitch = 4;
                }
                

                Texture2D _stagingTexture = new Texture2D(device, staging_descriptor, dataRectangle);
                Texture2D _finalTexture = new Texture2D(device, final_descriptor);

                _stagingTexture.Device.ImmediateContext.CopyResource(_stagingTexture, _finalTexture);

我的问题有两个:

  1. DataRectangle 使用 IntPtr 类型,而从 接口是字节数组..这不是问题吗?或者 在 DataRectangle 中的 pitch 成员地址是这个?现在我投了 byteArray 到 IntPtr。
  2. 这种方法行得通吗?或者有没有更好的方法来处理这个问题?

任何指点、建议或建设性的批评都将不胜感激!

【问题讨论】:

    标签: c# arrays sharpdx texture2d


    【解决方案1】:

    不久前我也在寻找相同的功能,但我想出了这个功能,它总是适用于我的用例

    public static Texture2D CreateTexture2DFrombytes(Device device, byte[] RawData, int width, int height)
    {
        Texture2DDescription desc;
        desc.Width = width;
        desc.Height = height;
        desc.ArraySize = 1;
        desc.BindFlags = BindFlags.ShaderResource;
        desc.Usage = ResourceUsage.Immutable;
        desc.CpuAccessFlags = CpuAccessFlags.None;
        desc.Format = Format.B8G8R8A8_UNorm;
        desc.MipLevels = 1;
        desc.OptionFlags = ResourceOptionFlags.None;
        desc.SampleDescription.Count = 1;
        desc.SampleDescription.Quality = 0;
        DataStream s = DataStream.Create(RawData, true, true);
        DataRectangle rect = new DataRectangle(s.DataPointer, width * 4);
        Texture2D t2D = new Texture2D(device, desc, rect);
        return t2D;
    }
    

    【讨论】:

    • 谢谢 Abhishek.. 真的很有帮助.. 你会推荐我提出的关于将资源从 Texture1 复制到 texture2 的实现吗?我觉得应该有一个简单的方法来做到这一点..
    • 你可以尝试使用 DeviceContext.CopySubresourceRegion(source, 0, null, destination, 0);其中源和目标是 texture2d
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多