在Metro视觉树中集成DirectX或Direct2D绘图

在Windows 8客户预览版中,开发者可以利用Visual Studio.NET 2011 Beta和SharpDX for Win8 Preview组件,将DirectX或Direct2D绘图注入Metro视觉树。本文将介绍如何实现这一功能,以及相关的代码示例。

项目需求

为了实现这一功能,需要以下工具和组件:

  • Windows 8客户预览版
  • Visual Studio.NET 2011 Beta
  • SharpDX for Win8 Preview组件

建议阅读"Combining XAML andDirectX"文章以获得更深入的理解。

代码使用

"SurfaceImageSource Manager"解决方案提供了一个WinRTC++组件的代码,以及一个C#Metro应用程序的测试代码,展示了如何使用该组件。

KSurfaceImageSourceManager组件的作用是:

  • 根据给定的尺寸(像素宽度、像素高度)生成SurfaceImageSource WinRT类的实例,并在之后注销该实例(NewSurfaceImageSource, DeleteSurfaceImageSource)。
  • 在给定的SurfaceImageSource上初始化和终止Direct2D绘图会话(BeginDraw2D/EndDraw2D)。
  • 在给定的SurfaceImageSource上初始化和终止DirectX绘图会话(BeginDraw3D/EndDraw3D)。
  • 提供KSurfaceImageSourceManager拥有的各种Direct2D/DirectX设备、上下文句柄(Get_ID3D11Device, Get_ID3D11DeviceContext等)。
public ref class KSurfaceImageSourceManager sealed { public: KSurfaceImageSourceManager(); int Get_ID3D11Device(); int Get_ID3D11DeviceContext(); int Get_IDXGIDevice(); int Get_ID2D1Factory1(); int Get_ID2D1Device(); int Get_ID2D1DeviceContext(); SurfaceImageSource^ NewSurfaceImageSource(int pixelWidth, int pixelHeight); void DeleteSurfaceImageSource(SurfaceImageSource^ pSurfaceImageSource); int GetSurfaceImageSourceSize(SurfaceImageSource^ pSurfaceImageSource, int* pWidth, int* pHeight); int ClearSurfaceImageSource(SurfaceImageSource^ pSurfaceImageSource, float R, float G, float B, float A); int BeginDraw2D(SurfaceImageSource^ pSurfaceImageSource, int* pOffsetX, int* pOffsetY, int* pSurfaceWidth, int* pSurfaceHeight); void EndDraw2D(SurfaceImageSource^ pSurfaceImageSource); int BeginDraw3D(SurfaceImageSource^ pSurfaceImageSource, int* pOffsetX, int* pOffsetY, int* pSurfaceWidth, int* pSurfaceHeight); void EndDraw3D(SurfaceImageSource^ pSurfaceImageSource); };

KSurfaceImageSourceManager允许执行Direct2D绘图会话,通过调用BeginDraw2D方法开始,然后通过调用EndDraw2D方法结束。

{ int _hrenderTarget = 0; int _offsetx = 0; int _offsety = 0; int _surfacewidth = 0; int _surfaceheight = 0; try { // initiating a Direct2D drawing session: BeginDraw2D _hrenderTarget = _pKSurfaceImageSourceManager.BeginDraw2D(_pSurfaceImageSource, out _offsetx, out _offsety, out _surfacewidth, out _surfaceheight); // connecting the _hrenderTarget handle returned by BeginDraw2D to a RenderTarget instance RenderTarget _pRenderTarget = new RenderTarget(new IntPtr(_hrenderTarget)); // Direct2D drawing session targetting _pRenderTarget { _pRenderTarget.BeginDraw(); SharpDX.Direct2D1.SolidColorBrush _brush = null; int _left = _offsetx; int _top = _offsety; int _right = _surfacewidth; int _bottom = _surfaceheight; // border _brush = new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, new SharpDX.Color4(1, 0, 0, 1)); _pRenderTarget.FillRectangle(new SharpDX.RectangleF(_left, _top, _right, _bottom), _brush); // fill int _border = 2; float _shade = 0.25f; _brush = new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, new SharpDX.Color4(_shade, _shade, _shade, 1)); _pRenderTarget.FillRectangle(new SharpDX.RectangleF(_left + _border, _top + _border, _right - 2 * _border, _bottom - 2 * _border), _brush); _pRenderTarget.EndDraw(); } } catch (Exception E) { } finally { // terminating the Direct2D drawing session _pKSurfaceImageSourceManager.EndDraw2D(_pSurfaceImageSource); } }

KSurfaceImageSourceManager类提供了Get_ID3D11Device方法,该方法返回一个句柄,用于创建SharpDX.Direct3D11.Device1类的包装实例。

{ int _hdevice = 0; int _pID3D11Texture2D = 0; int _offsetx = 0; int _offsety = 0; int _surfacewidth = 0; int _surfaceheight = 0; try { // retrieving the handle of the ID3D11Device used by _pKSurfaceImageSourceManager // and wrapping it with a SharpDX.Direct3D11.Device1 instance _hdevice = _pKSurfaceImageSourceManager.Get_ID3D11Device(); SharpDX.Direct3D11.Device1 _device = new SharpDX.Direct3D11.Device1(new IntPtr(_hdevice)); // initiating a DirectX drawing session on _pSurfaceImageSource, // and wrapping the returned _pID3D11Texture2D ID3D11Texture2D handle // in a SharpDX.Direct3D11.Texture2D instance _pID3D11Texture2D = _pKSurfaceImageSourceManager.BeginDraw3D(_pSurfaceImageSource, out _offsetx, out _offsety, out _surfacewidth, out _surfaceheight); Texture2D _pTexture2D = new Texture2D(new IntPtr(_pID3D11Texture2D)); // preparing the _device.ImmediateContext context SharpDX.Direct3D11.DeviceContext _context = _device.ImmediateContext; // making _pTexture2D, and therefore the _pSurfaceImageSource // DXGI surface, the _context current RenderTarget var _renderView = new RenderTargetView(_device, _pTexture2D); _context.OutputMerger.SetTargets(_renderView); // clearing the _context context _context.ClearRenderTargetView(_renderView, new Color4(0, 0, 1, 1f)); // IMPORTANT: adapting the context ViewPort to the effective // position (_offsetx, _offsety, _surfacewidth, _surfaceheight) // of the drawing session returned by BeginDraw3D { int _x = _offsetx; int _y = _offsety; int _dx = (_surfacewidth - _offsetx); int _dy = (_surfaceheight - _offsety); _context.Rasterizer.SetViewports(new Viewport(_x, _y, _dx, _dy, 0.0f, 1.0f)); } // Perform some DirectX drawing operations in the SharpDX.Direct3D11.Device1 _device render(_device, _context); } catch (Exception E) { } finally { // Completing the DirectX drawing session _pKSurfaceImageSourceManager.EndDraw3D(_pSurfaceImageSource); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485