用DX11从6个纹理制作立方体贴图



我想在skysphere中加载,我知道如何使用dds文件来完成,但我想尝试从6个单独的纹理文件中完成。我遇到的问题是,当我加载texturecbe时,只有3个单独的纹理可见,其他3个不可见。我将向您展示我的代码以及它在Nsight中的外观。我现在只使用6个不同的统一颜色的png文件,它们的大小都是512x512。

    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());

当图形调试时,这就是立方体映射的样子,3个纹理被加载两次,覆盖其他3个。

当阅读文档时,它说子资源应该与mip级别相关。如果I循环9次而不是6次,则显示其他3个图像而不是当前的3个图像。所有6个都应该有独特的颜色。

我在代码中所做的是创建一个Texture2D描述,一个着色器资源视图描述,然后我尝试使用WIC从导入的图像中获取数据,我将其放入资源中,然后将其映射到子资源结构。当查看子资源的地址时,所有6个地址都是唯一的,所以它们似乎正确地加载了纹理。我尝试过在球场上移动,改变图像的大小,但它似乎只影响textureCube中的单个图像,如果你理解我的意思,它似乎不会在重复的图像上移动。

非常感谢您的帮助。

所以我从Frank D Luna的一个例子中找到了一些做其他事情的代码。这是我使用的有效代码,必须考虑mip级别。如果将来有人遇到类似的问题,我希望这会有所帮助。

    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());

最新更新