2016-11-28 16 views
0

Я очень новичок в directx11, и мне захотелось добавить текстуру в шейдер, который я использую. (до сих пор я еще не использовал текстуры в directx11)PSSetSamplers doens't work (The Pixel Shader unit ожидает Sampler)

Но выборка не работает (это всегда float4 (0,0,0,0)), и я получаю предупреждение: " D3D11 ПРЕДУПРЕЖДЕНИЕ: ID3D11DeviceContext :: DrawIndexed: блок пиксельного шейдера ожидает, что Sampler будет установлен в Slot 0, но ни один из них не связан. "

Я искал, но все ответы говорят, чтобы использовать

_d3dContext->PSSetSamplers(0, 1, &_sampler); 

Но я уже делаю это. Кто-нибудь знает, что может быть неправильным?

Это вся моя шейдер:

Texture2D tex; 
SamplerState TexSampler : register(S0) 
{ 
    Texture = (Slope); 
    Filter = MIN_MAG_MIP_LINEAR; 
    AddressU = clamp; 
    AddressV = clamp; 
}; 

struct PixelShaderInput 
{ 
    float4 color : COLOR0; 
    //.r : slope 
    //.g : relative distance on road (compared the the rider) 
    //.b : shadow (currently darker on lower parts) 
    //.a : cameradepth 
    float fogfactor : COLOR1; 
}; 

float4 main(PixelShaderInput input) : SV_TARGET 
{ 
    const float4 fogColor = float4(0.9, 0.9, 1, 1); 

    const float halfWidth = 0.0016f; 

    float4 color; 

    if (input.color.g < -halfWidth * input.color.a) 
    { 
     color = float4(0.5, 0.85, 1, 1); 
    } 
    else if (input.color.g < halfWidth * input.color.a) 
    { 
     color = float4(1, 1, 1, 1); 
    } 
    else 
    { 
     color = tex.Sample(TexSampler, float2(input.color.r, 0.5)); 
    } 

    if (input.color.b < 0.999) 
    { 
     input.color.b *= 0.94; //makes the sides a bit darker 
    } 
    color.rgb *= input.color.b; 

    color.rgb = lerp(color.rgb, fogColor.rgb, input.fogfactor); 

    return color; 
} 

И в C++/сх Я делаю это (не полный код, только фрагменты):

Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> _slopeGradient; 
Microsoft::WRL::ComPtr<ID3D11SamplerState>   _sampler; 

D3D11_SAMPLER_DESC sampDesc; 
ZeroMemory(&sampDesc, sizeof(sampDesc)); 
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; 
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; 
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; 
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; 
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; 
sampDesc.MinLOD = 0; 
sampDesc.MaxLOD = D3D11_FLOAT32_MAX; 
_d3dDevice->CreateSamplerState(&sampDesc, &_sampler); 

_d3dContext->PSSetShaderResources(0, 1, &_slopeGradient); 
_d3dContext->PSSetSamplers(0, 1, &_sampler); 

ответ

2

Проблема в том, ваше использование ComPtr. Перегрузка operator& для Microsoft::WRL::ComPtr звонков ReleaseAndGetAddressOf, а не GetAddressOf. Таким образом, вы в основном делаете это прямо сейчас, который всегда настройки этих ресурсов nullptr (т.е. очистки слота):

_d3dContext->PSSetShaderResources(0, 1, _slopeGradient.ReleaseAndGetAddressOf()); 
_d3dContext->PSSetSamplers(0, 1, _sampler.ReleaseAndGetAddressOf()); 

Вы должны использовать:

_d3dContext->PSSetShaderResources(0, 1, _slopeGradient.GetAddressOf()); 
_d3dContext->PSSetSamplers(0, 1, _sampler.GetAddressOf()); 

Старые АТЛ CComPtr имел operator& перегрузили карту до GetAddressOf, но утверждали, что это был nullptr, который часто приводил к непреднамеренным утечкам памяти. Предполагается, что operator& используется при инициализации этими интеллектуальными указателями, и это не то, что вы здесь делаете. Вам действительно нужен адрес инициализированного исходного указателя.

Помните, что оба этих метода фактически принимают массив указателей COM. В C вы можете, конечно, лечить указатель как массив размера один, но вы можете найти более ясно, чтобы сделать что-то вроде:

ID3D11ShaderResourceView* srvs[] = { _slopeGradient.GetAddressOf() }; 
_d3dContext->PSSetShaderResources(0, _countof(srvs), srvs); 

ID3D11SamplerState* samplers[] = { _sampler.GetAddressOf() }; 
_d3dContext->PSSetSamplers(0, _countof(samplers), samplers); 

отметить также, что вы определяете некоторые элементы наследия Effects system в вашем HLSL источник, который игнорируется в стандартном использовании API DirectX. Вы можете просто удалить его.

{ 
    Texture = (Slope); 
    Filter = MIN_MAG_MIP_LINEAR; 
    AddressU = clamp; 
    AddressV = clamp; 
} 

Как вы новичок в DirectX 11, вы должны смотреть на DirectX Tool Kit.

+0

Спасибо, я понятия не имел об этом. Я изменил его, и теперь предупреждение исчезло, но я получаю тот же визуальный результат. Есть идеи? Должен признать, что я новичок в C++/cx, а также directx11. Я фактически начал использовать DirectXTK, но, похоже, он работает несколько иначе, чем то, что у меня уже было, и я пытаюсь его объединить, но, похоже, я не работаю. – Stef

+0

Отладка графики сложна, так как есть множество способов, чтобы она пошла не так и заканчивалась пустым экраном. Обратите внимание, что DirectX 11 является COM-интерфейсом, поэтому не имеет значения, используете ли вы C++/CX или чистый C++, поскольку он одинаковый на всех платформах Direct3D.Вы можете захотеть работать с учебниками DirectX Tool Kit независимо от вашего текущего проекта, а затем вернуться к нему, как только у вас появится ручка. –

+0

Я думаю, что это действительно самое лучшее. Спасибо за помощь. – Stef