"Component not found" 尝试加载 PNG 纹理时出错 (Direct3D 11)

"Component not found" error when I try to load a PNG texture (Direct3D 11)

我正在尝试从 Direct3D 11 中的 .GLB 模型加载纹理。图像数据编码为 PNG(我检查了缓冲区,我可以在前 4 个字节中看到文件签名)。当我尝试执行我的代码时,有一个 HRESULT 返回 WIC“未找到组件”错误 (0x88982F50)。这是我尝试从常规 C++ 64 位 Windows API 应用程序使用 WIC 的时候。我的机器上没有安装组件吗?我应该使用不同的方法吗?

相关代码如下:

using namespace std;
using namespace Microsoft::glTF;
using namespace Microsoft::WRL;

//...

void ModelRenderer::CreateTexture(Texture& tex, GLBResourceReader& binaryReader)
{
    string bufferViewId = cModel.images[tex.imageId].bufferViewId;
    string bufferId = cModel.bufferViews[bufferViewId].bufferId;
    Buffer* imageData = (Buffer*)&cModel.buffers[bufferId] + cModel.bufferViews[bufferViewId].byteOffset;
    vector<byte> imageBuffer = binaryReader.ReadBinaryData(cModel, cModel.images[tex.imageId]);

    // Create texture.
    D3D11_TEXTURE2D_DESC txtDesc = {};
    txtDesc.MipLevels = txtDesc.ArraySize = 1;

    txtDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    txtDesc.SampleDesc.Count = 1;
    txtDesc.Usage = D3D11_USAGE_IMMUTABLE;
    txtDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

    uint32_t width = 0;
    uint32_t height = 0;
    
    /*
    TODO - Figure out why CreateDecoderFromStream is giving us an error
    ComPtr<IWICImagingFactory> wicFactory;
    ThrowIfFailed(CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&wicFactory)));

    IWICStream* pIWICStream;
    // Create a WIC stream to map onto the memory.
    ThrowIfFailed(wicFactory->CreateStream(&pIWICStream));

    // Initialize the stream with the memory pointer and size.
    ThrowIfFailed(pIWICStream->InitializeFromMemory(reinterpret_cast<BYTE*>(&imageBuffer), static_cast<DWORD>(imageBuffer.size())));

    ComPtr<IWICBitmapDecoder> decoder;
//THE ERROR IS HERE:
    ThrowIfFailed(wicFactory->CreateDecoderFromStream(pIWICStream, nullptr, WICDecodeMetadataCacheOnLoad, decoder.GetAddressOf()));

    ComPtr<IWICBitmapFrameDecode> frame;
    ThrowIfFailed(decoder->GetFrame(0, frame.GetAddressOf()));

    ThrowIfFailed(frame->GetSize(&width, &height));
    */
    txtDesc.Width = width;
    txtDesc.Height = height;

    D3D11_SUBRESOURCE_DATA initialData = {};
    //The rest has been removed as it is still work in progress & not relevant
}

基本上,我正在尝试将 PNG 转换为可以加载到纹理中的原始位图缓冲区。

我安装了 Visual Studio 2019 和最新稳定的 Windows SDK。是什么导致了这个错误?我应该试试 DirectXTK 吗?我应该取消 WIC 并使用 libpng 吗?愿意考虑任何可行的解决方案。

请记住,这是不是 UWP 应用程序。这是一个经典的 Windows API 应用程序,但我从 UWP 应用程序中借用了代码。

这是我借用的代码:https://github.com/Microsoft/glTF-DXViewer

我已阅读 WICTextureLoader (DirectXTK) 文档,我需要调用 CoInitializeEx 才能使用 WIC。那是问题所在吗?我的代码中没有调用 CoInitialize/CoInitializeEx。但是在那种情况下 CoCreateInstance 不会失败吗?

我发现哪里出了问题。除了我没有调用 CoInitialize(我应该调用)之外,我没有正确引用缓冲区。

而不是:

ThrowIfFailed(pIWICStream->InitializeFromMemory(reinterpret_cast<BYTE*>(&imageBuffer), static_cast<DWORD>(imageBuffer.size())));

我应该做的:

ThrowIfFailed(pIWICStream->InitializeFromMemory(reinterpret_cast<BYTE*>(imageBuffer.data()), static_cast<DWORD>(imageBuffer.size())));