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?
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())));
User contributions licensed under CC BY-SA 3.0