"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())));
我正在尝试从 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())));