Emil Johansson
Emil Johansson

Reputation: 1

Making a Cubemap in DX11 from 6 Textures

I want to load in a skysphere, I know how to do it using a dds file, but I want to try and do it from 6 separate texture files. The problem I have is that when I load in the texturecube, only 3 separate textures are visible, the other 3 are not. I'll show you my code and how it looks in Nsight. I am right now using just 6 different uniform colored png files, they are all 512x512 in size.

    std::vector<std::string> paths = {  "../Resources/Textures/posX.png",  "../Resources/Textures/negX.png",
     "../Resources/Textures/posY.png",
     "../Resources/Textures/negY.png",
 "../Resources/Textures/posZ.png", "../Resources/Textures/negZ.png" };


ID3D11Texture2D* cubeTexture = NULL;
WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView = NULL;

//Description of each face
D3D11_TEXTURE2D_DESC texDesc = {};
texDesc.Width = 512;
texDesc.Height = 512;
texDesc.MipLevels = 1;
texDesc.ArraySize = 6;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.CPUAccessFlags = 0;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;

//The Shader Resource view description
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc = {};
SMViewDesc.Format = texDesc.Format;
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = texDesc.MipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;


D3D11_SUBRESOURCE_DATA pData[6] = {};


for (int i = 0; i < 6; i++)
{
    ID3D11Resource* res = nullptr;
    std::wstring pathWString(paths[j].begin(), paths[j].end());

    HRESULT hr = DirectX::CreateWICTextureFromFileEx(Renderer::getDevice(), pathWString.c_str(), 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0,
        WIC_LOADER_FLAGS::WIC_LOADER_DEFAULT,
        &res, 0);
    assert(SUCCEEDED(hr));
    D3D11_MAPPED_SUBRESOURCE destRes = {};
    
    Renderer::getContext()->Map(res, 0, D3D11_MAP_READ, 0, &destRes);
    pData[i].pSysMem = destRes.pData;
    pData[i].SysMemPitch = destRes.RowPitch;
    pData[i].SysMemSlicePitch = destRes.DepthPitch;
    
    Renderer::getContext()->Unmap(res, 0);

    RELEASE_COM(res);
}

Renderer::getDevice()->CreateTexture2D(&texDesc, &pData[0], &cubeTexture);
Renderer::getDevice()->CreateShaderResourceView(cubeTexture, &SMViewDesc, shaderResourceView.GetAddressOf());

When graphics debugging, this is what the cubemap looks like, 3 textures are loaded in twice, overwriting the other 3.

When reading the documentation it says subresource should be relating to mip levels. If I loop 9 times instead of 6, the other 3 images are shown instead of these current 3. All 6 should have unique colors.

What I'm doing in the code is creating a Texture2D Description, a Shader Resource View Descriptuion, then I try to fetch data from imported images using WIC, I put it in a resource then map that to a subresource struct. When looking at the addresses of the subresource, all 6 are always unique so it seems they load in the textures correctly, I have tried moving around the rowpitch, changing the size of the image but it only seems to affect the single images inside the textureCube, it doesn't seem to move around the duplicates if you understand what I mean.

Any help is greatly appreciated.

Upvotes: 0

Views: 1612

Answers (1)

Emil Johansson
Emil Johansson

Reputation: 1

So I found some code from a Frank D Luna example doing something else. Here is the code I use that works, mip levels had to be taken into account. I hope this helps if someone in the future has a similar issue.

    ID3D11Texture2D* cubeTexture = NULL;
    WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView = NULL;

    //Description of each face
    D3D11_TEXTURE2D_DESC texDesc = {};
    
    D3D11_TEXTURE2D_DESC texDesc1 = {};
    //The Shader Resource view description
    D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc = {};

    

    ID3D11Texture2D* tex[6] = { nullptr, nullptr, nullptr,nullptr, nullptr, nullptr };
    for (int i = 0; i < 6; i++)
    {
        std::wstring pathWString(paths[i].begin(), paths[i].end());

        HRESULT hr = DirectX::CreateWICTextureFromFileEx(Renderer::getDevice(), pathWString.c_str(), 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE, 0,
            WIC_LOADER_FLAGS::WIC_LOADER_DEFAULT,
            (ID3D11Resource**)&tex[i], 0);
        assert(SUCCEEDED(hr));
    }

    tex[0]->GetDesc(&texDesc1);

    texDesc.Width = texDesc1.Width;
    texDesc.Height = texDesc1.Height;
    texDesc.MipLevels = texDesc1.MipLevels;
    texDesc.ArraySize = 6;
    texDesc.Format = texDesc1.Format;
    texDesc.CPUAccessFlags = 0;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.Usage = D3D11_USAGE_DEFAULT;
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    texDesc.CPUAccessFlags = 0;
    texDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;

    SMViewDesc.Format = texDesc.Format;
    SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
    SMViewDesc.TextureCube.MipLevels = texDesc.MipLevels;
    SMViewDesc.TextureCube.MostDetailedMip = 0;


    Renderer::getDevice()->CreateTexture2D(&texDesc, NULL, &cubeTexture);
    for (int i = 0; i < 6; i++)
    {
        
        for (UINT mipLevel = 0; mipLevel < texDesc.MipLevels; ++mipLevel)
        {
            D3D11_MAPPED_SUBRESOURCE mappedTex2D;
            HRESULT hr = (Renderer::getContext()->Map(tex[i], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));
            assert(SUCCEEDED(hr));
            Renderer::getContext()->UpdateSubresource(cubeTexture,
                D3D11CalcSubresource(mipLevel, i, texDesc.MipLevels),
                0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);

            Renderer::getContext()->Unmap(tex[i], mipLevel);
        }
        

        
    }

    for (int i = 0; i < 6; i++)
    {
        RELEASE_COM(tex[i]);
    }

    
    Renderer::getDevice()->CreateShaderResourceView(cubeTexture, &SMViewDesc, shaderResourceView.GetAddressOf());

Upvotes: 0

Related Questions