2015-12-17 4 views
0

Я изучаю D3D, и в настоящее время я нахожусь в шейдерах. Я написал код и построил его - добиться успеха, но когда отладки я получаю эту ошибку:Vertex Shader Создание

ERROR

Вот строка, где отладчик Breake:

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

Как вы новичок в Direct3D, вы должны принять посмотрите на [DirectX Tool Kit] (https://github.com/Microsoft/DirectXTK) и [учебники] (https://github.com/Microsoft/DirectXTK/wiki/Getting-Started). –

ответ

0

(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())); 
} 
+0

Я все еще не понимаю. Когда мне нужно проверить этот HRESULT, после компиляции из файла или когда я создаю вершинный шейдер? Также я использовал NULL insted of 0, но я изменил его, потому что я что-то пытался, и мне было легче отслеживать. Else i have Realize, но в другом funcion (функция void, где я освобождаю все i на одном месте. – DoLoop

+0

Забыл об этом вопросе. Я понял, что это глупо, и я понял, что сам, когда я краю код, который вы мне отправляете, и я получил это то, что он не может скомпилировать из файла, но как я могу понять, почему он это делает? – DoLoop

+0

См. UPDATE в ответе выше. –

Смежные вопросы