0
\$\begingroup\$

these day i am working with texture2d array with mipmapping. so this is how i tried so far. my approach

  1. load multiple(not textureArray form) textures that i want to set as array from computer folder.
  2. Ceate Texture2dArray interface with mipmap setting
  3. using staging texture, copy multiple texture and write into the interface
  4. Create SRV and Call 'GenerateMipMap' function.

and the result is that only first element of texture has right color values along with all mipmap level. but other elemets only have black, although they have same mipmap level which is black too.

this is my code(i checked all HRESULT/DirectX Debug checking, all good)

std::string key = ...; 
std::vector<std::string> fileNames = ...; 
UINT miplevel = ...;

    const UINT spriteCount = fileNames.size();

    std::vector<ID3D11Resource*> ori_resources(spriteCount);
    for (int i = 0; i < spriteCount; ++i)// 1------------------------------------
    {
        ID3D11Resource* newResource = nullptr;
        std::wstring wFileName = std::wstring(fileNames[i].begin(), fileNames[i].end());
        r_assert(
            DirectX::CreateWICTextureFromFile(
                DX_Device,
                (L"Data\\Texture\\" + wFileName).c_str(),
                &newResource,
                nullptr)
        );

        ori_resources[i] = newResource;

    }

    ID3D11Texture2D* newTex = nullptr; 
        r_assert(
            ori_resources[0]->QueryInterface(IID_ID3D11Texture2D, (void**)&newTex)
        );
    D3D11_TEXTURE2D_DESC ori_desc;
        newTex->GetDesc(&ori_desc);


    D3D11_TEXTURE2D_DESC arr_desc; // 2------------------------------------------
    arr_desc.Format = ori_desc.Format;
    arr_desc.ArraySize = spriteCount;
    arr_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
    arr_desc.CPUAccessFlags = 0;
    arr_desc.Width = ori_desc.Width;
    arr_desc.Height = ori_desc.Height;
    arr_desc.MipLevels = miplevel;
    arr_desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
    arr_desc.SampleDesc.Count = 1;
    arr_desc.SampleDesc.Quality = 0;
    arr_desc.Usage = D3D11_USAGE_DEFAULT;

    ComPtr<ID3D11Texture2D> arrTex;
    r_assert(
        DX_Device->CreateTexture2D(
            &arr_desc, nullptr, arrTex.GetAddressOf())
    );

    for (int i = 0; i < spriteCount; ++i) // 3-----------------------------------
    {
        ComPtr<ID3D11Texture2D> stagTex;
        D3D11_TEXTURE2D_DESC stagDesc = ori_desc;
        stagDesc.BindFlags = 0;
        stagDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
        stagDesc.Usage = D3D11_USAGE_STAGING;
        r_assert(DX_Device->CreateTexture2D(&stagDesc, nullptr, &stagTex));

        // use staging texture to read and paste image
        // because for copying, we should match miplevels between dest and src
        DX_DContext->CopyResource(stagTex.Get(), ori_resources[i]);

        D3D11_MAPPED_SUBRESOURCE mapped;
        r_assert(DX_DContext->Map(stagTex.Get(), 0, D3D11_MAP_READ, 0, &mapped));
        // use 'UINT' because format of images from file is one of 8888
        UINT* arr = new UINT[(mapped.RowPitch/sizeof(UINT)) * ori_desc.Height];
        ZeroMemory(arr, mapped.RowPitch * ori_desc.Height);
        CopyMemory(arr, mapped.pData, mapped.RowPitch * ori_desc.Height);
        DX_DContext->Unmap(stagTex.Get(), 0);

        DX_DContext->UpdateSubresource(
            arrTex.Get(), i, 
            nullptr, 
            arr, 
            mapped.RowPitch, mapped.DepthPitch);
        delete[] arr;
    }


    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; // 4--------------------------------
    srvDesc.Format = ori_desc.Format;
    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    srvDesc.Texture2DArray.ArraySize = spriteCount;
    srvDesc.Texture2DArray.FirstArraySlice = 0;
    srvDesc.Texture2DArray.MipLevels = miplevel;
    srvDesc.Texture2DArray.MostDetailedMip = 0;
    ID3D11ShaderResourceView* integratedSRV = nullptr;
    r_assert(DX_Device->CreateShaderResourceView(arrTex.Get(), &srvDesc, &integratedSRV));
    DX_DContext->GenerateMips(integratedSRV);


    SRVs.insert(std::pair<std::string, ID3D11ShaderResourceView*>(key, integratedSRV));

any advice would be really helpful for me now. thanks

\$\endgroup\$
0
\$\begingroup\$
DX_DContext->UpdateSubresource(
            arrTex.Get(), i, 
            nullptr, 
            arr, 
            mapped.RowPitch, mapped.DepthPitch);

subresource parameter was wrong. a subresource is actually combination of mipmap level and array element. so we can use the formula 'curArrayelementIdx*totalmiplevel + curmiplevel' or d3d11calcsubresource

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.