2013-10-14 91 views

回答

5

它的工作原理是這樣的:

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

此創建六個 「紅色」 的圖像,爲立方體貼圖。

+0

如果您想在此處使用文件中的紋理而不是紅色填充立方體貼圖數據,該怎麼辦? – PinkTurtle

+1

注意:使用像http://openil.sourceforge.net/或http://cimg.eu/的圖像加載器來初始化您的紋理CPU端。 – PinkTurtle

+0

如何加載紋理數據:https://bitbucket.org/Anteru/d3d12sample/src/bf8c36ada43287ef3d786d99bc0d4d4b9eb9f394/inc/ImageIO.h?at=default – Vertexwahn

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。

+1

這是正確的嗎?我以爲我必須設置MiscFlags D3D11_RESOURCE_MISC_TEXTURECUBE – Thomas

+1

是啊你是對的,在我的原始代碼中我有一個條件: texArrayDesc.MiscFlags = isCubeMap? D3D11_RESOURCE_MISC_TEXTURECUBE:0; isCubeMap是創建紋理的函數參數,我將編輯我的答案。謝謝 – kaiser