2017-06-30 8 views
1

Je suis nouveau à Direct3D11 et je suis en train d'essayer de créer une texture programatically dans mon code en utilisant ce code j'ai trouvé en ligne:Confusion au sujet Texture2D et ShaderResourceViews

// Some Constants 
int w = 256; 
int h = 256; 
int bpp = 4; 
int *buf = new int[w*h]; 

//declarations 
ID3D11Texture2D* tex; 
D3D11_TEXTURE2D_DESC sTexDesc; 
D3D11_SUBRESOURCE_DATA tbsd; 

// 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 

// initializing sTexDesc 
sTexDesc.Width = w; 
sTexDesc.Height = h; 
sTexDesc.MipLevels = 1; 
sTexDesc.ArraySize = 1; 
sTexDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
sTexDesc.SampleDesc.Count = 1; 
sTexDesc.SampleDesc.Quality = 0; 
sTexDesc.Usage = D3D11_USAGE_DEFAULT; 
sTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 
sTexDesc.CPUAccessFlags = 0; 
sTexDesc.MiscFlags = 0; 

hr = m_pd3dDevice->CreateTexture2D(&sTexDesc, &tbsd, &tex); 

et que » tout va bien et dandy, mais je suis un peu confus sur la façon de réellement charger cela dans le shader. Ci-dessous j'initialisés cette ID3D11ShaderResourceView:

 ID3D11ShaderResourceView*   m_pTextureRV = nullptr; 

je trouve sur les didacticiels Microsoft dont j'ai besoin d'utiliser le CreateShaderResourceView. Mais comment exactement je l'utilise? J'ai essayé ceci:

 hr = m_pd3dDevice->CreateShaderResourceView(tex, NULL , m_pTextureRV); 

mais il me donne une erreur, me disant que m_pTextureRV est pas un argument valable pour la fonction. Qu'est-ce que je fais mal ici?

Répondre

0

La bonne façon d'appeler cette fonction est:

hr = m_pd3dDevice->CreateShaderResourceView(tex, nullptr, &m_pTextureRV); 

Rappelez-vous que ID3D11ShaderResourceView* est un pointeur vers une interface. Vous avez besoin d'un pointeur vers un pointeur pour obtenir une nouvelle instance d'un retour.

Vous devriez vraiment envisager d'utiliser un pointeur intelligent COM comme Microsoft::WRL::ComPtr au lieu de pointeurs bruts pour ces interfaces.

Une fois que vous avez créé la vue des ressources de shaders pour votre objet texture, alors vous devez l'associer à tout emplacement du HLSL attend de le trouver. Donc, par exemple, si vous deviez écrire un fichier source HLSL comme:

Texture2D texture : register(t0); 
SamplerState sampler: register(s0); 

float4 PS(float2 tex : TEXCOORD0) : SV_Target 
{ 
    return texture.Sample(sampler, tex); 
} 

compilez ensuite comme un pixel shader, et le lier à la canalisation rendre via PSSetShader. Ensuite, vous aurez besoin d'appeler:

ID3D11ShaderResourceView* srv[1] = { m_pTextureRV }; 
m_pImmediateContext->PSSetShaderResources(0, 1, srv); 

Bien sûr, vous avez également besoin d'un échantillonneur ID3D11SamplerState* lié ainsi:

ID3D11SamplerState* m_pSamplerLinear = nullptr; 

D3D11_SAMPLER_DESC sampDesc = {}; 
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; 
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; 
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; 
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; 
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; 
sampDesc.MinLOD = 0; 
sampDesc.MaxLOD = D3D11_FLOAT32_MAX; 
hr = m_pd3dDevice->CreateSamplerState(&sampDesc, &m_pSamplerLinear); 

Ensuite, lorsque vous êtes sur le point de tirer:

m_pImmediateContext->PSSetSamplers(0, 1, &m_pSamplerLinear); 

Je vous recommande fortement de vérifier le DirectX Tool Kit et le tutorials là.

+0

Merci beaucoup Chuck! Je vais certainement regarder dans les pointeurs intelligents COM. – NAKASSEIN