32 位格式的 D3D11 CreateTexture2D
D3D11 CreateTexture2D in 32 bit format
令人惊讶的是,我找不到关于这个问题的任何帮助,尽管我很确定这是一个非常基本的问题。所以也许这里有人可以帮助我在这方面取得进展。
我正在尝试创建一个 d3d11 纹理,单通道,每像素 32 位。官方文档很有趣(http://msdn.microsoft.com/en-us/library/windows/desktop/ff476521(v=vs.85).aspx),我发现这个例子是四通道每像素 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.调试层:
感谢您的建议,我阅读了您提供的 link,以及您对 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
(不能post link因为信誉低)
对于当前使用 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 aka DirectX 11.0[=12 的正确 DirectX 调试运行时=]
我应该可以使用调试层。但是激活标志并不会使 exe 更加冗长。我正在进一步挖掘。 (根据 dxdiag,我在 windows 7 上使用带有 DirectX SDK 的 mvs 2010,使用 DirectX 11)
编辑:解决方案
好的,所以确实输出消息在 msv 的 "output" 面板中可见,而不是在控制台中!这是向前迈出的一大步^^。这样这一点就解决了,关闭了。
2。 DXGI_FORMAT_R32_FLOAT
格式:
我不太明白你说的"initData"是什么意思。我猜你的意思是我正在创建纹理并同时填充它,而我可以使用空的子资源数据并使用 UpdateSubresource()
。但无论如何我尝试使用 DXGI_FORMAT_R32_FLOAT
。它似乎工作得很好,因为我没有任何错误,但纹理是黑色的,或者没有纹理。所以我想它不能正常工作,我需要解决这个问题。我希望使用调试层会有所帮助。尽管我很惊讶,因为再次,我在运行时没有错误。
编辑:由于调试层现在正常,我现在确定纹理是使用 Chuck Walbourn 的建议正确创建的。好的!但另一个问题仍然存在:纹理要么完全黑色,要么完全红色。深入挖掘。
编辑:解决方案
问题很简单:每个像素值必须在 0.0 和 1.0 之间浮动。就这样。问题解决了。但是然后图像是红色的...
3。 9.2以上的Direct3D功能等级:
我不知道。这对我来说开始是完全陌生的语言。 PC 使用的是 NVIDIA Quadro K4000,我只是偷偷地假设这就足够了。我希望...
编辑:解决方案
好像是,所以没关系。
4.想到一个绝望的心:
我不是核心程序员,我只是想使用单通道32位纹理而不是四通道32位,说真的,为什么这么复杂?
您应该尝试的第一件事是启用 DEBUG device 以查找更详细的诊断,因为这可能会告诉您确切的错误 w.r.t。参数验证。
就是说,问题是您正在使用深度格式 DXGI_FORMAT_D32_FLOAT
,然后尝试使用不受支持的 initData 对其进行初始化。请尝试 DXGI_FORMAT_R32_FLOAT
。
请注意 DXGI_FORMAT_R32_FLOAT
需要 Direct3D feature level 9.2 或更高版本。
我只是发现 DXGI_FORMAT_R32G32B32_FLOAT
存在。所以我正在创建一个 r32g32b32 纹理,并且因为我需要一个黑白图像,所以我在每种颜色上使用相同的级别。很简单。
这是我针对此解决方案提出的问题中示例的偏角:
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);
}
令人惊讶的是,我找不到关于这个问题的任何帮助,尽管我很确定这是一个非常基本的问题。所以也许这里有人可以帮助我在这方面取得进展。
我正在尝试创建一个 d3d11 纹理,单通道,每像素 32 位。官方文档很有趣(http://msdn.microsoft.com/en-us/library/windows/desktop/ff476521(v=vs.85).aspx),我发现这个例子是四通道每像素 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.调试层:
感谢您的建议,我阅读了您提供的 link,以及您对 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
(不能post link因为信誉低)
对于当前使用 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 aka DirectX 11.0[=12 的正确 DirectX 调试运行时=]
我应该可以使用调试层。但是激活标志并不会使 exe 更加冗长。我正在进一步挖掘。 (根据 dxdiag,我在 windows 7 上使用带有 DirectX SDK 的 mvs 2010,使用 DirectX 11)
编辑:解决方案 好的,所以确实输出消息在 msv 的 "output" 面板中可见,而不是在控制台中!这是向前迈出的一大步^^。这样这一点就解决了,关闭了。
2。 DXGI_FORMAT_R32_FLOAT
格式:
我不太明白你说的"initData"是什么意思。我猜你的意思是我正在创建纹理并同时填充它,而我可以使用空的子资源数据并使用 UpdateSubresource()
。但无论如何我尝试使用 DXGI_FORMAT_R32_FLOAT
。它似乎工作得很好,因为我没有任何错误,但纹理是黑色的,或者没有纹理。所以我想它不能正常工作,我需要解决这个问题。我希望使用调试层会有所帮助。尽管我很惊讶,因为再次,我在运行时没有错误。
编辑:由于调试层现在正常,我现在确定纹理是使用 Chuck Walbourn 的建议正确创建的。好的!但另一个问题仍然存在:纹理要么完全黑色,要么完全红色。深入挖掘。
编辑:解决方案 问题很简单:每个像素值必须在 0.0 和 1.0 之间浮动。就这样。问题解决了。但是然后图像是红色的...
3。 9.2以上的Direct3D功能等级:
我不知道。这对我来说开始是完全陌生的语言。 PC 使用的是 NVIDIA Quadro K4000,我只是偷偷地假设这就足够了。我希望...
编辑:解决方案 好像是,所以没关系。
4.想到一个绝望的心:
我不是核心程序员,我只是想使用单通道32位纹理而不是四通道32位,说真的,为什么这么复杂?
您应该尝试的第一件事是启用 DEBUG device 以查找更详细的诊断,因为这可能会告诉您确切的错误 w.r.t。参数验证。
就是说,问题是您正在使用深度格式 DXGI_FORMAT_D32_FLOAT
,然后尝试使用不受支持的 initData 对其进行初始化。请尝试 DXGI_FORMAT_R32_FLOAT
。
请注意 DXGI_FORMAT_R32_FLOAT
需要 Direct3D feature level 9.2 或更高版本。
我只是发现 DXGI_FORMAT_R32G32B32_FLOAT
存在。所以我正在创建一个 r32g32b32 纹理,并且因为我需要一个黑白图像,所以我在每种颜色上使用相同的级别。很简单。
这是我针对此解决方案提出的问题中示例的偏角:
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);
}