现在的位置: 首页 > 综合 > 正文

SurfaceImageSource – XAML UI 中的 DirectX 岛

2013年05月04日 ⁄ 综合 ⁄ 共 6772字 ⁄ 字号 评论关闭

微软官方博客http://blogs.msdn.com/b/windowsappdev_cn/archive/2012/03/22/xaml-directx.aspx如此说:

作为合并 DirectX 和 XAML 的第一个选项,您可使用全新的 SurfaceImageSource XAML 类型来将 DirectX 内容区域添加至 Metro 风格 XAML 应用程序之中。这种类型的实例可为您提供共享的 DirectX 表面,您可使用 DirectX 的所有功能来绘制该表面,然后将该表面组合至 XAML 应用程序界面的其余部分之中。

当您希望使用 DirectX 来绘制隶属于较大 XAML UI 的特定组件时,这一选项将对您大有裨益。例如,当您向照片应用复杂图像效果或创建高性能 3D 数据可视化时,您就可能希望使用 SurfaceImageSource。

MSDN上提供了一个例子Direct2D interpolation modes sample演绎了SurfaceImageSource最基本的用法(2D, 3D)。那么,如何来用SurfaceImageSource来显示复杂的内容呢?

本文演示利用SurfaceImageSource如何在一张背景图上显示文字,画一些东西,并保存为一张图片。代码见http://download.csdn.net/detail/hylaking/4978437

第一步,从Windows::UI::Xaml::Media::Imaging::SurfaceImageSource继承

//
// ZebraImageSource,h
//


#pragma once

#include <dxgi.h>
#include <dxgi1_2.h>
#include <d2d1_1.h>
#include <d3d11_1.h>

#include "windows.ui.xaml.media.dxinterop.h"


#include <d2d1effects.h>
#include <dwrite_1.h>
#include <wincodec.h>
#include <math.h>
//#include <DirectXMath.h>
#include <ppltasks.h>
#include <shcore.h>
#include <collection.h>
#include <assert.h>
#include <agile.h>
#include <guiddef.h>

#include <list>
#include <vector>
#include <sstream>

#include "ZebraUtils.h"
#include "imagerenderer.h"
#include "TextRenderer.h"


namespace ZebraDX
{

	public ref class ZebraImageSource sealed : Windows::UI::Xaml::Media::Imaging::SurfaceImageSource
	{
	internal:
		ZebraImageSource(int pixelWidth, int pixelHeight, bool isOpaque);
		//~ZebraImageSource(void);
        void BeginDraw(Windows::Foundation::Rect updateRect);
        void BeginDraw()    { BeginDraw(Windows::Foundation::Rect(0, 0, (float)m_width, (float)m_height)); }
        void EndDraw();

		void SetDpi(float dpi);
		void Render(void);

		void Clear(Windows::UI::Color color);
		void FillSolidRect(Windows::UI::Color color, Windows::Foundation::Rect rect);

		void LoadImage(Windows::Storage::Streams::IRandomAccessStream^ randomAccessStream);

	private protected:
		void CreateDeviceIndependentResources();
		void CreateDeviceResources();

		Microsoft::WRL::ComPtr<ISurfaceImageSourceNative>   m_sisNative;

		// Direct3D device
		Microsoft::WRL::ComPtr<ID3D11Device>                m_d3dDevice;

		// Direct2D objects
		Microsoft::WRL::ComPtr<ID2D1Device>                 m_d2dDevice;
		Microsoft::WRL::ComPtr<ID2D1DeviceContext>          m_d2dContext;

		int                                                 m_width;
		int                                                 m_height;

	protected private:
		void SaveBitmapToStream(
			_In_ ID2D1Bitmap1* d2dBitmap,
			_In_ IWICImagingFactory2* wicFactory2,
			_In_ ID2D1DeviceContext* d2dContext,
			_In_ REFGUID wicFormat,
			_In_ IStream* stream
			);

		Microsoft::WRL::ComPtr<IDWriteFactory1>				m_dwriteFactory;
		Microsoft::WRL::ComPtr<IWICImagingFactory2>			m_wicFactory;
		//void CreateWindowSizeDependentResources(void);
		Microsoft::WRL::ComPtr<IDXGISwapChain1>				m_swapChain;
		Microsoft::WRL::ComPtr<ID2D1Bitmap1>				m_d2dTargetBitmap;

	public:
		void CreateWindowSizeDependentResources(void);
		void SaveAsImage(Windows::Storage::Streams::IRandomAccessStream^ randomAccessStream, Platform::String^ fileType);

	private:
		void CopyAsBuffer(void);

		Microsoft::WRL::ComPtr<ID2D1SolidColorBrush>		m_blackBrush;
		Microsoft::WRL::ComPtr<IDWriteTextFormat>			m_textFormat;
		Microsoft::WRL::ComPtr<IDWriteTypography>			m_textTypography;

		void Draw(void);

	public:
		void SetText(Platform::String^ text);

	private:
		ImageRenderer^ m_imageRendererBk;
		ImageRenderer^ m_imageRenderPhoto;
		TextRenderer^ m_textTopic;
		TextRenderer^ m_textBody;
	};

}

// 
// 
// ImageRenderer.h
//

#pragma once#include <dxgi.h>#include <dxgi1_2.h>#include <d2d1_1.h>#include <d3d11_1.h>#include <d2d1effects.h>#include <dwrite.h>#include <dwrite_1.h>#include <wincodec.h>#include <ppltasks.h>#include <shcore.h>#include
<collection.h>#include <assert.h>#include <agile.h>#include <guiddef.h>#include <math.h>#include <list>#include <vector>#include <sstream>#include "windows.ui.xaml.media.dxinterop.h"namespace ZebraDX{ref class ImageRenderer{internal: void CreateDeviceIndependentResources(Microsoft::WRL::ComPtr<IWICImagingFactory2>
wicFactory); void CreateDeviceResources(Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2dContext); void CreateWindowSizeDependentResources(float dpi); void Render();void LoadImage(Windows::Storage::Streams::IRandomAccessStream^ randomAccessStream);void LoadImage(Platform::String
^ pstrImageFileName);void SetEffectIntensity(float value);void Reset();void SetBounds(Windows::Foundation::Rect bounds);private: void UpdateImageZoom(); // Resources shared with PostcardRenderer. Microsoft::WRL::ComPtr<IWICImagingFactory2> m_wicFactory; Microsoft::WRL::ComPtr<ID2D1DeviceContext>
m_d2dContext; float m_dpi; // Resources specific to this renderer. Microsoft::WRL::ComPtr<ID2D1Effect> m_bitmapSourceEffect; D2D1_SIZE_U m_imagePixelSize; D2D1_SIZE_F m_imageSizeDips; float m_imageZoomFactor; Microsoft::WRL::ComPtr<ID2D1Effect> m_saturationEffect;Windows::Foundation::Rect
m_rectBounds;};}


//
// TextRenderer.h
// 
#pragma once

#include <dxgi.h>
#include <dxgi1_2.h>
#include <d2d1_1.h>
#include <d3d11_1.h>

#include <d2d1effects.h>
#include <dwrite.h>
#include <dwrite_1.h>

#include <wincodec.h>
#include <ppltasks.h>
#include <shcore.h>
#include <collection.h>
#include <assert.h>
#include <agile.h>
#include <guiddef.h>

#include <math.h>
#include <list>
#include <vector>
#include <sstream>

#include "windows.ui.xaml.media.dxinterop.h"

namespace ZebraDX
{

	ref class TextRenderer
	{
	internal:
		void CreateDeviceIndependentResources(Microsoft::WRL::ComPtr<IWICImagingFactory2> wicFactory,  Microsoft::WRL::ComPtr<IDWriteFactory1> dwriteFactory);
		void CreateDeviceResources(Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2dContext);
		void CreateWindowSizeDependentResources(float dpi);

		void Render();
		void Render(Windows::Foundation::Point point, Platform::String^ text);

		void SetText(Platform::String^ text);
		void SetBounds(Windows::Foundation::Rect bounds);
		void SetColor(D2D1::ColorF color);

		void SetFont(Platform::String^	fontName, 
			 FLOAT						fontSize = 64.0f,
			 DWRITE_TEXT_ALIGNMENT		textAlignment = DWRITE_TEXT_ALIGNMENT_LEADING, 
			 DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment = DWRITE_PARAGRAPH_ALIGNMENT_NEAR,
			 DWRITE_FONT_WEIGHT			fontWeight = DWRITE_FONT_WEIGHT_REGULAR
			 );
		void SetFont(Microsoft::WRL::ComPtr<IDWriteTextFormat>		 textFormat);
		void SetTypography(Microsoft::WRL::ComPtr<IDWriteTypography> typography);

		void SetTextAlignment(DWRITE_TEXT_ALIGNMENT textAlignment);
		void SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment);

	private:
		// Resources shared with PostcardRenderer.
		Microsoft::WRL::ComPtr<IWICImagingFactory2>			m_wicFactory;
		Microsoft::WRL::ComPtr<ID2D1DeviceContext>			m_d2dContext;
		float												m_dpi;
		Microsoft::WRL::ComPtr<IDWriteFactory1>				m_dwriteFactory;

		Windows::Foundation::Rect							m_rectBounds;

		Microsoft::WRL::ComPtr<ID2D1SolidColorBrush>		m_colorBrush;
		Microsoft::WRL::ComPtr<IDWriteTextFormat>			m_dwriteTextFormat;
		Microsoft::WRL::ComPtr<IDWriteTypography>			m_dwriteTypography;
		Microsoft::WRL::ComPtr<IDWriteTextLayout>			m_dwriteTextLayout;
		Platform::String^									m_textDrawing;

		void CreateTextLayout(Platform::String^ text);
	};

}

第二步,在恰当的地方声明SurfaceImageSource变量ZebraDX::ZebraImageSource^ fooImageSource;
第三步,实例化这个SurfaceImageSource变量
fooImageSource = ref new ZebraImageSource(1366, 768, true);
第四步,初始化这个SurfaceImageSource变量
CreateDeviceIndependentResources();
CreateDeviceResources();
CreateWindowSizeDependentResources();
第五步,绘画
Render();
第六步,设置为Image控件的Source,显示它
Image1->Source = fooImageSource;


抱歉!评论已关闭.