当我尝试使用SharpDX转储(或显示)在C ++中创建的共享DirectX10 Texture2D时,纹理中的第一行像素出现,但纹理的其余部分为黑色。
我希望显示整个纹理。共享格式为32位B8G8R8A8_UNORM。我正在从在C ++程序中正确显示的源纹理复制到共享纹理。两种纹理的大小和格式都相同。
在SharpDX中,如果我在纹理之外尝试任何指针地址(即使是一个"像素"超过结尾),它会给我一个内存访问错误,所以我知道我使用了正确的移动到下一行像素时的指针值。间距为4 x宽度(每像素4个字节),这与我读过的所有内容都是正确的。步幅也是4 x宽。
我使用的是nuget的最新版SharpDX,2.6.3。
我还尝试使用D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX标志进行互斥锁定,但我遇到了完全相同的问题。
源纹理创建(c ++):
ID3D10Texture2D* CreateShared(unsigned int width, unsigned int height)
{
HRESULT err;
D3D10_TEXTURE2D_DESC td;
zero(&td, sizeof(td));
td.Width = width;
td.Height = height;
td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
td.MipLevels = 1;
td.ArraySize = 1;
td.SampleDesc.Count = 1;
td.Usage = D3D10_USAGE_STAGING;
td.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
td.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
ID3D10Texture2D *texVal;
if (FAILED(err = device->CreateTexture2D(&td, NULL, &texVal)))
{
AppWarning(TEXT("D3D10Texture::CreateShared: CreateTexture2D failed, result = 0x%08lX"), err);
return NULL;
}
return texVal
}
将相同尺寸的现有(工作)纹理内容复制到共享纹理(c ++):
device->CopyResource(desttexure, sourcetexture);
device->Flush();
获取共享句柄:
texture->GetSharedHandle(&sharedHandle);
使用已知句柄打开共享纹理的SharpDX代码:
var factory1 = new Factory1();
var adapter1 = factory1.GetAdapter1(0);
var device10 = new Device10(adapter1,SharpDX.Direct3D10.DeviceCreationFlags.Debug);
var ptrVal = ((long)1073743362); // handle of shared texture
var textureD3D10 = device10.OpenSharedResource<SharpDX.Direct3D10.Texture2D>(new IntPtr(ptrVal));
SharpDX代码,用于将共享纹理转储到磁盘(C#)
public static void Save(this Texture2D texture, Stream stream, SharpDX.Direct3D10.Device device)
{
var textureCopy = new Texture2D(device, new Texture2DDescription
{
Width = (int) texture.Description.Width,
Height = (int) texture.Description.Height,
MipLevels = 1,
ArraySize = 1,
Format = texture.Description.Format,
Usage = ResourceUsage.Staging,
SampleDescription = new SampleDescription(1, 0),
BindFlags = BindFlags.None,
CpuAccessFlags = CpuAccessFlags.Read,
OptionFlags = ResourceOptionFlags.None
});
Thread.Sleep(50);
device.CopyResource(texture, textureCopy);
device.Flush();
Thread.Sleep(50);
DataStream mipsize;
var dataBox = textureCopy.Map(
0,
MapMode.Read,
SharpDX.Direct3D10.MapFlags.None,
out mipsize);
var bitmap = new System.Drawing.Bitmap(textureCopy.Description.Width, textureCopy.Description.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var boundsRect = new System.Drawing.Rectangle(0, 0, textureCopy.Description.Width, textureCopy.Description.Height);
// Copy pixels from screen capture Texture to GDI bitmap
var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
var sourcePtr = dataBox.DataPointer;
var destPtr = mapDest.Scan0;
for (int y = 0; y < textureCopy.Description.Height; y++)
{
// Copy a single line
Utilities.CopyMemory(destPtr, sourcePtr, dataBox.Pitch);
// Advance pointers
sourcePtr = IntPtr.Add(sourcePtr, dataBox.Pitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
bitmap.UnlockBits(mapDest);
var path = "c:\\temp\\screens\\" + DateTime.Now.Ticks + ".bmp";
// Save the output
bitmap.Save(path, ImageFormat.Bmp);
bitmap.Dispose();
}
视频深入解释问题: https://www.youtube.com/watch?v=QO30oN5kCYY
如果需要,可以提供更多信息。