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

1

I am trying to load a texture from a .GLB model in Direct3D 11. The image data is encoded as PNG (I checked the buffer and I could see the file signature in the first 4 bytes). When I try to execute my code, there is an HRESULT returning a WIC "component not found" error (0x88982F50). This is when I try to use WIC from a regular C++ 64-bit Windows API application. Is a component not installed on my machine? Should I use a different approach?

Here is the relevant code:

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
}

Basically, I am trying to translate the PNG into a raw bitmap buffer that I can load into a texture.

I have Visual Studio 2019 installed with latest stable Windows SDK. What could be causing this error? Should I try DirectXTK? Should I just do away with WIC and go libpng? Willing to consider any solution that works.

Bear in mind this is not a UWP application. It's a classic Windows API app, but I borrowed the code from a UWP app.

Here is the code I am borrowing from: https://github.com/Microsoft/glTF-DXViewer

I have read on the WICTextureLoader (DirectXTK) documentation that I would need to call CoInitializeEx to use WIC. Is that the problem? I do not have a call to CoInitialize/CoInitializeEx in my code. But wouldn't CoCreateInstance fail in that case?

c++
visual-studio
c++17
gltf
direct3d11
asked on Stack Overflow Jan 20, 2021 by Dan Tohatan • edited Jan 21, 2021 by Nicol Bolas

1 Answer

1

I found what was wrong. Besides the fact that I was not calling CoInitialize (which I should), I was not referencing the buffer right.

Instead of:

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

I should have done:

ThrowIfFailed(pIWICStream->InitializeFromMemory(reinterpret_cast<BYTE*>(imageBuffer.data()), static_cast<DWORD>(imageBuffer.size())));
answered on Stack Overflow Jan 20, 2021 by Dan Tohatan

User contributions licensed under CC BY-SA 3.0