Intro :
Souvent à l’étape pixel shader, on a besoin d’accéder à plusieurs textures en même temps.
Prérequis :
– Savoir lire du C++
– Savoir initialiser DirectX
Explications :
Voici une fonction qui créé un objet Texture2D :
ID3D10Texture2D* CreateTexture(const std::string& sImageFileName)
{
ID3D10Texture2D* pLoadedTexture = nullptr;
D3DX10_IMAGE_LOAD_INFO loadinfo;
ZeroMemory(&loadinfo, sizeof(D3DX10_IMAGE_LOAD_INFO));
loadinfo.Width = D3DX10_FROM_FILE;
loadinfo.Height = D3DX10_FROM_FILE;
loadinfo.Depth = D3DX10_FROM_FILE;
loadinfo.FirstMipLevel = 0;
loadinfo.MipLevels = D3DX10_FROM_FILE;
loadinfo.Usage = D3D10_USAGE_STAGING;
loadinfo.BindFlags = 0;
loadinfo.CpuAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
loadinfo.MiscFlags = 0;
loadinfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
loadinfo.Filter = D3DX10_FILTER_NONE;
loadinfo.MipFilter = D3DX10_FILTER_NONE;
loadinfo.pSrcInfo = 0;
D3DX10CreateTextureFromFileA(D3D10_RENDERER->GetDevice(),
sImageFileName.c_str(), &loadinfo, 0, (ID3D10Resource**)&pLoadedTexture, 0);
return pLoadedTexture;
}
Voici une fonction qui créé un objet Texture2D assemblé et combiné de plusieurs Texture2D :
ID3D10Texture2D* CreateTextureArray(std::vector<ID3D10Texture2D*>& textures)
{
if (textures.size() == 0)
{
return nullptr;
}
ID3D10Texture2D* pTexturesArray = nullptr;
D3D10_TEXTURE2D_DESC textElementDesc;
ZeroMemory(&textElementDesc, sizeof(D3D10_TEXTURE2D_DESC));
textures[0]->GetDesc(&textElementDesc);
D3D10_TEXTURE2D_DESC textArrayDesc;
textArrayDesc.Width = textElementDesc.Width;
textArrayDesc.Height = textElementDesc.Height;
textArrayDesc.MipLevels = textElementDesc.MipLevels;
textArrayDesc.ArraySize = textures.size();
textArrayDesc.Format = textElementDesc.Format;
textArrayDesc.SampleDesc.Count = 1;
textArrayDesc.SampleDesc.Quality = 0;
textArrayDesc.Usage = D3D10_USAGE_DEFAULT;
textArrayDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
textArrayDesc.CPUAccessFlags = 0;
textArrayDesc.MiscFlags = 0;
D3D10_RENDERER->GetDevice()->CreateTexture2D(&textArrayDesc, 0, &pTexturesArray);
// On copie toutes les textures dans le tableau !
for (uint16 i = 0; i < textures.size(); i++)
{
for (uint16 j = 0; j < textElementDesc.MipLevels; j++)
{
D3D10_MAPPED_TEXTURE2D mappedTex2D;
ID3D10Texture2D* pCurrentTexture = textures[i];
pCurrentTexture->Map(j, D3D10_MAP_READ, 0, &mappedTex2D);
uint32 c = D3D10CalcSubresource(j, i, textElementDesc.MipLevels);
D3D10_RENDERER->GetDevice()->UpdateSubresource(pTexturesArray, c,
0, mappedTex2D.pData, mappedTex2D.RowPitch, 0);
pCurrentTexture->Unmap(j);
}
}
return pTexturesArray;
}
Voici la fonction qui créée une texture ressource shader pour le programme HLSL :
ID3D10ShaderResourceView* FontTextManager::GetTextureRVArray(ID3D10Texture2D* pTexArray)
{
if (pTexArray == nullptr)
{
return nullptr;
}
ID3D10ShaderResourceView* pArrayRV = nullptr;
D3D10_SHADER_RESOURCE_VIEW_DESC viewDesc;
ZeroMemory(&viewDesc, sizeof(D3D10_SHADER_RESOURCE_VIEW_DESC));
D3D10_TEXTURE2D_DESC textArrayDesc;
pTexArray->GetDesc(&textArrayDesc);
viewDesc.Format = textArrayDesc.Format;
viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2DARRAY;
viewDesc.Texture1DArray.MostDetailedMip = 0;
viewDesc.Texture1DArray.MipLevels = textArrayDesc.MipLevels;
viewDesc.Texture1DArray.FirstArraySlice = 0;
viewDesc.Texture1DArray.ArraySize = textArrayDesc.ArraySize;
D3D10_RENDERER->GetDevice()->CreateShaderResourceView(pTexArray, &viewDesc, &pArrayRV);
return pArrayRV;
}
Utilisation :
std::vector<ID3D10Texture2D*> textures;
textures.push_back( CreateTexture("UneImage.png") ) ;
textures.push_back( CreateTexture("UneAutreImage.png") ) ;
ID3D10Texture2D* pTextureArray = CreateTextureArray(textures);
// On libère la mémoire
for (uint32 i = 0; i < textures.size(); i++)
{
ID3D10Texture2D* pCurrentTexture = textures[i];
SAFE_RELEASE(pCurrentTexture);
}
// Cette ressource est prête à être utilisée par un programme HLSL
ID3D10ShaderResourceView* pRVArray = GetTextureRVArray(pTextureArray);
SAFE_RELEASE(pTextureArray);
Résumé :
Nous avons présenté une façon d’accéder à une variable représentant un tableau de textures directement dans le shader !
Références :
– Franck D.Luna – DirectX 10

