使用 SharpDX 显示 D3DImage
Show A D3DImage With SharpDX
我打算开发一个应用程序来从文件中获取图像并用 Directx9
显示它。我已经使用了这段代码,但我在 SetBackBuffer
方法上遇到了错误!!
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
private void d3dImage_IsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (d3dImage.IsFrontBufferAvailable)
{
// (Re)initialization:
Bitmap b = new Bitmap(@"C:\Users\newuser\Desktop.jpg");
IntPtr Mysurface = b.GetHbitmap();
if (Mysurface != IntPtr.Zero)
{
d3dImage.Lock();
//Error occurred this line
d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, Mysurface);
d3dImage.Unlock();
CompositionTarget.Rendering += CompositionTarget_Rendering;
}
}
else
{
// Cleanup:
CompositionTarget.Rendering -= CompositionTarget_Rendering;
//Sample.Cleanup();
}
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
// Now that we can get an HWND for the Window, force the initialization
// that is otherwise done when the front buffer becomes available:
d3dImage_IsFrontBufferAvailableChanged(this,
new DependencyPropertyChangedEventArgs());
}
private void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (d3dImage.IsFrontBufferAvailable)
{
d3dImage.Lock();
//Sample.Render();
// Invalidate the whole area:
d3dImage.AddDirtyRect(new Int32Rect(0, 0,
d3dImage.PixelWidth, d3dImage.PixelHeight));
d3dImage.Unlock();
}
}
实际上我想在 WPF
项目中显示 d3dimage
中的图像。谁能帮我?我找不到关于 Directx
和 C# 的好资源!!!
使用 Sharpdx
编辑并出现新错误“'HRESULT: [0x8876086C], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_INVALIDCALL/InvalidCall]
,”
s = new SharpDX.Direct3D9.Surface(IntPtr.Zero);
SharpDX.Direct3D9.Surface.FromFile(s, @"C:\Users\newuser\Desktop.jpg", SharpDX.Direct3D9.Filter.None, 1);
您正在将后台缓冲区设置为 Bitmap
。你不能做这个。后台缓冲区必须是 IDirect3DSurface9
类型。 SetBackBuffer 方法的文档中对此进行了说明。
为了从 C#(托管)使用 DirectX9
(非托管),您需要使用包装器库。你在用一个吗?如果没有,有几个可用。 SlimDX and SharpDX 似乎是最受欢迎的。使用任何包装器库,您可以创建一个 IDirect3DSurface9
,您可以使用 IDirect3DDevice9
将其渲染到,并将该图面附加到您的 WPF 控件。然后,您呈现的内容将出现在控件中。
我认为使用 DirectX
可能无法满足您的需求,但我不确定您项目的整个范围。
使用 SharpDX 的解决方案
我整理了一个使用 SharpDX 在 D3DImage
中显示图像的工作示例。这是非常基本的,不包括正确的错误处理。这只是为了让您朝着正确的方向前进。
第 1 步 - 创建 D3D9 设备
要创建必要的表面,您需要 Direct3D 9 Device
。以下代码将使用 SharpDX 创建 Device
。
//Create the d3d interface.
Direct3D d3d = new Direct3D();
//Get a handle to the WPF window. This is required to create a device.
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
//Create a device. Using standard creation param.
//Width and height have been set to 1 because we wont be using the backbuffer.
//Adapter 0 = default adapter.
PresentParameters presentationParams = new PresentParameters(1,1);
Device d3dDevice = new Device(d3d, 0, DeviceType.Hardware, windowHandle, CreateFlags.HardwareVertexProcessing, presentationParams);
第 2 步 - 创建图像表面
创建一个表面来保存图像数据。
//Create an empty offscreen surface. Use SystemMemory to allow for surface copying.
Surface imageSurface = Surface.CreateOffscreenPlain(d3dDevice, ImageWidthPixels, ImageHeightPixels, Format.A8R8G8B8, Pool.SystemMemory);
//Fill the surface with the image data.
Surface.FromFile(imageSurface, "dx.jpg", Filter.None, 0);
步骤 3 - 创建渲染目标表面
创建充当渲染目标的表面。这是 D3DImage
.
要求的表面类型
//Create the surface that will act as the render target.
//Set as lockable (required for D3DImage)
Surface target = Surface.CreateRenderTarget(d3dDevice, ImageWidthPixels, ImageHeightPixels, Format.A8R8G8B8, MultisampleType.None, 0, true);
步骤 4 - 将图像表面复制到渲染目标。
可以使用 Device.UpdateSurfaces
方法将图像表面复制到渲染目标表面。请注意,在前面的步骤中,两个表面都是使用相同的格式 (A8R8G8B) 创建的。当心这个。表面复印件必备。
//Copy the image surface contents into the target surface.
d3dDevice.UpdateSurface(imageSurface, target);
第 5 步 - 将表面附加到 D3DImage
您现在拥有一个包含您的图像并可与“D3DImage”一起使用的表面。确保使用目标表面,而不是图像源表面。
this.wpfImageSource.Lock();
this.wpfImageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, target.NativePointer);
this.wpfImageSource.AddDirtyRect(new Int32Rect(0, 0, wpfImageSource.PixelWidth, wpfImageSource.PixelHeight));
this.wpfImageSource.Unlock();
结果
图像出现!
我打算开发一个应用程序来从文件中获取图像并用 Directx9
显示它。我已经使用了这段代码,但我在 SetBackBuffer
方法上遇到了错误!!
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
private void d3dImage_IsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (d3dImage.IsFrontBufferAvailable)
{
// (Re)initialization:
Bitmap b = new Bitmap(@"C:\Users\newuser\Desktop.jpg");
IntPtr Mysurface = b.GetHbitmap();
if (Mysurface != IntPtr.Zero)
{
d3dImage.Lock();
//Error occurred this line
d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, Mysurface);
d3dImage.Unlock();
CompositionTarget.Rendering += CompositionTarget_Rendering;
}
}
else
{
// Cleanup:
CompositionTarget.Rendering -= CompositionTarget_Rendering;
//Sample.Cleanup();
}
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
// Now that we can get an HWND for the Window, force the initialization
// that is otherwise done when the front buffer becomes available:
d3dImage_IsFrontBufferAvailableChanged(this,
new DependencyPropertyChangedEventArgs());
}
private void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (d3dImage.IsFrontBufferAvailable)
{
d3dImage.Lock();
//Sample.Render();
// Invalidate the whole area:
d3dImage.AddDirtyRect(new Int32Rect(0, 0,
d3dImage.PixelWidth, d3dImage.PixelHeight));
d3dImage.Unlock();
}
}
实际上我想在 WPF
项目中显示 d3dimage
中的图像。谁能帮我?我找不到关于 Directx
和 C# 的好资源!!!
使用 Sharpdx
编辑并出现新错误“'HRESULT: [0x8876086C], Module: [SharpDX.Direct3D9], ApiCode: [D3DERR_INVALIDCALL/InvalidCall]
,”
s = new SharpDX.Direct3D9.Surface(IntPtr.Zero);
SharpDX.Direct3D9.Surface.FromFile(s, @"C:\Users\newuser\Desktop.jpg", SharpDX.Direct3D9.Filter.None, 1);
您正在将后台缓冲区设置为 Bitmap
。你不能做这个。后台缓冲区必须是 IDirect3DSurface9
类型。 SetBackBuffer 方法的文档中对此进行了说明。
为了从 C#(托管)使用 DirectX9
(非托管),您需要使用包装器库。你在用一个吗?如果没有,有几个可用。 SlimDX and SharpDX 似乎是最受欢迎的。使用任何包装器库,您可以创建一个 IDirect3DSurface9
,您可以使用 IDirect3DDevice9
将其渲染到,并将该图面附加到您的 WPF 控件。然后,您呈现的内容将出现在控件中。
我认为使用 DirectX
可能无法满足您的需求,但我不确定您项目的整个范围。
使用 SharpDX 的解决方案
我整理了一个使用 SharpDX 在 D3DImage
中显示图像的工作示例。这是非常基本的,不包括正确的错误处理。这只是为了让您朝着正确的方向前进。
第 1 步 - 创建 D3D9 设备
要创建必要的表面,您需要 Direct3D 9 Device
。以下代码将使用 SharpDX 创建 Device
。
//Create the d3d interface.
Direct3D d3d = new Direct3D();
//Get a handle to the WPF window. This is required to create a device.
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
//Create a device. Using standard creation param.
//Width and height have been set to 1 because we wont be using the backbuffer.
//Adapter 0 = default adapter.
PresentParameters presentationParams = new PresentParameters(1,1);
Device d3dDevice = new Device(d3d, 0, DeviceType.Hardware, windowHandle, CreateFlags.HardwareVertexProcessing, presentationParams);
第 2 步 - 创建图像表面
创建一个表面来保存图像数据。
//Create an empty offscreen surface. Use SystemMemory to allow for surface copying.
Surface imageSurface = Surface.CreateOffscreenPlain(d3dDevice, ImageWidthPixels, ImageHeightPixels, Format.A8R8G8B8, Pool.SystemMemory);
//Fill the surface with the image data.
Surface.FromFile(imageSurface, "dx.jpg", Filter.None, 0);
步骤 3 - 创建渲染目标表面
创建充当渲染目标的表面。这是 D3DImage
.
//Create the surface that will act as the render target.
//Set as lockable (required for D3DImage)
Surface target = Surface.CreateRenderTarget(d3dDevice, ImageWidthPixels, ImageHeightPixels, Format.A8R8G8B8, MultisampleType.None, 0, true);
步骤 4 - 将图像表面复制到渲染目标。
可以使用 Device.UpdateSurfaces
方法将图像表面复制到渲染目标表面。请注意,在前面的步骤中,两个表面都是使用相同的格式 (A8R8G8B) 创建的。当心这个。表面复印件必备。
//Copy the image surface contents into the target surface.
d3dDevice.UpdateSurface(imageSurface, target);
第 5 步 - 将表面附加到 D3DImage
您现在拥有一个包含您的图像并可与“D3DImage”一起使用的表面。确保使用目标表面,而不是图像源表面。
this.wpfImageSource.Lock();
this.wpfImageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, target.NativePointer);
this.wpfImageSource.AddDirtyRect(new Int32Rect(0, 0, wpfImageSource.PixelWidth, wpfImageSource.PixelHeight));
this.wpfImageSource.Unlock();
结果
图像出现!