我原本打算使用图集纹理将大量纹理传递到我的着色器,但由于 mip 映射而导致的纹理渗色是不可接受的。经过一些研究后,我认为纹理数组是完美的。
下面的代码片段采用全分辨率 (mip 0) 的图像缓冲区数组以及每个缓冲区的预生成 mipmap 数组。该代码可以与一组 mip 0 图像 (ArraySize = n; MipLevels = 1) 或单个 mip 0 图像及其关联的 mipmap (ArraySize = 1; MipLevels = n) 完美配合,但如果满足以下条件,则对 CreateTexture2D( ) 的调用会失败给定数组和 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;
}
我花了几天时间试图找出这段代码的问题,并且知道它应该可以工作...我知道它可以工作,因为它可以与一组纹理或单个 mipmap 链一起工作。它归结为一行:
subData[imipLevels].pSysMem = imageDataArray[imipLevels]; 这应该是: subData[i*mipLevels].pSysMem = imageDataArray[i];
现在可以了!哈哈。