当我尝试在某些 pc 上将交换链纹理中的渲染内容读取到 byte[] 时,返回的数组大小大于预期
when i try read renderd content from the texture of swapchain into byte[] on some pc's the returned array size bigger then expected
所以情况是这样的
我现在使用 sharp dx 创建链接到 XAML 元素 SwapchainPanel 的交换链
我在上面渲染了一些东西,然后我尝试将渲染数据抓取到 byte[] 中以放入图像缓冲区
为此,我使用这个函数 ReadBuffer
private D3D11.Texture2D OffscreenstagingTexture;
private D3D11.Texture2D GetTexture(D3D11.Device _Device,
D3D11.DeviceContext _Context,
D3D11.Texture2DDescription _Desc)
{
if (OffscreenstagingTexture == null ||
OffscreenstagingTexture.Description.Width != _Desc.Width ||
OffscreenstagingTexture.Description.Height != _Desc.Height)
{
RemoveAndDispose(ref OffscreenstagingTexture);
D3D11.Texture2DDescription _2DDesc = new D3D11.Texture2DDescription
{
Format = DXGI.Format.B8G8R8A8_UNorm,
Height = _Desc.Height,
Width = _Desc.Width,
SampleDescription = new DXGI.SampleDescription(1, 0),
ArraySize = _Desc.ArraySize,
BindFlags = D3D11.BindFlags.None,
CpuAccessFlags = D3D11.CpuAccessFlags.Read | D3D11.CpuAccessFlags.Write,
Usage = D3D11.ResourceUsage.Staging,
MipLevels = _Desc.MipLevels
};
OffscreenstagingTexture = ToDispose(new D3D11.Texture2D(_Device, _2DDesc));
}
return OffscreenstagingTexture;
}
public byte[] ReadBuffer(D3D11.Texture2D _2DTexture)
{
byte[] data = null;
D3D11.Texture2DDescription _Desc = _2DTexture.Description;
D3D11.Device _Device = _2DTexture.Device;
D3D11.DeviceContext _Context = _Device.ImmediateContext;
D3D11.Texture2D _2DMappedTexture = GetTexture(_Device, _Context, _Desc);
try
{
_Context.CopyResource(_2DTexture, _2DMappedTexture);
int size = _Desc.Width * _Desc.Height * 4;
DataBox box = _Context.MapSubresource(_2DMappedTexture, 0, 0, D3D11.MapMode.Read, D3D11.MapFlags.None, out DataStream stream);
data = ToByteArray(stream);
stream.Dispose();
}
catch (Exception)
{
}
return data;
}
private byte[] ToByteArray(Stream inputStream)
{
using (MemoryStream ms = new MemoryStream())
{
inputStream.CopyTo(ms);
return ms.ToArray();
}
}
现在,在大多数电脑上,它工作正常,但有一些电脑 SwapChainPanle 返回比预期更大的字节[]
如果我有 100 * 100 SwapChainPanel 那么预期的字节数组大小是 100 * 100 * 4 但它 returns 比那个更大的数组并且因为在某些电脑上我的应用程序崩溃了
我也在我的戴尔 Vostro 3558 上检查了同样的崩溃
所以我找到了修复方法,我必须更新 Readbuffer 函数
public byte[] ReadBuffer(D3D11.Texture2D _2DTexture)
{
D3D11.Texture2DDescription _Desc = _2DTexture.Description;
D3D11.Device _Device = _2DTexture.Device;
D3D11.DeviceContext _Context = _Device.ImmediateContext;
D3D11.Texture2D _2DMappedTexture = GetTexture(_Device, _Context, _Desc);
_Context.CopyResource(_2DTexture, _2DMappedTexture);
DataBox box = _Context.MapSubresource(_2DMappedTexture, 0, 0, D3D11.MapMode.Read, D3D11.MapFlags.None, out DataStream stream);
var dataRectangle = new DataRectangle
{
DataPointer = stream.DataPointer,
Pitch = box.RowPitch
};
var strid = _Desc.Width * 4;
int size = _Desc.Width * _Desc.Height * 4;
using (var bitmap = new Bitmap(manager.WICFactory,
_2DMappedTexture.Description.Width,
_2DMappedTexture.Description.Height,
PixelFormat.Format32bppBGRA,
dataRectangle))
{
var data = new byte[size];
bitmap.CopyPixels(data, strid);
_Context.UnmapSubresource(_2DMappedTexture, 0);
return data;
}
}
而且效果很好
所以情况是这样的
我现在使用 sharp dx 创建链接到 XAML 元素 SwapchainPanel 的交换链
我在上面渲染了一些东西,然后我尝试将渲染数据抓取到 byte[] 中以放入图像缓冲区
为此,我使用这个函数 ReadBuffer
private D3D11.Texture2D OffscreenstagingTexture;
private D3D11.Texture2D GetTexture(D3D11.Device _Device,
D3D11.DeviceContext _Context,
D3D11.Texture2DDescription _Desc)
{
if (OffscreenstagingTexture == null ||
OffscreenstagingTexture.Description.Width != _Desc.Width ||
OffscreenstagingTexture.Description.Height != _Desc.Height)
{
RemoveAndDispose(ref OffscreenstagingTexture);
D3D11.Texture2DDescription _2DDesc = new D3D11.Texture2DDescription
{
Format = DXGI.Format.B8G8R8A8_UNorm,
Height = _Desc.Height,
Width = _Desc.Width,
SampleDescription = new DXGI.SampleDescription(1, 0),
ArraySize = _Desc.ArraySize,
BindFlags = D3D11.BindFlags.None,
CpuAccessFlags = D3D11.CpuAccessFlags.Read | D3D11.CpuAccessFlags.Write,
Usage = D3D11.ResourceUsage.Staging,
MipLevels = _Desc.MipLevels
};
OffscreenstagingTexture = ToDispose(new D3D11.Texture2D(_Device, _2DDesc));
}
return OffscreenstagingTexture;
}
public byte[] ReadBuffer(D3D11.Texture2D _2DTexture)
{
byte[] data = null;
D3D11.Texture2DDescription _Desc = _2DTexture.Description;
D3D11.Device _Device = _2DTexture.Device;
D3D11.DeviceContext _Context = _Device.ImmediateContext;
D3D11.Texture2D _2DMappedTexture = GetTexture(_Device, _Context, _Desc);
try
{
_Context.CopyResource(_2DTexture, _2DMappedTexture);
int size = _Desc.Width * _Desc.Height * 4;
DataBox box = _Context.MapSubresource(_2DMappedTexture, 0, 0, D3D11.MapMode.Read, D3D11.MapFlags.None, out DataStream stream);
data = ToByteArray(stream);
stream.Dispose();
}
catch (Exception)
{
}
return data;
}
private byte[] ToByteArray(Stream inputStream)
{
using (MemoryStream ms = new MemoryStream())
{
inputStream.CopyTo(ms);
return ms.ToArray();
}
}
现在,在大多数电脑上,它工作正常,但有一些电脑 SwapChainPanle 返回比预期更大的字节[] 如果我有 100 * 100 SwapChainPanel 那么预期的字节数组大小是 100 * 100 * 4 但它 returns 比那个更大的数组并且因为在某些电脑上我的应用程序崩溃了 我也在我的戴尔 Vostro 3558 上检查了同样的崩溃
所以我找到了修复方法,我必须更新 Readbuffer 函数
public byte[] ReadBuffer(D3D11.Texture2D _2DTexture)
{
D3D11.Texture2DDescription _Desc = _2DTexture.Description;
D3D11.Device _Device = _2DTexture.Device;
D3D11.DeviceContext _Context = _Device.ImmediateContext;
D3D11.Texture2D _2DMappedTexture = GetTexture(_Device, _Context, _Desc);
_Context.CopyResource(_2DTexture, _2DMappedTexture);
DataBox box = _Context.MapSubresource(_2DMappedTexture, 0, 0, D3D11.MapMode.Read, D3D11.MapFlags.None, out DataStream stream);
var dataRectangle = new DataRectangle
{
DataPointer = stream.DataPointer,
Pitch = box.RowPitch
};
var strid = _Desc.Width * 4;
int size = _Desc.Width * _Desc.Height * 4;
using (var bitmap = new Bitmap(manager.WICFactory,
_2DMappedTexture.Description.Width,
_2DMappedTexture.Description.Height,
PixelFormat.Format32bppBGRA,
dataRectangle))
{
var data = new byte[size];
bitmap.CopyPixels(data, strid);
_Context.UnmapSubresource(_2DMappedTexture, 0);
return data;
}
}
而且效果很好