在d3d11中为cubemap自动生成mipmap

时间:2017-08-22 07:50:59

标签: c++ texture-mapping direct3d11

最近我遇到了在d3d11中为立方体贴图创建mipmap的问题。让DirectX框架为立方体贴图中的每个平面生成每个lod的图像的想法,但似乎我应该为它们手动创建。

为纹理生成mips的正确方法是什么?我必须自己生成它们,还是有办法让d3d来做它们?

这就是我创建纹理的方式:

void TextureCube::Initialize(Renderer & device, CubemapRef cubemap)
{
    HRESULT result;

    BitmapRef bitmap = cubemap->GetPosX(); //assume that everything is equal there
    int ch = bitmap->GetCh();
    DXGI_FORMAT fmt = bitmapformats[ch % 4];

    m_format = fmt;

    m_w = cubemap->GetPosX()->GetX();
    m_h = cubemap->GetPosX()->GetY();
    m_ch = (m_ch == 3) ? 4 : ch; // if bitmap has 3 component per pixel, we'll force it to 4 and convert it before creating initial data
    m_chW = 1;


    D3D11_TEXTURE2D_DESC textureDesc;
    ZeroMemory(&textureDesc, sizeof(textureDesc));
    textureDesc.Width = m_w;
    textureDesc.Height = m_h;
    textureDesc.MipLevels = 0;
    textureDesc.ArraySize = 6;
    textureDesc.Format = m_format;
    textureDesc.SampleDesc.Count = 1;
    textureDesc.Usage = D3D11_USAGE_DEFAULT;
    textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE| D3D11_BIND_RENDER_TARGET;
    textureDesc.CPUAccessFlags = 0;
    textureDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS;

    // --- setup inital data 
    D3D11_SUBRESOURCE_DATA pData[6];

    for (int i = 0; i < 6; i++)
    {
        void *inData = cubemap->GetBitmap(i)->GetData();
        void *outData = inData;
        if (cubemap->GetBitmap(i)->GetCh() == 3) {
            outData = new unsigned int[m_w * m_h];
            CopyChannel3To4(inData, outData, m_w, m_h);
        }
        pData[i].pSysMem = outData;
        pData[i].SysMemPitch = m_w * 4;
        pData[i].SysMemSlicePitch = 0;
    }

    ID3D11Texture2D *ppTex = nullptr;
    result = device->CreateTexture2D(&textureDesc, pData, &ppTex);

    // cleanup converted data 
    for (int i = 0; i < 6; i++)
        if (pData[i].pSysMem != cubemap->GetBitmap(i)->GetData())
            delete pData[i].pSysMem;

    if (FAILED(result)) 
        throw EX_HRESULT(TextureCreateException, result);

    m_pTexture = ppTex;

    // --- srv
    D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
    ZeroMemory(&shaderResourceViewDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
    shaderResourceViewDesc.Format = m_format;
    shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;

    shaderResourceViewDesc.TextureCube.MostDetailedMip = 0;
    shaderResourceViewDesc.TextureCube.MipLevels = -1;

    result = device->CreateShaderResourceView(m_pTexture, &shaderResourceViewDesc, &m_pResourceView);

    if (FAILED(result)) 
        throw EX_HRESULT(TextureCreateException, result);

}

0 个答案:

没有答案