Utilisation du type TextureArray

TextureArray

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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *