D3D11 32位格式的CreateTexture2D

时间:2015-01-07 15:52:03

标签: directx-11

令人惊讶的是,我无法在这个问题上找到任何帮助,尽管我非常肯定这是一个非常基本的问题。所以也许这里有人可以帮助我取得进展。

我正在尝试创建一个d3d11纹理,单通道,每像素32位。官方文档很有意思(http://msdn.microsoft.com/en-us/library/windows/desktop/ff476521(v=vs.85).aspx),我发现这个例子是每像素一个4通道8位:

ID3D11Texture2D *MakeCheckerboard(ID3D11Device *myDevice)
{
    ID3D11Texture2D *tex;
    D3D11_TEXTURE2D_DESC tdesc;
    D3D11_SUBRESOURCE_DATA tbsd;

    int w = 512;
    int h = 512;
    int bpp = 4;
    int *buf = new int[w*h];

    // filling the image
    for(int i=0;i<h;i++)
        for(int j=0;j<w;j++)
        {
            if((i&32)==(j&32))
                buf[i*w+j] = 0x00000000;
            else
                buf[i*w+j] = 0xffffffff;
        }

    // setting up D3D11_SUBRESOURCE_DATA 
    tbsd.pSysMem = (void *)buf;
    tbsd.SysMemPitch = w*bpp ;
    tbsd.SysMemSlicePitch = w*h*bpp ; // Not needed since this is a 2d texture

    // setting up D3D11_TEXTURE2D_DESC 
    tdesc.Width  = w;
    tdesc.Height = h;
    tdesc.MipLevels = 1;
    tdesc.ArraySize = 1;
    tdesc.SampleDesc.Count   = 1;
    tdesc.SampleDesc.Quality = 0;
    tdesc.Usage     = D3D11_USAGE_DEFAULT;
    tdesc.Format    = DXGI_FORMAT_R8G8B8A8_UNORM;
    tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    tdesc.CPUAccessFlags = 0;
    tdesc.MiscFlags      = 0;

    // checking inputs
    if ( myDevice->CreateTexture2D(&tdesc, &tbsd, NULL) == S_FALSE )
        std::cout << "Inputs correct" << std::endl;
    else
        std::cout << "wrong inputs" << std::endl;

    // create the texture
    if(FAILED(myDevice->CreateTexture2D(&tdesc,&tbsd,&tex)))
    {
        std::cout << "Failed" << std::endl;
        return(0);
    }
    else
        std::cout << "Success" << std::endl;

    delete[] buf;

    return(tex);
}

这个例子工作得很好,所以输出是:

Inputs correct
Success

然后,如果我对32位单通道进行一点修改

ID3D11Texture2D *MakeCheckerboard(ID3D11Device *myDevice)
{
    ID3D11Texture2D *tex;
    D3D11_TEXTURE2D_DESC tdesc;
    D3D11_SUBRESOURCE_DATA tbsd;

    int w = 512;
    int h = 512;
    int bpp = 4;
    int *buf = new int[w*h];

    for(int i=0;i<h;i++)
        for(int j=0;j<w;j++)
        {
            if((i&32)==(j&32))
                buf[i*w+j] = 0x00000000;
            else
                buf[i*w+j] = 0xffffffff;
        }

    tbsd.pSysMem = (void *)buf;
    tbsd.SysMemPitch = w*bpp ;
    tbsd.SysMemSlicePitch = w*h*bpp ; // Not needed since this is a 2d texture

    tdesc.Width = w;
    tdesc.Height = h;

    tdesc.MipLevels = 1;
    tdesc.ArraySize = 1;
    tdesc.SampleDesc.Count = 1;
    tdesc.SampleDesc.Quality = 0;
    tdesc.Usage = D3D11_USAGE_DEFAULT;
    tdesc.Format = DXGI_FORMAT_D32_FLOAT;
    tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

    tdesc.CPUAccessFlags = 0;
    tdesc.MiscFlags = 0;

    if ( myDevice->CreateTexture2D(&tdesc, &tbsd, NULL) == S_FALSE )
        std::cout << "Inputs correct" << std::endl;
    else
        std::cout << "wrong inputs" << std::endl;

    if(FAILED(myDevice->CreateTexture2D(&tdesc,&tbsd,&tex)))
    {
        std::cout << "Failed" << std::endl;
        return(0);
    }
    else
        std::cout << "Sucess" << std::endl;

    delete[] buf;

    return(tex);
}

相应的输出变为

wrong inputs
Failed

所以我猜输入是错误的,但它们对我来说似乎很好,文档也不是很冗长。有人有线索吗?

编辑 - 在Chuck Walbourn回答

之后

我在这里看到三点:

1。调试层:

感谢您的建议,我阅读了您提供的链接,以及this question here上的答案,以及此文档(4)和此处的最后一段(5):

msdn.microsoft.com/en-us/library/windows/desktop/jj200584(V = vs.85)的.aspx

msdn.microsoft.com/en-us/library/windows/desktop/jj863687(V = vs.85)的.aspx

(由于报酬低,无法发布链接)

对于目前使用D3D11_CREATE_DEVICE_DEBUG标志在Microsoft Visual Studio 2010或更早版本中处理应用程序的开发人员,请注意对D3D11CreateDevice的调用将失败。这是因为D3D11.1运行时现在需要D3D11_1SDKLayers.dll而不是D3D11SDKLayers.dll。

我必须使用VS 2010开发,如果我激活标记D3D11_CREATE_DEVICE_DEBUG,则D3D11CreateDevice()的调用不会产生任何错误。但是在运行时没有调试消息。所以我在我的电脑上进行了研究,并且缺少dll D3D11_1SDKLayers.dll。因此,我假设我将不得不安装Windows SDK 8.1。

这提出了我将尝试回答的两个问题:

我可以在Windows 7 PC上安装Windows 8.1 SDK吗?

调试消息将出现在哪里?在运行时的控制台中? (愚蠢的问题,我猜,但我必须承认,我不是一个真正的程序员,对你们来说显然有些琐事不适合我,我想......)

编辑:根据

传统的DirectX SDK(2010年6月)具有适用于Windows Vista SP2和Windows 7(即DirectX 11.0)的正确DirectX调试运行时

我应该可以使用调试层。但是激活标志并不会使exe更加冗长。我正在深入挖掘。 (我在2010年6月使用mvs 2010和DirectX SDK,在Windows 7上使用DirectX 11,根据dxdiag)

编辑:解决方案 好的,确实输出msg在&#34;输出&#34;中可见。 msv的面板,不在控制台中!这是向前迈出的一大步^^。因此,这一点得到了解决和结束。

2。 DXGI_FORMAT_R32_FLOAT格式:

我真的不明白你的意思&#34; initData&#34;。我猜你的意思是我在创建纹理并在同一时间填充它,而我可以使用空的子资源数据并使用UpdateSubresource()。但无论如何我尝试使用DXGI_FORMAT_R32_FLOAT。它似乎工作得很好,因为我没有任何错误,但纹理是黑色的,或没有纹理。所以我猜它不能正常工作,我需要继续努力。我希望使用调试层会有所帮助。即使我再次感到非常惊讶,我在运行时也没有错误。

编辑:由于调试层现在正常,我现在可以确定使用Chuck Walbourn建议正确创建了纹理。好!但另一个问题仍然存在:纹理要么是完全黑色,要么是完全红色。深入挖掘。

编辑:解决方案 问题很简单:每个像素值必须介于0.0和1.0之间。这就是全部。问题解决了。但那时图像是红色的......

第3。 Direct3D功能级别高于9.2:

我不知道。这开始对我来说是完全的外语。 PC正在使用NVIDIA Quadro K4000,我只是秘密地假设这已经足够了。我希望......

编辑:解决方案 显然它是,所以没关系。

4。想到一个绝望的头脑:

我不是核心程序员,我只是想要使用单通道32位纹理而不是4通道32位,严重的是,为什么这么复杂?

2 个答案:

答案 0 :(得分:2)

你应该尝试的第一件事是让DEBUG device寻找更详细的诊断,因为这可能会告诉你究竟什么是错误的w.r.t.参数验证。

也就是说,问题是您使用的是深度格式DXGI_FORMAT_D32_FLOAT,然后尝试使用不支持的initData初始化它。请改为DXGI_FORMAT_R32_FLOAT

请注意,DXGI_FORMAT_R32_FLOAT需要Direct3D feature level 9.2或更高版本。

答案 1 :(得分:2)

我发现DXGI_FORMAT_R32G32B32_FLOAT存在。所以我正在创建一个r32g32b32纹理,因为我需要一个b&amp; w图像,我在每种颜色上使用相同的级别。很简单。

以下是我对此解决方案的问题中示例的偏差:

ID3D11Texture2D *MakeCheckerboard(ID3D11Device *myDevice)
{
    ID3D11Texture2D*       tex;
    D3D11_TEXTURE2D_DESC   tdesc;
    D3D11_SUBRESOURCE_DATA tbsd;

    int width    = 3;   // three pixel wide
    int height   = 1;   // one pixel height
    int bpp      = 12;
    int nb_color = 3;

    // CREATING THE IMAGE
    float* buf[ width * height * nb_color ];

    // pixel white
    buf[0] = 1.0f; // red
    buf[1] = 1.0f; // green
    buf[2] = 1.0f; // blue

    // pixel black
    buf[3] = 0.0f;
    buf[4] = 0.0f;
    buf[5] = 0.0f;

    // pixel white
    buf[6] = 1.0f;
    buf[7] = 1.0f;
    buf[8] = 1.0f;

    tbsd.pSysMem          = (void *) buf;
    tbsd.SysMemPitch      = width * bpp ;
    tbsd.SysMemSlicePitch = width * height * bpp ; // Not needed since this is a 2d texture

    tdesc.Width              = width;
    tdesc.Height             = height;
    tdesc.MipLevels          = 1;
    tdesc.ArraySize          = 1;
    tdesc.SampleDesc.Count   = 1;
    tdesc.SampleDesc.Quality = 0;
    tdesc.Usage              = D3D11_USAGE_DEFAULT;
    tdesc.Format             = DXGI_FORMAT_R32G32B32_FLOAT;
    tdesc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
    tdesc.CPUAccessFlags     = 0;
    tdesc.MiscFlags          = 0;


    if(FAILED(myDevice->CreateTexture2D(&tdesc,&tbsd,&tex)))
        return(0);

    delete[] buf;

    return(tex);
}