在C ++中创建的Direct3D共享纹理仅在SharpDX中显示一行像素(视频说明)

时间:2015-05-05 11:03:45

标签: shared direct3d texture2d sharpdx direct3d11

当我尝试使用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

如果需要,可以提供更多信息。

0 个答案:

没有答案