我正在学习D3D,目前我正在使用着色器。我编写了代码并构建了它 - 成功但是在调试时我得到了这个错误:
以下是调试器崩溃的行:
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
以下是整个功能:
void InitPipeline()
{
// load and compile the two shaders
ID3D10Blob *VS, *PS;
D3DX11CompileFromFile("Shaders.shader", 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile("Shaders.shader", 0, 0, "PShader", "ps_4_0", 0, 0, 0, &PS, 0, 0);
// encapsulate both shaders into shader objects
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);
// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
devcon->IASetInputLayout(pLayout);
}
答案 0 :(得分:0)
(1)您没有检查任何HRESULT值是否失败。对于任何COM API用法,包括Direct3D,这是一个必不可少的编码步骤。很可能你在编译语句中遇到了失败,因此VS将返回null。
您可以直接使用FAILED
和SUCCEEDED
宏来执行错误处理,也可以使用现代C ++示例中使用的DX::ThrowIfFailed帮助程序。
if (FAILED(D3DX11CompileFromFile("Shaders.shader", nullptr, nullptr, "VShader", "vs_4_0",
0, 0, nullptr, &VS, nullptr, nullptr)))
// error
if (FAILED(D3DX11CompileFromFile("Shaders.shader", nullptr, nullptr, "PShader", "ps_4_0",
0, 0, nullptr, &PS, nullptr, nullptr)))
// error
在传递NULL指针参数时,您还应该使用VS {2010或更高版本的
nullptr
而不是0,以帮助使用您使用0的各种DWORD参数保持它们。
(2)对于COM API,您还应该考虑使用类似Microsoft::WRL::ComPtr的智能指针而不是原始指针,这些指针会在变量时自动处理调用Release
超出范围。
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
ComPtr<ID3D10Blob> VS, PS;
DX::ThrowIfFailed(D3DX11CompileFromFile("Shaders.shader", nullptr, nullptr, "VShader",
"vs_4_0", 0, 0, nullptr, &VS, nullptr, nullptr));
DX::ThrowIfFailed(D3DX11CompileFromFile("Shaders.shader", nullptr, nullptr, "PShader",
"ps_4_0", 0, 0, nullptr, &PS, nullptr, nullptr));
DX::ThrowIfFailed(dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(),
nullptr, &pVS)(;
DX::ThrowIfFailed(dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(),
nullptr, &pPS));
在上面的代码中,您永远不会在Release
或VS
上调用PS
,因此最终会泄露该内存。
(3)不推荐使用D3DX的所有版本(包括D3DX11),DirectX SDK本身也是如此(请参阅MSDN)。使用VS 2012或更高版本,您已经拥有具有Direct3D 11标头和HLSL编译器的Windows 8.x SDK。不要使用仅仅是包装函数的D3DX11CompileFromFile
,而是直接调用D3DCompileFromFile
(参见HLSL, FXC, and D3DCompile)。
#include <wrl/client.h>
#include <d3dcompiler.h>
using Microsoft::WRL::ComPtr;
ComPtr<ID3DBlob> VS, PS;
DX::ThrowIfFailed(D3DCompileFromFile("Shaders.shader", nullptr, nullptr, "VShader",
"vs_4_0", 0, 0, &VS, nullptr));
DX::ThrowIfFailed(D3DCompileFromFile("Shaders.shader", nullptr, nullptr, "PShader",
"ps_4_0", 0, 0, &PS, nullptr));
DX::ThrowIfFailed(dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(),
nullptr, &pVS)(;
DX::ThrowIfFailed(dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(),
nullptr, &pPS));
更新:如果您需要更详细地了解从D3DCompileFromFile
返回的错误,则应为错误提供ID3DBlob
:
ComPtr<ID3DBlob> VS, Errors;
DX::ThrowIfFailed(D3DCompileFromFile("Shaders.shader", nullptr, nullptr, "VShader",
"vs_4_0", 0, 0, &VS, &Errors));
if ( Errors )
{
OutputDebugStringA( reinterpret_cast<const char*>( Errors->GetBufferPointer() ) );
}