我正在开发一个(通用Windows)c ++ / cx Directx项目,该项目构建为c#UWP项目中使用的dll。
我使用DirectX Toolkit加载纹理。
我已经用它来从文件创建纹理,但现在我需要它来从UWP项目发送的字节数组创建纹理。 但是当试图使用CreateWICTextureFromMemory()时,HRESULT会说 0x88982F50:"找不到该组件"
我能找到关于这个问题的所有内容都表明字节不是正确的图像,但是我在UWP项目中测试了它,在那里我从bingmaps获得了字节数组(它是一个静态地图图像),我可以从这些字节中创建一个工作图像。
是否有人知道我做错了什么?
UWP c#下载代码(获取字节):
var height = $("#imgHeading").height();
if(parseInt($(".header").css('margin-top'), 10) !== height) {
$(".header").css('margin-top', height);
}
Directx C ++代码(失败):
private async Task DownloadTexture()
{
byte[] buffer = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
WebResponse response = await request.GetResponseAsync();
using (Stream stream = response.GetResponseStream())
using (MemoryStream ms = new MemoryStream())
{
stream.CopyTo(ms);
buffer = ms.ToArray();
}
}
catch (Exception exception)
{
Logger.Error($"Could not Download Texture: {exception}");
}
_track3D.SetImage(out buffer[0], (ulong)buffer.Length);
}
UWP C#测试代码(显示图像):
void Track3D::SetImage(uint8_t* ddsData, size_t ddsDataSize)
{
HRESULT result = CreateWICTextureFromMemory(_d3dDevice.Get(), _d3dContext.Get(), ddsData, ddsDataSize, nullptr, _Terrain.ReleaseAndGetAddressOf());
//here it goes wrong
//TODO: use the texture
}
修改
好的,结果是缓冲区中的第一个字节在C ++代码中与从UWP发送时不同。当我将第一个字节更改为C ++代码中的正确值(作为测试)时,正确创建纹理。
这提出了一个问题,为什么第一个字节的值会发生变化? (或者我做错了什么?)
根据要求,函数setImage()在c#中显示如下:
private async void setImage(byte[] buffer) //test
{
try
{
BitmapImage bmpImage = new BitmapImage();
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(buffer.AsBuffer());
stream.Seek(0);
await bmpImage.SetSourceAsync(stream);
}
Image image = new Image();
image.Source = bmpImage;
((Grid)Content).Children.Add(image);
}
catch (Exception exception)
{
Logger.Error($"{exception}");
}
}
(另外,我刚刚意识到参数名称在他们的名字中仍然有' dds'抱歉,在我的代码中会改变它,因为它会产生误导)
答案 0 :(得分:1)
0x88982F50:“无法找到该组件”
这是didDeselect...
,只要WIC无法确定用于文件/二进制文件的格式编解码器,就会发生这种情况。您的问题是您将数据从托管代码传输到本机代码是错误的。
您的互操作方法设置为:
WINCODEC_ERR_COMPONENTNOTFOUND
使用C ++方法签名:
[MethodImpl]
public void __ITrack3DPublicNonVirtuals.SetImage(out byte ddsData, [In] ulong ddsDataSize);
由于void Track3D::SetImage(uint8_t* ddsData, size_t ddsDataSize)
您的第一个参数作为安全数组传递,其长度在第一个元素中。
相反,你应该使用:
out