(1) Вы не проверяете значения HRESULT для отказа. Для любого использования COM API, включая Direct3D, это важный шаг кодирования. Скорее всего, вы получаете отказ в операторах компиляции, поэтому VS возвращается в нуль.
Вы можете использовать макросы FAILED
и SUCCEEDED
непосредственно для выполнения обработки ошибок или помощника DX::ThrowIfFailed, используемого в современных образцах C++.
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
You should also use nullptr
with VS 2010 or later instead of 0 when passing NULL pointer parameters to help keep them straight with the various DWORD parameters you are using 0 for.
(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 или более поздней версией у вас уже есть SDK Windows 8.x с заголовками Direct3D 11 и компилятором HLSL. Вместо использования 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));
UPDATE: Если вам нужна более подробная информация об ошибке вы получаете назад от 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()));
}
Как вы новичок в Direct3D, вы должны принять посмотрите на [DirectX Tool Kit] (https://github.com/Microsoft/DirectXTK) и [учебники] (https://github.com/Microsoft/DirectXTK/wiki/Getting-Started). –