【问题标题】:D3D11: Creating a cube map from 6 imagesD3D11:从 6 个图像创建立方体贴图
【发布时间】:2013-10-22 05:47:49
【问题描述】:

如何在 D3D11 中从 6 个图像创建立方体贴图?我发现的所有示例都只使用一个 .dds。具体来说,如何上传立方体纹理的各个面?

【问题讨论】:

    标签: direct3d texture-mapping


    【解决方案1】:

    它是这样工作的:

    D3D11_TEXTURE2D_DESC texDesc;
    texDesc.Width = description.width;
    texDesc.Height = description.height;
    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;
    
    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];
    std::vector<vector4b> d[6]; // 6 images of type vector4b = 4 * unsigned char
    
    for (int cubeMapFaceIndex = 0; cubeMapFaceIndex < 6; cubeMapFaceIndex++)
    {   
        d[cubeMapFaceIndex].resize(description.width * description.height);
    
        // fill with red color  
        std::fill(
            d[cubeMapFaceIndex].begin(), 
            d[cubeMapFaceIndex].end(), 
            vector4b(255,0,0,255));
    
        pData[cubeMapFaceIndex].pSysMem = &d[cubeMapFaceIndex][0];// description.data;
        pData[cubeMapFaceIndex].SysMemPitch = description.width * 4;
        pData[cubeMapFaceIndex].SysMemSlicePitch = 0;
    }
    
    HRESULT hr = renderer->getDevice()->CreateTexture2D(&texDesc, 
        description.data[0] ? &pData[0] : nullptr, &m_pCubeTexture);
    assert(hr == S_OK);
    
    hr = renderer->getDevice()->CreateShaderResourceView(
        m_pCubeTexture, &SMViewDesc, &m_pShaderResourceView);
    assert(hr == S_OK);
    

    这会为 CubeMap 创建六个“红色”图像。

    【讨论】:

    【解决方案2】:

    我知道这个问题很老了,而且已经有了解决方案。

    这是一个代码示例,它从磁盘加载 6 个纹理并将它们组合成一个立方体贴图:

    前提条件:

    ID3D11ShaderResourceView* srv = 0;
    ID3D11Resource* srcTex[6];
    

    指向 ShaderResourceView 的指针和一个由磁盘中的六个纹理填充的数组。我使用的顺序是右、左、上、下、前、后。

    // Each element in the texture array has the same format/dimensions.
    D3D11_TEXTURE2D_DESC texElementDesc;
    ((ID3D11Texture2D*)srcTex[0])->GetDesc(&texElementDesc);
    
    D3D11_TEXTURE2D_DESC texArrayDesc;
    texArrayDesc.Width = texElementDesc.Width;
    texArrayDesc.Height = texElementDesc.Height;
    texArrayDesc.MipLevels = texElementDesc.MipLevels;
    texArrayDesc.ArraySize = 6;
    texArrayDesc.Format = texElementDesc.Format;
    texArrayDesc.SampleDesc.Count = 1;
    texArrayDesc.SampleDesc.Quality = 0;
    texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
    texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    texArrayDesc.CPUAccessFlags = 0;
    texArrayDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
    
    ID3D11Texture2D* texArray = 0;
    if (FAILED(pd3dDevice->CreateTexture2D(&texArrayDesc, 0, &texArray)))
        return false;
    
    // Copy individual texture elements into texture array.
    ID3D11DeviceContext* pd3dContext;
    pd3dDevice->GetImmediateContext(&pd3dContext);
    D3D11_BOX sourceRegion;
    
    //Here i copy the mip map levels of the textures
    for (UINT x = 0; x < 6; x++)
    {
        for (UINT mipLevel = 0; mipLevel < texArrayDesc.MipLevels; mipLevel++)
        {
            sourceRegion.left = 0;
            sourceRegion.right = (texArrayDesc.Width >> mipLevel);
            sourceRegion.top = 0;
            sourceRegion.bottom = (texArrayDesc.Height >> mipLevel);
            sourceRegion.front = 0;
            sourceRegion.back = 1;
    
            //test for overflow
            if (sourceRegion.bottom == 0 || sourceRegion.right == 0)
                break;
    
            pd3dContext->CopySubresourceRegion(texArray, D3D11CalcSubresource(mipLevel, x, texArrayDesc.MipLevels), 0, 0, 0, srcTex[x], mipLevel, &sourceRegion);
        }
    }
    
    // Create a resource view to the texture array.
    D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
    viewDesc.Format = texArrayDesc.Format;
    viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
    viewDesc.TextureCube.MostDetailedMip = 0;
    viewDesc.TextureCube.MipLevels = texArrayDesc.MipLevels;
    
    if (FAILED(pd3dDevice->CreateShaderResourceView(texArray, &viewDesc, &srv)))
        return false;
    

    如果有人再次阅读这个问题,不妨试试这个。警告:这个函数不是线程安全的,因为我必须使用 deviceContext。

    【讨论】:

    • 这是正确的吗?我想我必须将 MiscFlags 设置为 D3D11_RESOURCE_MISC_TEXTURECUBE
    • 是的,你是对的,在我的原始代码中,我有一个条件:texArrayDesc.MiscFlags = isCubeMap? D3D11_RESOURCE_MISC_TEXTURECUBE:0; isCubeMap 是创建纹理的函数参数,我将编辑我的答案。 THX
    猜你喜欢
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多