我尝试用2d图像填充texture3D切片。 我的结果只能让我回到6张图片中的第一张,就像你在这张照片中看到的那样:
要确保它不是像错误的uvw坐标那样的渲染问题我还会给你uvw坐标的图片:
这里是texture3d的创建代码:
if (ETextureType::Texture3D == TextureType)
{
ID3D11Texture3D* pTexture3D = nullptr;
D3D11_TEXTURE3D_DESC TextureDesc;
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Width = nWidth;
TextureDesc.Height = nHeight;
TextureDesc.MipLevels = nMipMaps;
TextureDesc.Depth = nDepth;
TextureDesc.Usage = D3D11_USAGE_DEFAULT;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
switch (TextureFormat)
{
case ETextureFormat::R8G8B8A8:
{
TextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
}
break;
case ETextureFormat::R32FG32FB32FA32F:
{
TextureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
}
break;
default:
DebugAssertOnce(UNKNOWN_TEXTURE_FORMAT);
}
HRESULT hr = m_pD3D11Device->CreateTexture3D(&TextureDesc, nullptr, &pTexture3D);
if (FAILED(hr))
{
DebugAssertOnce(UNABLE_TO_CREATE_TEXTURE);
return false;
}
if (bCreateShaderResourceView)
{
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory(&SRVDesc, sizeof(SRVDesc));
SRVDesc.Format = TextureDesc.Format;
SRVDesc.Texture3D.MipLevels = TextureDesc.MipLevels;
SRVDesc.Texture3D.MostDetailedMip = 0;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
hr = m_pD3D11Device->CreateShaderResourceView(pTexture3D, &SRVDesc, &pShaderResourceView);
if (FAILED(hr))
{
pTexture3D->Release();
DebugAssertOnce(UNABLE_TO_CREATE_SHADER_RESOURCE_VIEW);
return false;
}
}
else if (bCreateRenderTargetView)
{
ID3D11RenderTargetView* pRenderTargetView = nullptr;
hr = m_pD3D11Device->CreateRenderTargetView(pTexture3D, nullptr, &pRenderTargetView);
if (FAILED(hr))
{
pShaderResourceView->Release();
pTexture3D->Release();
DebugAssertOnce(UNABLE_TO_CREATE_RENDERTARGET_VIEW);
return false;
}
pView = pRenderTargetView;
}
*ppTexture = new CTextureDX11(TextureType, pTexture3D, pShaderResourceView, pView);
return true;
}
以及填充部分:
bool CGraphicsDriverDX11::CreateTexture3DFromImageBuffers(CTexture** ppTexture, const std::vector<CImageBuffer*>* pvecImageBuffers)
{
uint32_t nWidth = pvecImageBuffers->front()->GetWidth();
uint32_t nHeight = pvecImageBuffers->front()->GetHeight();
uint32_t nMipMapLevels = 1;
bool bRet = CreateTexture(ppTexture, nWidth, nHeight, ETextureType::Texture3D, ETextureFormat::R8G8B8A8, nMipMapLevels, false, true, false, static_cast<UINT>(pvecImageBuffers->size()));
if (bRet)
{
ID3D11Texture3D* pD3DTexture = static_cast<ID3D11Texture3D*>((*ppTexture)->GetTexture());
for (size_t nImageBuffer = 0; nImageBuffer < pvecImageBuffers->size(); ++nImageBuffer)
{
uint32_t nIndex = D3D11CalcSubresource(static_cast<UINT>(nImageBuffer), 0, 1);
m_pD3D11DeviceContext->UpdateSubresource(pD3DTexture, nIndex, nullptr, pvecImageBuffers->at(nImageBuffer)->GetData(), nWidth * 4, 0);
}
}
return bRet;
}
我尝试了很多...例如我将此代码更改为texture2DArray并且它工作正常。所以错误不是我的 CImageBuffer 类。 nDepth变量也有正确的值......我想我必须为 UpdateSubresource 使用另一个命令,或者至少以某种方式更改参数。 我也没有在互联网上找到一些例子。 先谢谢你了
答案 0 :(得分:2)
切片中的所有深度纹理在单个子资源中并排显示。您还需要计算给定miplevel的切片中存在多少深度图像。
这为您提供了包含整个切片的子资源索引:
std::max(depth >> level, 1);
这为您提供给定miplevel的切片中的图像数量:
D3D11_MAPPED_SUBRESOURCE.RowPitch
切片中的每个图像在子资源中一个接一个地布置D3D11_MAPPED_SUBRESOURCE.DepthPitch
的间距,切片的总大小(以字节为单位)为 if (metadata.IsVolumemap())
{
assert(metadata.arraySize == 1);
size_t height = metadata.height;
size_t depth = metadata.depth;
for (size_t level = 0; level < metadata.mipLevels; ++level)
{
UINT dindex = D3D11CalcSubresource(level, 0, metadata.mipLevels);
D3D11_MAPPED_SUBRESOURCE mapped;
HRESULT hr = pContext->Map(pSource, dindex, D3D11_MAP_READ, 0, &mapped);
if (FAILED(hr))
// error
auto pslice = reinterpret_cast<const uint8_t*>(mapped.pData);
size_t lines = ComputeScanlines(metadata.format, height);
// For uncompressed images, lines == height
for (size_t slice = 0; slice < depth; ++slice)
{
const Image* img = result.GetImage(level, 0, slice);
const uint8_t* sptr = pslice;
uint8_t* dptr = img->pixels;
for (size_t h = 0; h < lines; ++h)
{
size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch);
memcpy_s(dptr, img->rowPitch, sptr, msize);
sptr += mapped.RowPitch;
dptr += img->rowPitch;
}
pslice += mapped.DepthPitch;
}
pContext->Unmap(pSource, dindex);
if (height > 1)
height >>= 1;
if (depth > 1)
depth >>= 1;
}
}
。
例如,这里有一些来自DirectXTex的代码,因为它更容易阅读。它从捕获的3D体积纹理中读取数据,但填充纹理时逻辑相同。
findViewById