提问人:Tenebre 提问时间:10/28/2023 更新时间:10/28/2023 访问量:24
如何使用 ID3D11Device::CreateTexture2D 方法使用 mipmap 创建纹理数组
How to use ID3D11Device::CreateTexture2D method to create texture array with mipmaps
问:
我本来打算使用贴图纹理将大量纹理传递到我的着色器,但由于 mip 映射导致的纹理渗色是不可接受的。在做了一些研究之后,我认为纹理数组将是完美的。
下面的代码片段采用全分辨率 (mip 0) 的图像缓冲区数组,以及每个缓冲区的预生成的 mipmap 数组。该代码可以完美地处理一组 mip 0 图像(ArraySize = n;MipLevels = 1) 或单个 mip 0 映像及其关联的 mipmap (ArraySize = 1;MipLevels = n),但如果同时给定数组和 mip 级别 (ArraySize = n;MipLevels = m),返回代码 0x80070057(参数无效)。
我已经阅读并重新阅读了文档,并阅读了网络上我能找到的所有相关帖子,并尝试了我能想到的一切。DirectX 11 文档说它可以完成,所以我一定遗漏了什么。任何帮助将不胜感激。
这是我用来生成纹理的代码。从我读过的所有内容来看,它应该是正确的。
// Setup the description of the texture.
textureDesc.Height = height;
textureDesc.Width = width;
textureDesc.MipLevels = mipLevels;
textureDesc.ArraySize = count;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_IMMUTABLE;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA* subData = new D3D11_SUBRESOURCE_DATA[count*mipLevels];
for( int i = 0; i < count; i++ ) {
subData[i*mipLevels].pSysMem = imageDataArray[i*mipLevels];
subData[i*mipLevels].SysMemPitch = (UINT)(width*4);
subData[i*mipLevels].SysMemSlicePitch = 0;
int w = width;
for( int m = 0; m < mipLevels-1; m++ ) {
w >>= 1;
subData[i*mipLevels+m+1].pSysMem = mipsPtr[i][m];
subData[i*mipLevels+m+1].SysMemPitch = (UINT)(w*4);
subData[i*mipLevels+m+1].SysMemSlicePitch = 0;
}
}
// Create the empty texture.
hResult = device->CreateTexture2D(&textureDesc, (D3D11_SUBRESOURCE_DATA*)subData, &texture);
if( FAILED(hResult) ) {
return false;
}
答:
0赞
Tenebre
10/28/2023
#1
我花了几天时间试图追踪这段代码的问题,并知道它应该可以工作......我知道它有效,因为它可以与一组纹理或单个 mipmap 链一起使用。它归结为一行:
subData[i mipLevels].pSysMem = imageDataArray[i mipLevels]; 应该是: subData[i*mipLevels].pSysMem = imageDataArray[i];
现在它工作了!哈哈。
评论
0赞
Chuck Walbourn
11/2/2023
您可能会发现 DirectXTex 中的代码是一个有用的参考。
评论