update: GraphicsDevice owns all Direct2D resources
This commit is contained in:
		
							parent
							
								
									c474d259c5
								
							
						
					
					
						commit
						2b366e42be
					
				|  | @ -46,8 +46,8 @@ namespace easy2d | ||||||
| 		Right	/* ÓÒ */ | 		Right	/* ÓÒ */ | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	// ÏßÌõÏཻÑùʽ
 | 	// »±ÊÑùʽ
 | ||||||
| 	enum class Stroke : int | 	enum class StrokeStyle : int | ||||||
| 	{ | 	{ | ||||||
| 		Miter = 0,	/* бÇÐ */ | 		Miter = 0,	/* бÇÐ */ | ||||||
| 		Bevel = 1,	/* б½Ç */ | 		Bevel = 1,	/* б½Ç */ | ||||||
|  |  | ||||||
|  | @ -24,15 +24,21 @@ | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | 	///////////////////////////////////////////////////////
 | ||||||
|  | 	///////////////////////////////////////////////////////
 | ||||||
|  | 	// FIXME!!!
 | ||||||
|  | 	///////////////////////////////////////////////////////
 | ||||||
|  | 	///////////////////////////////////////////////////////
 | ||||||
|  | 
 | ||||||
| 	Canvas::Canvas(float width, float height) | 	Canvas::Canvas(float width, float height) | ||||||
| 		: render_target_(nullptr) | 		: render_target_(nullptr) | ||||||
| 		, fill_brush_(nullptr) | 		, fill_brush_(nullptr) | ||||||
| 		, line_brush_(nullptr) | 		, line_brush_(nullptr) | ||||||
| 		, stroke_style_(nullptr) | 		, stroke_style_(nullptr) | ||||||
| 		, stroke_width_(1.0f) | 		, stroke_width_(1.0f) | ||||||
| 		, stroke_(Stroke::Miter) | 		, stroke_(StrokeStyle::Miter) | ||||||
| 	{ | 	{ | ||||||
| 		render_target_ = render::D2D.HwndRenderTarget; | 		// render_target_ = render::D2D.HwndRenderTarget;
 | ||||||
| 		render_target_->AddRef(); | 		render_target_->AddRef(); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
|  | @ -78,22 +84,11 @@ namespace easy2d | ||||||
| 		stroke_width_ = std::max(width, 0.f); | 		stroke_width_ = std::max(width, 0.f); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Canvas::SetStrokeStyle(Stroke strokeStyle) | 	void Canvas::SetStrokeStyle(StrokeStyle stroke) | ||||||
| 	{ | 	{ | ||||||
| 		SafeRelease(stroke_style_); | 		SafeRelease(stroke_style_); | ||||||
| 
 | 
 | ||||||
| 		switch (strokeStyle) | 		stroke_style_ = render::instance.GetStrokeStyle(stroke); | ||||||
| 		{ |  | ||||||
| 		case Stroke::Miter: |  | ||||||
| 			stroke_style_ = render::D2D.MiterStrokeStyle; |  | ||||||
| 			break; |  | ||||||
| 		case Stroke::Bevel: |  | ||||||
| 			stroke_style_ = render::D2D.BevelStrokeStyle; |  | ||||||
| 			break; |  | ||||||
| 		case Stroke::Round: |  | ||||||
| 			stroke_style_ = render::D2D.RoundStrokeStyle; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if (stroke_style_) | 		if (stroke_style_) | ||||||
| 			stroke_style_->AddRef(); | 			stroke_style_->AddRef(); | ||||||
|  | @ -114,7 +109,7 @@ namespace easy2d | ||||||
| 		return stroke_width_; | 		return stroke_width_; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Stroke Canvas::GetStrokeStyle() const | 	StrokeStyle Canvas::GetStrokeStyle() const | ||||||
| 	{ | 	{ | ||||||
| 		return stroke_; | 		return stroke_; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		// ÉèÖÃÏßÌõÏཻÑùʽ
 | 		// ÉèÖÃÏßÌõÏཻÑùʽ
 | ||||||
| 		void SetStrokeStyle( | 		void SetStrokeStyle( | ||||||
| 			Stroke strokeStyle | 			StrokeStyle stroke | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// »ñÈ¡ÏßÌõÑÕÉ«
 | 		// »ñÈ¡ÏßÌõÑÕÉ«
 | ||||||
|  | @ -66,7 +66,7 @@ namespace easy2d | ||||||
| 		float GetStrokeWidth() const; | 		float GetStrokeWidth() const; | ||||||
| 
 | 
 | ||||||
| 		// »ñÈ¡ÏßÌõÏཻÑùʽ
 | 		// »ñÈ¡ÏßÌõÏཻÑùʽ
 | ||||||
| 		Stroke GetStrokeStyle() const; | 		StrokeStyle GetStrokeStyle() const; | ||||||
| 
 | 
 | ||||||
| 		// »Ö±Ïß
 | 		// »Ö±Ïß
 | ||||||
| 		void DrawLine( | 		void DrawLine( | ||||||
|  | @ -129,7 +129,7 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		float					stroke_width_; | 		float					stroke_width_; | ||||||
| 		Stroke					stroke_; | 		StrokeStyle					stroke_; | ||||||
| 		ID2D1RenderTarget*		render_target_; | 		ID2D1RenderTarget*		render_target_; | ||||||
| 		ID2D1SolidColorBrush*	fill_brush_; | 		ID2D1SolidColorBrush*	fill_brush_; | ||||||
| 		ID2D1SolidColorBrush*	line_brush_; | 		ID2D1SolidColorBrush*	line_brush_; | ||||||
|  |  | ||||||
|  | @ -80,9 +80,4 @@ namespace easy2d | ||||||
| 		, a(color.a) | 		, a(color.a) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	Color::operator D2D1_COLOR_F() const |  | ||||||
| 	{ |  | ||||||
| 		return D2D1::ColorF(r, g, b, a); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | @ -63,7 +63,10 @@ namespace easy2d | ||||||
| 			const D2D1_COLOR_F& color | 			const D2D1_COLOR_F& color | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		operator D2D1_COLOR_F() const; | 		inline operator D2D1_COLOR_F() const | ||||||
|  | 		{ | ||||||
|  | 			return D2D1_COLOR_F{ r, g, b, a }; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		enum Value : unsigned int | 		enum Value : unsigned int | ||||||
|  |  | ||||||
|  | @ -23,12 +23,13 @@ | ||||||
| #include "Scene.h" | #include "Scene.h" | ||||||
| #include "Transition.h" | #include "Transition.h" | ||||||
| #include "Image.h" | #include "Image.h" | ||||||
| #include "../utils/Player.h" |  | ||||||
| #include "time.h" | #include "time.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| #include "input.h" | #include "input.h" | ||||||
| #include "audio.h" | #include "audio.h" | ||||||
| #include "modules.h" | #include "modules.h" | ||||||
|  | #include "../utils/Player.h" | ||||||
|  | #include "../math/Matrix.hpp" | ||||||
| #include <thread> | #include <thread> | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
|  | @ -68,7 +69,7 @@ namespace easy2d | ||||||
| 		Image::ClearCache(); | 		Image::ClearCache(); | ||||||
| 		Player::ClearCache(); | 		Player::ClearCache(); | ||||||
| 
 | 
 | ||||||
| 		render::Uninitialize(); | 		render::instance.Uninitialize(); | ||||||
| 		audio::instance.Uninitialize(); | 		audio::instance.Uninitialize(); | ||||||
| 		window::instance.Destroy(); | 		window::instance.Destroy(); | ||||||
| 		modules::Uninitialize(); | 		modules::Uninitialize(); | ||||||
|  | @ -82,8 +83,8 @@ namespace easy2d | ||||||
| 	{ | 	{ | ||||||
| 		modules::Initialize(); | 		modules::Initialize(); | ||||||
| 		window::instance.Initialize(property); | 		window::instance.Initialize(property); | ||||||
|  | 		render::instance.Initialize(window::instance.handle); | ||||||
| 		audio::instance.Initialize(); | 		audio::instance.Initialize(); | ||||||
| 		render::Initialize(window::instance.handle); |  | ||||||
| 
 | 
 | ||||||
| 		// 若开启了调试模式,打开控制台
 | 		// 若开启了调试模式,打开控制台
 | ||||||
| 		HWND console = ::GetConsoleWindow(); | 		HWND console = ::GetConsoleWindow(); | ||||||
|  | @ -291,14 +292,14 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 			if (curr_scene_ && curr_scene_->GetRoot()) | 			if (curr_scene_ && curr_scene_->GetRoot()) | ||||||
| 			{ | 			{ | ||||||
| 				render::D2D.HwndRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); | 				render::instance.SetTransform(math::Matrix()); | ||||||
| 				render::D2D.SolidColorBrush->SetOpacity(1.f); | 				render::instance.SetBrushOpacity(1.f); | ||||||
| 				curr_scene_->GetRoot()->DrawBorder(); | 				curr_scene_->GetRoot()->DrawBorder(); | ||||||
| 			} | 			} | ||||||
| 			if (next_scene_ && next_scene_->GetRoot()) | 			if (next_scene_ && next_scene_->GetRoot()) | ||||||
| 			{ | 			{ | ||||||
| 				render::D2D.HwndRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); | 				render::instance.SetTransform(math::Matrix()); | ||||||
| 				render::D2D.SolidColorBrush->SetOpacity(1.f); | 				render::instance.SetBrushOpacity(1.f); | ||||||
| 				next_scene_->GetRoot()->DrawBorder(); | 				next_scene_->GetRoot()->DrawBorder(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "Image.h" | #include "Image.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
|  | #include "logs.h" | ||||||
| #include "../utils/File.h" | #include "../utils/File.h" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
|  | @ -193,91 +194,17 @@ namespace easy2d | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		HRESULT hr; |  | ||||||
| 
 |  | ||||||
| 		HINSTANCE				hinstance = GetModuleHandle(nullptr); |  | ||||||
| 		IWICImagingFactory*		imaging_factory = render::D2D.WICImagingFactory; |  | ||||||
| 		ID2D1HwndRenderTarget*	render_target = render::D2D.HwndRenderTarget; |  | ||||||
| 		IWICBitmapDecoder*		decoder = nullptr; |  | ||||||
| 		IWICBitmapFrameDecode*	source = nullptr; |  | ||||||
| 		IWICStream*				stream = nullptr; |  | ||||||
| 		IWICFormatConverter*	converter = nullptr; |  | ||||||
| 		ID2D1Bitmap* bitmap = nullptr; | 		ID2D1Bitmap* bitmap = nullptr; | ||||||
| 
 | 		HRESULT hr = render::instance.CreateBitmapFromResource(res, &bitmap); | ||||||
| 		// 加载资源
 |  | ||||||
| 		hr = res.Load() ? S_OK : E_FAIL; |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 创建 WIC 流
 |  | ||||||
| 			hr = imaging_factory->CreateStream(&stream); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 初始化流
 |  | ||||||
| 			hr = stream->InitializeFromMemory( |  | ||||||
| 				static_cast<WICInProcPointer>(res.GetData()), |  | ||||||
| 				res.GetDataSize() |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 创建流的解码器
 |  | ||||||
| 			hr = imaging_factory->CreateDecoderFromStream( |  | ||||||
| 				stream, |  | ||||||
| 				nullptr, |  | ||||||
| 				WICDecodeMetadataCacheOnLoad, |  | ||||||
| 				&decoder |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 创建初始化框架
 |  | ||||||
| 			hr = decoder->GetFrame(0, &source); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 创建图片格式转换器
 |  | ||||||
| 			hr = imaging_factory->CreateFormatConverter(&converter); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 图片格式转换成 32bppPBGRA
 |  | ||||||
| 			hr = converter->Initialize( |  | ||||||
| 				source, |  | ||||||
| 				GUID_WICPixelFormat32bppPBGRA, |  | ||||||
| 				WICBitmapDitherTypeNone, |  | ||||||
| 				nullptr, |  | ||||||
| 				0.f, |  | ||||||
| 				WICBitmapPaletteTypeMedianCut |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 从 WIC 位图创建一个 Direct2D 位图
 |  | ||||||
| 			hr = render_target->CreateBitmapFromWicBitmap( |  | ||||||
| 				converter, |  | ||||||
| 				nullptr, |  | ||||||
| 				&bitmap |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
| 			bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); | 			bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); | ||||||
| 		} | 		} | ||||||
| 
 | 		else | ||||||
| 		// 释放相关资源
 | 		{ | ||||||
| 		SafeRelease(decoder); | 			logs::Trace(L"CreateBitmapFromFile", hr); | ||||||
| 		SafeRelease(source); | 		} | ||||||
| 		SafeRelease(stream); |  | ||||||
| 		SafeRelease(converter); |  | ||||||
| 
 | 
 | ||||||
| 		return SUCCEEDED(hr); | 		return SUCCEEDED(hr); | ||||||
| 	} | 	} | ||||||
|  | @ -296,68 +223,17 @@ namespace easy2d | ||||||
| 		// 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
 | 		// 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
 | ||||||
| 		String image_file_path = image_file.GetPath(); | 		String image_file_path = image_file.GetPath(); | ||||||
| 
 | 
 | ||||||
| 		IWICImagingFactory*		imaging_factory = render::D2D.WICImagingFactory; |  | ||||||
| 		ID2D1HwndRenderTarget*	render_target = render::D2D.HwndRenderTarget; |  | ||||||
| 		IWICBitmapDecoder*		decoder = nullptr; |  | ||||||
| 		IWICBitmapFrameDecode*	source = nullptr; |  | ||||||
| 		IWICStream*				stream = nullptr; |  | ||||||
| 		IWICFormatConverter*	converter = nullptr; |  | ||||||
| 		ID2D1Bitmap* bitmap = nullptr; | 		ID2D1Bitmap* bitmap = nullptr; | ||||||
| 
 | 		HRESULT hr = render::instance.CreateBitmapFromFile(file_name, &bitmap); | ||||||
| 		// 创建解码器
 |  | ||||||
| 		HRESULT hr = imaging_factory->CreateDecoderFromFilename( |  | ||||||
| 			image_file_path.c_str(), |  | ||||||
| 			nullptr, |  | ||||||
| 			GENERIC_READ, |  | ||||||
| 			WICDecodeMetadataCacheOnLoad, |  | ||||||
| 			&decoder |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 创建初始化框架
 |  | ||||||
| 			hr = decoder->GetFrame(0, &source); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 创建图片格式转换器
 |  | ||||||
| 			hr = imaging_factory->CreateFormatConverter(&converter); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 图片格式转换成 32bppPBGRA
 |  | ||||||
| 			hr = converter->Initialize( |  | ||||||
| 				source, |  | ||||||
| 				GUID_WICPixelFormat32bppPBGRA, |  | ||||||
| 				WICBitmapDitherTypeNone, |  | ||||||
| 				nullptr, |  | ||||||
| 				0.f, |  | ||||||
| 				WICBitmapPaletteTypeMedianCut |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			// 从 WIC 位图创建一个 Direct2D 位图
 |  | ||||||
| 			hr = render_target->CreateBitmapFromWicBitmap( |  | ||||||
| 				converter, |  | ||||||
| 				nullptr, |  | ||||||
| 				&bitmap |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
| 			bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); | 			bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); | ||||||
| 		} | 		} | ||||||
| 
 | 		else | ||||||
| 		// 释放相关资源
 | 		{ | ||||||
| 		SafeRelease(decoder); | 			logs::Trace(L"CreateBitmapFromFile", hr); | ||||||
| 		SafeRelease(source); | 		} | ||||||
| 		SafeRelease(stream); |  | ||||||
| 		SafeRelease(converter); |  | ||||||
| 
 | 
 | ||||||
| 		return SUCCEEDED(hr); | 		return SUCCEEDED(hr); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -44,8 +44,8 @@ namespace easy2d | ||||||
| 		, children_() | 		, children_() | ||||||
| 		, actions_() | 		, actions_() | ||||||
| 		, tasks_() | 		, tasks_() | ||||||
| 		, initial_matrix_(D2D1::Matrix3x2F::Identity()) | 		, initial_matrix_() | ||||||
| 		, final_matrix_(D2D1::Matrix3x2F::Identity()) | 		, final_matrix_() | ||||||
| 		, border_color_(Color::Red, 0.6f) | 		, border_color_(Color::Red, 0.6f) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
|  | @ -75,19 +75,14 @@ namespace easy2d | ||||||
| 		if (!visible_) | 		if (!visible_) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		auto render_target = render::D2D.HwndRenderTarget; |  | ||||||
| 		if (clip_enabled_) | 		if (clip_enabled_) | ||||||
| 		{ | 		{ | ||||||
| 			render_target->SetTransform(final_matrix_); | 			render::instance.PushClip(final_matrix_, transform_.size); | ||||||
| 			render_target->PushAxisAlignedClip( |  | ||||||
| 				D2D1::RectF(0, 0, transform_.size.width, transform_.size.height), |  | ||||||
| 				D2D1_ANTIALIAS_MODE_PER_PRIMITIVE |  | ||||||
| 			); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (children_.empty()) | 		if (children_.empty()) | ||||||
| 		{ | 		{ | ||||||
| 			render_target->SetTransform(final_matrix_); | 			render::instance.SetTransform(final_matrix_); | ||||||
| 			OnDraw(); | 			OnDraw(); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
|  | @ -119,7 +114,7 @@ namespace easy2d | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			render_target->SetTransform(final_matrix_); | 			render::instance.SetTransform(final_matrix_); | ||||||
| 			OnDraw(); | 			OnDraw(); | ||||||
| 
 | 
 | ||||||
| 			// 访问剩余节点
 | 			// 访问剩余节点
 | ||||||
|  | @ -129,7 +124,7 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		if (clip_enabled_) | 		if (clip_enabled_) | ||||||
| 		{ | 		{ | ||||||
| 			render_target->PopAxisAlignedClip(); | 			render::instance.PopClip(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -176,12 +171,7 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 			if (border_) | 			if (border_) | ||||||
| 			{ | 			{ | ||||||
| 				render::D2D.SolidColorBrush->SetColor(D2D1_COLOR_F(border_color_)); | 				render::instance.DrawGeometry(border_, border_color_, 1.f, 1.5f); | ||||||
| 				render::D2D.HwndRenderTarget->DrawGeometry( |  | ||||||
| 					border_, |  | ||||||
| 					render::D2D.SolidColorBrush, |  | ||||||
| 					1.5f |  | ||||||
| 				); |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			for (const auto& child : children_) | 			for (const auto& child : children_) | ||||||
|  | @ -198,14 +188,14 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		dirty_transform_ = false; | 		dirty_transform_ = false; | ||||||
| 
 | 
 | ||||||
| 		final_matrix_ = static_cast<D2D1::Matrix3x2F>(transform_); | 		final_matrix_ = transform_.ToMatrix(); | ||||||
| 
 | 
 | ||||||
| 		// 根据自身支点计算 Initial 矩阵,子节点将根据这个矩阵进行变换
 | 		// 根据自身支点计算 Initial 矩阵,子节点将根据这个矩阵进行变换
 | ||||||
| 		auto pivot = Point( | 		auto pivot = Point( | ||||||
| 			transform_.size.width * transform_.pivot_x, | 			transform_.size.width * transform_.pivot_x, | ||||||
| 			transform_.size.height * transform_.pivot_y | 			transform_.size.height * transform_.pivot_y | ||||||
| 		); | 		); | ||||||
| 		initial_matrix_ = final_matrix_ * D2D1::Matrix3x2F::Translation(pivot.x, pivot.y); | 		initial_matrix_ = final_matrix_ * math::Matrix::Translation(pivot); | ||||||
| 
 | 
 | ||||||
| 		if (parent_) | 		if (parent_) | ||||||
| 		{ | 		{ | ||||||
|  | @ -221,25 +211,9 @@ namespace easy2d | ||||||
| 		// 重新构造轮廓
 | 		// 重新构造轮廓
 | ||||||
| 		SafeRelease(border_); | 		SafeRelease(border_); | ||||||
| 		 | 		 | ||||||
| 		ID2D1Factory * factory = render::D2D.Factory; |  | ||||||
| 		ID2D1RectangleGeometry * rectangle = nullptr; |  | ||||||
| 		ID2D1TransformedGeometry * transformed = nullptr; |  | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			factory->CreateRectangleGeometry( | 			render::instance.CreateRectGeometry(final_matrix_, transform_.size, &border_) | ||||||
| 				D2D1::RectF(0, 0, transform_.size.width, transform_.size.height), |  | ||||||
| 				&rectangle |  | ||||||
| 			) |  | ||||||
| 		); | 		); | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			factory->CreateTransformedGeometry( |  | ||||||
| 				rectangle, |  | ||||||
| 				final_matrix_, |  | ||||||
| 				&transformed |  | ||||||
| 			) |  | ||||||
| 		); |  | ||||||
| 		border_ = transformed; |  | ||||||
| 
 |  | ||||||
| 		SafeRelease(rectangle); |  | ||||||
| 
 | 
 | ||||||
| 		// 通知子节点进行转换
 | 		// 通知子节点进行转换
 | ||||||
| 		for (const auto& child : children_) | 		for (const auto& child : children_) | ||||||
|  |  | ||||||
|  | @ -21,9 +21,10 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "base.h" | #include "base.h" | ||||||
| #include "RefCounter.h" | #include "RefCounter.h" | ||||||
| #include "../math/Transform.h" |  | ||||||
| #include "KeyEvent.h" | #include "KeyEvent.h" | ||||||
| #include "MouseEvent.h" | #include "MouseEvent.h" | ||||||
|  | #include "../math/Transform.h" | ||||||
|  | #include "../math/Matrix.hpp" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -448,7 +449,6 @@ namespace easy2d | ||||||
| 	private: | 	private: | ||||||
| 		String				name_; | 		String				name_; | ||||||
| 		size_t				hash_name_; | 		size_t				hash_name_; | ||||||
| 		math::Transform		transform_; |  | ||||||
| 		float				display_opacity_; | 		float				display_opacity_; | ||||||
| 		float				real_opacity_; | 		float				real_opacity_; | ||||||
| 		int					order_; | 		int					order_; | ||||||
|  | @ -463,7 +463,8 @@ namespace easy2d | ||||||
| 		Tasks				tasks_; | 		Tasks				tasks_; | ||||||
| 		Nodes				children_; | 		Nodes				children_; | ||||||
| 		ID2D1Geometry*		border_; | 		ID2D1Geometry*		border_; | ||||||
| 		D2D1::Matrix3x2F	initial_matrix_; | 		math::Transform		transform_; | ||||||
| 		D2D1::Matrix3x2F	final_matrix_; | 		math::Matrix		initial_matrix_; | ||||||
|  | 		math::Matrix		final_matrix_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "BaseTypes.h" | #include "BaseTypes.h" | ||||||
|  | #include <d2d1.h> | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -96,5 +97,10 @@ namespace easy2d | ||||||
| 					(origin.y + size.height)			< rect.origin.y || | 					(origin.y + size.height)			< rect.origin.y || | ||||||
| 					(rect.origin.y + rect.size.height)	< origin.y); | 					(rect.origin.y + rect.size.height)	< origin.y); | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		inline operator D2D1_RECT_F () const | ||||||
|  | 		{ | ||||||
|  | 			return D2D1_RECT_F{ origin.x, origin.y, origin.x + size.width, origin.y + size.height }; | ||||||
|  | 		} | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,13 +25,13 @@ namespace easy2d | ||||||
| { | { | ||||||
| 	Scene::Scene() | 	Scene::Scene() | ||||||
| 		: root_(nullptr) | 		: root_(nullptr) | ||||||
| 		, transform_(D2D1::Matrix3x2F::Identity()) | 		, transform_() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Scene::Scene(Node * root) | 	Scene::Scene(Node * root) | ||||||
| 		: root_(nullptr) | 		: root_(nullptr) | ||||||
| 		, transform_(D2D1::Matrix3x2F::Identity()) | 		, transform_() | ||||||
| 	{ | 	{ | ||||||
| 		this->SetRoot(root); | 		this->SetRoot(root); | ||||||
| 	} | 	} | ||||||
|  | @ -106,7 +106,7 @@ namespace easy2d | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Scene::SetTransform(const D2D1::Matrix3x2F& matrix) | 	void Scene::SetTransform(const math::Matrix& matrix) | ||||||
| 	{ | 	{ | ||||||
| 		transform_ = matrix; | 		transform_ = matrix; | ||||||
| 
 | 
 | ||||||
|  | @ -116,7 +116,7 @@ namespace easy2d | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	const D2D1::Matrix3x2F & Scene::GetTransform() const | 	const math::Matrix& Scene::GetTransform() const | ||||||
| 	{ | 	{ | ||||||
| 		return transform_; | 		return transform_; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ | ||||||
| #include "RefCounter.h" | #include "RefCounter.h" | ||||||
| #include "KeyEvent.h" | #include "KeyEvent.h" | ||||||
| #include "MouseEvent.h" | #include "MouseEvent.h" | ||||||
| #include <d2d1.h> | #include "../math/Matrix.hpp" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -73,17 +73,17 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		// ÉèÖÃת»»¾ØÕó
 | 		// ÉèÖÃת»»¾ØÕó
 | ||||||
| 		void SetTransform( | 		void SetTransform( | ||||||
| 			const D2D1::Matrix3x2F& matrix | 			const math::Matrix& matrix | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// »ñȡת»»¾ØÕó
 | 		// »ñȡת»»¾ØÕó
 | ||||||
| 		const D2D1::Matrix3x2F& GetTransform() const; | 		const math::Matrix& GetTransform() const; | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		E2D_DISABLE_COPY(Scene); | 		E2D_DISABLE_COPY(Scene); | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		Node*			root_; | 		Node*			root_; | ||||||
| 		D2D1::Matrix3x2F	transform_; | 		math::Matrix	transform_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
|  | #include <d2d1.h> | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -52,5 +53,10 @@ namespace easy2d | ||||||
| 		Size operator / (float val) const; | 		Size operator / (float val) const; | ||||||
| 		Size operator - () const; | 		Size operator - () const; | ||||||
| 		bool operator== (const Size& other) const; | 		bool operator== (const Size& other) const; | ||||||
|  | 
 | ||||||
|  | 		inline operator D2D1_SIZE_F () const | ||||||
|  | 		{ | ||||||
|  | 			return D2D1_SIZE_F{ width, height }; | ||||||
|  | 		} | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -135,17 +135,11 @@ namespace easy2d | ||||||
| 		if (image_ && image_->GetBitmap()) | 		if (image_ && image_->GetBitmap()) | ||||||
| 		{ | 		{ | ||||||
| 			auto crop_pos = image_->GetCropPos(); | 			auto crop_pos = image_->GetCropPos(); | ||||||
| 			render::D2D.HwndRenderTarget->DrawBitmap( | 			render::instance.DrawImage( | ||||||
| 				image_->GetBitmap(), | 				image_, | ||||||
| 				D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height), |  | ||||||
| 				GetDisplayOpacity(), | 				GetDisplayOpacity(), | ||||||
| 				D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | 				Rect(Point(), GetTransform().size), | ||||||
| 				D2D1::RectF( | 				Rect(crop_pos, GetTransform().size) | ||||||
| 					crop_pos.x, |  | ||||||
| 					crop_pos.y, |  | ||||||
| 					crop_pos.y + GetTransform().size.width, |  | ||||||
| 					crop_pos.y + GetTransform().size.height |  | ||||||
| 				) |  | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ namespace easy2d | ||||||
| 		, outline(true) | 		, outline(true) | ||||||
| 		, outline_color(Color(Color::Black, 0.5)) | 		, outline_color(Color(Color::Black, 0.5)) | ||||||
| 		, outline_width(1.f) | 		, outline_width(1.f) | ||||||
| 		, outline_stroke(Stroke::Round) | 		, outline_stroke(StrokeStyle::Round) | ||||||
| 	{} | 	{} | ||||||
| 
 | 
 | ||||||
| 	Text::Style::Style( | 	Text::Style::Style( | ||||||
|  | @ -53,7 +53,7 @@ namespace easy2d | ||||||
| 		bool outline, | 		bool outline, | ||||||
| 		Color outline_color, | 		Color outline_color, | ||||||
| 		float outline_width, | 		float outline_width, | ||||||
| 		Stroke outline_stroke | 		StrokeStyle outline_stroke | ||||||
| 	) | 	) | ||||||
| 		: color(color) | 		: color(color) | ||||||
| 		, alignment(alignment) | 		, alignment(alignment) | ||||||
|  | @ -143,7 +143,7 @@ namespace easy2d | ||||||
| 		return style_.outline_width; | 		return style_.outline_width; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Stroke Text::GetOutlineStroke() const | 	StrokeStyle Text::GetOutlineStroke() const | ||||||
| 	{ | 	{ | ||||||
| 		return style_.outline_stroke; | 		return style_.outline_stroke; | ||||||
| 	} | 	} | ||||||
|  | @ -306,7 +306,7 @@ namespace easy2d | ||||||
| 		style_.outline_width = outline_width; | 		style_.outline_width = outline_width; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Text::SetOutlineStroke(Stroke outline_stroke) | 	void Text::SetOutlineStroke(StrokeStyle outline_stroke) | ||||||
| 	{ | 	{ | ||||||
| 		style_.outline_stroke = outline_stroke; | 		style_.outline_stroke = outline_stroke; | ||||||
| 	} | 	} | ||||||
|  | @ -318,16 +318,16 @@ namespace easy2d | ||||||
| 			// 创建文本区域
 | 			// 创建文本区域
 | ||||||
| 			D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height); | 			D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height); | ||||||
| 			// 设置画刷颜色和透明度
 | 			// 设置画刷颜色和透明度
 | ||||||
| 			render::D2D.SolidColorBrush->SetOpacity(GetDisplayOpacity()); | 			render::instance.SetBrushOpacity(GetDisplayOpacity()); | ||||||
| 			// 获取文本渲染器
 | 			// 获取文本渲染器
 | ||||||
| 			render::D2D.TextRenderer->SetTextStyle( | 			render::instance.SetTextStyle( | ||||||
| 				style_.color, | 				style_.color, | ||||||
| 				style_.outline, | 				style_.outline, | ||||||
| 				style_.outline_color, | 				style_.outline_color, | ||||||
| 				style_.outline_width, | 				style_.outline_width, | ||||||
| 				static_cast<D2D1_LINE_JOIN>(style_.outline_stroke) | 				style_.outline_stroke | ||||||
| 			); | 			); | ||||||
| 			text_layout_->Draw(nullptr, render::D2D.TextRenderer, 0, 0); | 			render::instance.DrawTextLayout(text_layout_); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -344,15 +344,9 @@ namespace easy2d | ||||||
| 		SafeRelease(text_format_); | 		SafeRelease(text_format_); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			render::D2D.DWriteFactory->CreateTextFormat( | 			render::instance.CreateTextFormat( | ||||||
| 				font_.family.c_str(), | 				&text_format_, | ||||||
| 				nullptr, | 				font_ | ||||||
| 				DWRITE_FONT_WEIGHT(font_.weight), |  | ||||||
| 				font_.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, |  | ||||||
| 				DWRITE_FONT_STRETCH_NORMAL, |  | ||||||
| 				font_.size, |  | ||||||
| 				L"", |  | ||||||
| 				&text_format_ |  | ||||||
| 			) | 			) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | @ -401,19 +395,15 @@ namespace easy2d | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		UINT32 length = static_cast<UINT32>(text_.size()); |  | ||||||
| 
 |  | ||||||
| 		// 对文本自动换行情况下进行处理
 | 		// 对文本自动换行情况下进行处理
 | ||||||
| 		if (style_.wrap) | 		if (style_.wrap) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				render::D2D.DWriteFactory->CreateTextLayout( | 				render::instance.CreateTextLayout( | ||||||
| 					text_.c_str(), | 					&text_layout_, | ||||||
| 					length, | 					text_, | ||||||
| 					text_format_, | 					text_format_, | ||||||
| 					style_.wrap_width, | 					style_.wrap_width | ||||||
| 					0, |  | ||||||
| 					&text_layout_ |  | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 			// 获取文本布局的宽度和高度
 | 			// 获取文本布局的宽度和高度
 | ||||||
|  | @ -426,13 +416,11 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 			// 为防止文本对齐问题,根据先创建 layout 以获取宽度
 | 			// 为防止文本对齐问题,根据先创建 layout 以获取宽度
 | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				render::D2D.DWriteFactory->CreateTextLayout( | 				render::instance.CreateTextLayout( | ||||||
| 					text_.c_str(), | 					&text_layout_, | ||||||
| 					length, | 					text_, | ||||||
| 					text_format_, | 					text_format_, | ||||||
| 					0, | 					0 | ||||||
| 					0, |  | ||||||
| 					&text_layout_ |  | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
|  | @ -445,19 +433,17 @@ namespace easy2d | ||||||
| 			// 重新创建 layout
 | 			// 重新创建 layout
 | ||||||
| 			SafeRelease(text_layout_); | 			SafeRelease(text_layout_); | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				render::D2D.DWriteFactory->CreateTextLayout( | 				render::instance.CreateTextLayout( | ||||||
| 					text_.c_str(), | 					&text_layout_, | ||||||
| 					length, | 					text_, | ||||||
| 					text_format_, | 					text_format_, | ||||||
| 					GetTransform().size.width, | 					GetTransform().size.width | ||||||
| 					0, |  | ||||||
| 					&text_layout_ |  | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// 添加下划线和删除线
 | 		// 添加下划线和删除线
 | ||||||
| 		DWRITE_TEXT_RANGE range = { 0, length }; | 		DWRITE_TEXT_RANGE range = { 0, static_cast<UINT32>(text_.length()) }; | ||||||
| 		if (style_.underline) | 		if (style_.underline) | ||||||
| 		{ | 		{ | ||||||
| 			text_layout_->SetUnderline(true, range); | 			text_layout_->SetUnderline(true, range); | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ namespace easy2d | ||||||
| 			bool	outline;			// 显示描边
 | 			bool	outline;			// 显示描边
 | ||||||
| 			Color	outline_color;		// 描边颜色
 | 			Color	outline_color;		// 描边颜色
 | ||||||
| 			float	outline_width;		// 描边线宽
 | 			float	outline_width;		// 描边线宽
 | ||||||
| 			Stroke	outline_stroke;		// Ãè±ßÏßÏཻÑùʽ
 | 			StrokeStyle	outline_stroke;		// Ãè±ßÏßÏཻÑùʽ
 | ||||||
| 
 | 
 | ||||||
| 		public: | 		public: | ||||||
| 			Style(); | 			Style(); | ||||||
|  | @ -67,7 +67,7 @@ namespace easy2d | ||||||
| 				bool outline			= true, | 				bool outline			= true, | ||||||
| 				Color outline_color		= Color(Color::Black, 0.5), | 				Color outline_color		= Color(Color::Black, 0.5), | ||||||
| 				float outline_width		= 1.f, | 				float outline_width		= 1.f, | ||||||
| 				Stroke outline_stroke = Stroke::Round | 				StrokeStyle outline_stroke = StrokeStyle::Round | ||||||
| 			); | 			); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | @ -110,7 +110,7 @@ namespace easy2d | ||||||
| 		float GetOutlineWidth() const; | 		float GetOutlineWidth() const; | ||||||
| 
 | 
 | ||||||
| 		// 获取描边线相交样式
 | 		// 获取描边线相交样式
 | ||||||
| 		Stroke GetOutlineStroke() const; | 		StrokeStyle GetOutlineStroke() const; | ||||||
| 
 | 
 | ||||||
| 		// 获取文本显示行数
 | 		// 获取文本显示行数
 | ||||||
| 		int GetLineCount() const; | 		int GetLineCount() const; | ||||||
|  | @ -214,7 +214,7 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		// 设置描边线相交样式
 | 		// 设置描边线相交样式
 | ||||||
| 		void SetOutlineStroke( | 		void SetOutlineStroke( | ||||||
| 			Stroke outline_stroke | 			StrokeStyle outline_stroke | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 渲染文字
 | 		// 渲染文字
 | ||||||
|  |  | ||||||
|  | @ -73,22 +73,7 @@ namespace easy2d | ||||||
| 		bShowOutline_ = outline; | 		bShowOutline_ = outline; | ||||||
| 		sOutlineColor_ = outline_color; | 		sOutlineColor_ = outline_color; | ||||||
| 		fOutlineWidth = 2 * outline_width; | 		fOutlineWidth = 2 * outline_width; | ||||||
| 
 | 		pCurrStrokeStyle_ = render::instance.GetStrokeStyle(StrokeStyle(outlineJoin)); | ||||||
| 		switch (outlineJoin) |  | ||||||
| 		{ |  | ||||||
| 		case D2D1_LINE_JOIN_MITER: |  | ||||||
| 			pCurrStrokeStyle_ = render::D2D.MiterStrokeStyle; |  | ||||||
| 			break; |  | ||||||
| 		case D2D1_LINE_JOIN_BEVEL: |  | ||||||
| 			pCurrStrokeStyle_ = render::D2D.BevelStrokeStyle; |  | ||||||
| 			break; |  | ||||||
| 		case D2D1_LINE_JOIN_ROUND: |  | ||||||
| 			pCurrStrokeStyle_ = render::D2D.RoundStrokeStyle; |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			pCurrStrokeStyle_ = nullptr; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	STDMETHODIMP ITextRenderer::DrawGlyphRun( | 	STDMETHODIMP ITextRenderer::DrawGlyphRun( | ||||||
|  |  | ||||||
|  | @ -21,8 +21,8 @@ | ||||||
| #include "Transition.h" | #include "Transition.h" | ||||||
| #include "Node.h" | #include "Node.h" | ||||||
| #include "Scene.h" | #include "Scene.h" | ||||||
| #include "render.h" |  | ||||||
| #include "window.h" | #include "window.h" | ||||||
|  | #include "../math/Matrix.hpp" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -39,8 +39,8 @@ namespace easy2d | ||||||
| 		, in_scene_(nullptr) | 		, in_scene_(nullptr) | ||||||
| 		, out_layer_(nullptr) | 		, out_layer_(nullptr) | ||||||
| 		, in_layer_(nullptr) | 		, in_layer_(nullptr) | ||||||
| 		, out_layer_param_() | 		, out_layer_prop_() | ||||||
| 		, in_layer_param_() | 		, in_layer_prop_() | ||||||
| 	{ | 	{ | ||||||
| 		duration_ = std::max(duration, 0.f); | 		duration_ = std::max(duration, 0.f); | ||||||
| 	} | 	} | ||||||
|  | @ -73,32 +73,22 @@ namespace easy2d | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				render::D2D.HwndRenderTarget->CreateLayer(&in_layer_) | 				render::instance.CreateLayer(&in_layer_) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				render::D2D.HwndRenderTarget->CreateLayer(&out_layer_) | 				render::instance.CreateLayer(&out_layer_) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		window_size_ = window::instance.GetSize(); | 		window_size_ = window::instance.GetSize(); | ||||||
| 		out_layer_param_ = in_layer_param_ = D2D1::LayerParameters( | 		out_layer_prop_ = in_layer_prop_ = render::LayerProperties{ | ||||||
| 			D2D1::RectF( | 			Rect(Point(), window_size_), | ||||||
| 				0.f, | 			1.f | ||||||
| 				0.f, | 		}; | ||||||
| 				window_size_.width, |  | ||||||
| 				window_size_.height |  | ||||||
| 			), |  | ||||||
| 			nullptr, |  | ||||||
| 			D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, |  | ||||||
| 			D2D1::Matrix3x2F::Identity(), |  | ||||||
| 			1.f, |  | ||||||
| 			render::D2D.SolidColorBrush, |  | ||||||
| 			D2D1_LAYER_OPTIONS_NONE |  | ||||||
| 		); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Transition::Update() | 	void Transition::Update() | ||||||
|  | @ -121,46 +111,32 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 	void Transition::Draw() | 	void Transition::Draw() | ||||||
| 	{ | 	{ | ||||||
| 		auto render_target = render::D2D.HwndRenderTarget; |  | ||||||
| 
 |  | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			render_target->SetTransform(out_scene_->GetTransform()); | 			render::instance.PushClip( | ||||||
| 			render_target->PushAxisAlignedClip( | 				out_scene_->GetTransform(), | ||||||
| 				D2D1::RectF( | 				window_size_ | ||||||
| 					0.f, |  | ||||||
| 					0.f, |  | ||||||
| 					window_size_.width, |  | ||||||
| 					window_size_.height |  | ||||||
| 				), |  | ||||||
| 				D2D1_ANTIALIAS_MODE_PER_PRIMITIVE |  | ||||||
| 			); | 			); | ||||||
| 			render_target->PushLayer(out_layer_param_, out_layer_); | 			render::instance.PushLayer(out_layer_, out_layer_prop_); | ||||||
| 
 | 
 | ||||||
| 			out_scene_->Draw(); | 			out_scene_->Draw(); | ||||||
| 
 | 
 | ||||||
| 			render_target->PopLayer(); | 			render::instance.PopLayer(); | ||||||
| 			render_target->PopAxisAlignedClip(); | 			render::instance.PopClip(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			render_target->SetTransform(in_scene_->GetTransform()); | 			render::instance.PushClip( | ||||||
| 			render_target->PushAxisAlignedClip( | 				in_scene_->GetTransform(), | ||||||
| 				D2D1::RectF( | 				window_size_ | ||||||
| 					0.f, |  | ||||||
| 					0.f, |  | ||||||
| 					window_size_.width, |  | ||||||
| 					window_size_.height |  | ||||||
| 				), |  | ||||||
| 				D2D1_ANTIALIAS_MODE_PER_PRIMITIVE |  | ||||||
| 			); | 			); | ||||||
| 			render_target->PushLayer(in_layer_param_, in_layer_); | 			render::instance.PushLayer(in_layer_, in_layer_prop_); | ||||||
| 
 | 
 | ||||||
| 			in_scene_->Draw(); | 			in_scene_->Draw(); | ||||||
| 
 | 
 | ||||||
| 			render_target->PopLayer(); | 			render::instance.PopLayer(); | ||||||
| 			render_target->PopAxisAlignedClip(); | 			render::instance.PopClip(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -183,7 +159,7 @@ namespace easy2d | ||||||
| 	{ | 	{ | ||||||
| 		Transition::Initialize(prev, next, game); | 		Transition::Initialize(prev, next, game); | ||||||
| 
 | 
 | ||||||
| 		in_layer_param_.opacity = 0; | 		in_layer_prop_.opacity = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void BoxTransition::Update() | 	void BoxTransition::Update() | ||||||
|  | @ -192,22 +168,22 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		if (process_ < .5f) | 		if (process_ < .5f) | ||||||
| 		{ | 		{ | ||||||
| 			out_layer_param_.contentBounds = D2D1::RectF( | 			out_layer_prop_.area = Rect( | ||||||
| 				window_size_.width * process_, | 				window_size_.width * process_, | ||||||
| 				window_size_.height * process_, | 				window_size_.height * process_, | ||||||
| 				window_size_.width * (1 - process_), | 				window_size_.width * (1 - process_ * 2), | ||||||
| 				window_size_.height * (1 - process_) | 				window_size_.height * (1 - process_ * 2) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			out_layer_param_.opacity = 0; | 			out_layer_prop_.opacity = 0; | ||||||
| 			in_layer_param_.opacity = 1; | 			in_layer_prop_.opacity = 1; | ||||||
| 			in_layer_param_.contentBounds = D2D1::RectF( | 			in_layer_prop_.area = Rect( | ||||||
| 				window_size_.width * (1 - process_), | 				window_size_.width * (1 - process_), | ||||||
| 				window_size_.height * (1 - process_), | 				window_size_.height * (1 - process_), | ||||||
| 				window_size_.width * process_, | 				window_size_.width * (2 * process_ - 1), | ||||||
| 				window_size_.height * process_ | 				window_size_.height * (2 * process_ - 1) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -225,16 +201,16 @@ namespace easy2d | ||||||
| 	{ | 	{ | ||||||
| 		Transition::Initialize(prev, next, game); | 		Transition::Initialize(prev, next, game); | ||||||
| 
 | 
 | ||||||
| 		out_layer_param_.opacity = 1; | 		out_layer_prop_.opacity = 1; | ||||||
| 		in_layer_param_.opacity = 0; | 		in_layer_prop_.opacity = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void EmergeTransition::Update() | 	void EmergeTransition::Update() | ||||||
| 	{ | 	{ | ||||||
| 		Transition::Update(); | 		Transition::Update(); | ||||||
| 
 | 
 | ||||||
| 		out_layer_param_.opacity = 1 - process_; | 		out_layer_prop_.opacity = 1 - process_; | ||||||
| 		in_layer_param_.opacity = process_; | 		in_layer_prop_.opacity = process_; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
|  | @ -250,8 +226,8 @@ namespace easy2d | ||||||
| 	{ | 	{ | ||||||
| 		Transition::Initialize(prev, next, game); | 		Transition::Initialize(prev, next, game); | ||||||
| 
 | 
 | ||||||
| 		out_layer_param_.opacity = 1; | 		out_layer_prop_.opacity = 1; | ||||||
| 		in_layer_param_.opacity = 0; | 		in_layer_prop_.opacity = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void FadeTransition::Update() | 	void FadeTransition::Update() | ||||||
|  | @ -260,13 +236,13 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		if (process_ < 0.5) | 		if (process_ < 0.5) | ||||||
| 		{ | 		{ | ||||||
| 			out_layer_param_.opacity = 1 - process_ * 2; | 			out_layer_prop_.opacity = 1 - process_ * 2; | ||||||
| 			in_layer_param_.opacity = 0; | 			in_layer_prop_.opacity = 0; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			out_layer_param_.opacity = 0; | 			out_layer_prop_.opacity = 0; | ||||||
| 			in_layer_param_.opacity = (process_ - 0.5f) * 2; | 			in_layer_prop_.opacity = (process_ - 0.5f) * 2; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -306,13 +282,13 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			out_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			in_scene_->SetTransform( | 			in_scene_->SetTransform( | ||||||
| 				D2D1::Matrix3x2F::Translation( | 				math::Matrix::Translation( | ||||||
| 					start_pos_.x, | 					start_pos_.x, | ||||||
| 					start_pos_.y | 					start_pos_.y | ||||||
| 				) | 				) | ||||||
|  | @ -328,7 +304,7 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 			auto translation = pos_delta_ * process_; | 			auto translation = pos_delta_ * process_; | ||||||
| 			out_scene_->SetTransform( | 			out_scene_->SetTransform( | ||||||
| 				D2D1::Matrix3x2F::Translation( | 				math::Matrix::Translation( | ||||||
| 					translation.x, | 					translation.x, | ||||||
| 					translation.y | 					translation.y | ||||||
| 				) | 				) | ||||||
|  | @ -339,7 +315,7 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 			auto translation = start_pos_ + pos_delta_ * process_; | 			auto translation = start_pos_ + pos_delta_ * process_; | ||||||
| 			in_scene_->SetTransform( | 			in_scene_->SetTransform( | ||||||
| 				D2D1::Matrix3x2F::Translation( | 				math::Matrix::Translation( | ||||||
| 					translation.x, | 					translation.x, | ||||||
| 					translation.y | 					translation.y | ||||||
| 				) | 				) | ||||||
|  | @ -351,12 +327,12 @@ namespace easy2d | ||||||
| 	{ | 	{ | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			out_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			in_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -376,22 +352,22 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			out_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			in_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		in_layer_param_.opacity = 0; | 		in_layer_prop_.opacity = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RotationTransition::Update() | 	void RotationTransition::Update() | ||||||
| 	{ | 	{ | ||||||
| 		Transition::Update(); | 		Transition::Update(); | ||||||
| 
 | 
 | ||||||
| 		auto center_pos = D2D1::Point2F( | 		auto center_pos = math::Vector2( | ||||||
| 			window_size_.width / 2, | 			window_size_.width / 2, | ||||||
| 			window_size_.height / 2 | 			window_size_.height / 2 | ||||||
| 		); | 		); | ||||||
|  | @ -401,11 +377,11 @@ namespace easy2d | ||||||
| 			if (out_scene_) | 			if (out_scene_) | ||||||
| 			{ | 			{ | ||||||
| 				out_scene_->SetTransform( | 				out_scene_->SetTransform( | ||||||
| 					D2D1::Matrix3x2F::Scale( | 					math::Matrix::Scaling( | ||||||
| 						(.5f - process_) * 2, | 						(.5f - process_) * 2, | ||||||
| 						(.5f - process_) * 2, | 						(.5f - process_) * 2, | ||||||
| 						center_pos | 						center_pos | ||||||
| 					) * D2D1::Matrix3x2F::Rotation( | 					) * math::Matrix::Rotation( | ||||||
| 						rotation_ * (.5f - process_) * 2, | 						rotation_ * (.5f - process_) * 2, | ||||||
| 						center_pos | 						center_pos | ||||||
| 					) | 					) | ||||||
|  | @ -416,15 +392,15 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 			if (in_scene_) | 			if (in_scene_) | ||||||
| 			{ | 			{ | ||||||
| 				out_layer_param_.opacity = 0; | 				out_layer_prop_.opacity = 0; | ||||||
| 				in_layer_param_.opacity = 1; | 				in_layer_prop_.opacity = 1; | ||||||
| 
 | 
 | ||||||
| 				in_scene_->SetTransform( | 				in_scene_->SetTransform( | ||||||
| 					D2D1::Matrix3x2F::Scale( | 					math::Matrix::Scaling( | ||||||
| 					(process_ - .5f) * 2, | 					(process_ - .5f) * 2, | ||||||
| 						(process_ - .5f) * 2, | 						(process_ - .5f) * 2, | ||||||
| 						center_pos | 						center_pos | ||||||
| 					) * D2D1::Matrix3x2F::Rotation( | 					) * math::Matrix::Rotation( | ||||||
| 						rotation_ * (process_ - .5f) * 2, | 						rotation_ * (process_ - .5f) * 2, | ||||||
| 						center_pos | 						center_pos | ||||||
| 					) | 					) | ||||||
|  | @ -437,12 +413,12 @@ namespace easy2d | ||||||
| 	{ | 	{ | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			out_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); | 			in_scene_->SetTransform(math::Matrix()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "base.h" | #include "base.h" | ||||||
| #include "time.h" | #include "time.h" | ||||||
|  | #include "render.h" | ||||||
| #include "RefCounter.h" | #include "RefCounter.h" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
|  | @ -72,10 +73,10 @@ namespace easy2d | ||||||
| 		Size			window_size_; | 		Size			window_size_; | ||||||
| 		Scene*			out_scene_; | 		Scene*			out_scene_; | ||||||
| 		Scene*			in_scene_; | 		Scene*			in_scene_; | ||||||
| 		ID2D1Layer * out_layer_; | 		ID2D1Layer*		out_layer_; | ||||||
| 		ID2D1Layer * in_layer_; | 		ID2D1Layer*		in_layer_; | ||||||
| 		D2D1_LAYER_PARAMETERS out_layer_param_; | 		render::LayerProperties out_layer_prop_; | ||||||
| 		D2D1_LAYER_PARAMETERS in_layer_param_; | 		render::LayerProperties in_layer_prop_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,17 +30,31 @@ namespace easy2d | ||||||
| { | { | ||||||
| 	namespace render | 	namespace render | ||||||
| 	{ | 	{ | ||||||
| 		_D2D_Resource D2D = { 0 }; | 		GraphicsDevice instance; | ||||||
| 
 | 
 | ||||||
| 		void easy2d::render::Initialize(HWND hwnd) | 		GraphicsDevice::GraphicsDevice() | ||||||
|  | 			: fps_text_format_(nullptr) | ||||||
|  | 			, fps_text_layout_(nullptr) | ||||||
|  | 			, clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) | ||||||
| 		{ | 		{ | ||||||
| 			if (D2D.Factory) | 			ZeroMemory(&d2d, sizeof(D2DResources)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		GraphicsDevice::~GraphicsDevice() | ||||||
|  | 		{ | ||||||
|  | 			SafeRelease(fps_text_format_); | ||||||
|  | 			SafeRelease(fps_text_layout_); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		void GraphicsDevice::Initialize(HWND hwnd) | ||||||
|  | 		{ | ||||||
|  | 			if (d2d.Factory) | ||||||
| 				return; | 				return; | ||||||
| 
 | 
 | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				D2D1CreateFactory( | 				D2D1CreateFactory( | ||||||
| 					D2D1_FACTORY_TYPE_SINGLE_THREADED, | 					D2D1_FACTORY_TYPE_SINGLE_THREADED, | ||||||
| 					&D2D.Factory | 					&d2d.Factory | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
|  | @ -50,7 +64,7 @@ namespace easy2d | ||||||
| 					nullptr, | 					nullptr, | ||||||
| 					CLSCTX_INPROC_SERVER, | 					CLSCTX_INPROC_SERVER, | ||||||
| 					IID_IWICImagingFactory, | 					IID_IWICImagingFactory, | ||||||
| 					reinterpret_cast<void**>(&D2D.WICImagingFactory) | 					reinterpret_cast<void**>(&d2d.WICImagingFactory) | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
|  | @ -58,7 +72,7 @@ namespace easy2d | ||||||
| 				DWriteCreateFactory( | 				DWriteCreateFactory( | ||||||
| 					DWRITE_FACTORY_TYPE_SHARED, | 					DWRITE_FACTORY_TYPE_SHARED, | ||||||
| 					__uuidof(IDWriteFactory), | 					__uuidof(IDWriteFactory), | ||||||
| 					reinterpret_cast<IUnknown**>(&D2D.DWriteFactory) | 					reinterpret_cast<IUnknown**>(&d2d.DWriteFactory) | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
|  | @ -73,132 +87,65 @@ namespace easy2d | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				D2D.Factory->CreateStrokeStyle( | 				d2d.Factory->CreateStrokeStyle( | ||||||
| 					stroke_style, | 					stroke_style, | ||||||
| 					nullptr, | 					nullptr, | ||||||
| 					0, | 					0, | ||||||
| 					&D2D.MiterStrokeStyle | 					&d2d.MiterStrokeStyle | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
| 			stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL; | 			stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL; | ||||||
| 
 | 
 | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				D2D.Factory->CreateStrokeStyle( | 				d2d.Factory->CreateStrokeStyle( | ||||||
| 					stroke_style, | 					stroke_style, | ||||||
| 					nullptr, | 					nullptr, | ||||||
| 					0, | 					0, | ||||||
| 					&D2D.BevelStrokeStyle | 					&d2d.BevelStrokeStyle | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
| 			stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND; | 			stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND; | ||||||
| 
 | 
 | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				D2D.Factory->CreateStrokeStyle( | 				d2d.Factory->CreateStrokeStyle( | ||||||
| 					stroke_style, | 					stroke_style, | ||||||
| 					nullptr, | 					nullptr, | ||||||
| 					0, | 					0, | ||||||
| 					&D2D.RoundStrokeStyle | 					&d2d.RoundStrokeStyle | ||||||
| 				) | 				) | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
| 			CreateDeviceResources(hwnd); | 			CreateDeviceResources(hwnd); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void easy2d::render::CreateDeviceResources(HWND hwnd) | 		void GraphicsDevice::Uninitialize() | ||||||
| 		{ | 		{ | ||||||
| 			if (!D2D.HwndRenderTarget) | 			SafeRelease(d2d.TextRenderer); | ||||||
| 			{ | 			SafeRelease(d2d.SolidColorBrush); | ||||||
| 				RECT rc; | 			SafeRelease(d2d.HwndRenderTarget); | ||||||
| 				::GetClientRect(hwnd, &rc); |  | ||||||
| 
 | 
 | ||||||
| 				D2D1_SIZE_U size = D2D1::SizeU( | 			SafeRelease(d2d.MiterStrokeStyle); | ||||||
| 					rc.right - rc.left, | 			SafeRelease(d2d.BevelStrokeStyle); | ||||||
| 					rc.bottom - rc.top | 			SafeRelease(d2d.RoundStrokeStyle); | ||||||
| 				); |  | ||||||
| 
 | 
 | ||||||
| 				// 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建
 | 			SafeRelease(d2d.WICImagingFactory); | ||||||
| 				// 创建一个 Direct2D 渲染目标
 | 			SafeRelease(d2d.DWriteFactory); | ||||||
| 				ThrowIfFailed( | 			SafeRelease(d2d.Factory); | ||||||
| 					D2D.Factory->CreateHwndRenderTarget( |  | ||||||
| 						D2D1::RenderTargetProperties(), |  | ||||||
| 						D2D1::HwndRenderTargetProperties( |  | ||||||
| 							hwnd, |  | ||||||
| 							size, |  | ||||||
| 							D2D1_PRESENT_OPTIONS_NONE), |  | ||||||
| 						&D2D.HwndRenderTarget |  | ||||||
| 					) |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (!D2D.SolidColorBrush) |  | ||||||
| 			{ |  | ||||||
| 				ThrowIfFailed( |  | ||||||
| 					D2D.HwndRenderTarget->CreateSolidColorBrush( |  | ||||||
| 						D2D1::ColorF(D2D1::ColorF::White), |  | ||||||
| 						&D2D.SolidColorBrush |  | ||||||
| 					) |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (!D2D.TextRenderer) |  | ||||||
| 			{ |  | ||||||
| 				ThrowIfFailed( |  | ||||||
| 					ITextRenderer::Create( |  | ||||||
| 						&D2D.TextRenderer, |  | ||||||
| 						D2D.Factory, |  | ||||||
| 						D2D.HwndRenderTarget, |  | ||||||
| 						D2D.SolidColorBrush |  | ||||||
| 					) |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		void easy2d::render::Uninitialize() |  | ||||||
| 		{ |  | ||||||
| 			SafeRelease(D2D.TextRenderer); |  | ||||||
| 			SafeRelease(D2D.SolidColorBrush); |  | ||||||
| 			SafeRelease(D2D.HwndRenderTarget); |  | ||||||
| 
 |  | ||||||
| 			SafeRelease(D2D.MiterStrokeStyle); |  | ||||||
| 			SafeRelease(D2D.BevelStrokeStyle); |  | ||||||
| 			SafeRelease(D2D.RoundStrokeStyle); |  | ||||||
| 
 |  | ||||||
| 			SafeRelease(D2D.WICImagingFactory); |  | ||||||
| 			SafeRelease(D2D.DWriteFactory); |  | ||||||
| 			SafeRelease(D2D.Factory); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		//-------------------------------------------------------
 |  | ||||||
| 		// GraphicsDevice
 |  | ||||||
| 		//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 		GraphicsDevice instance; |  | ||||||
| 
 |  | ||||||
| 		GraphicsDevice::GraphicsDevice() |  | ||||||
| 			: fps_text_format_(nullptr) |  | ||||||
| 			, fps_text_layout_(nullptr) |  | ||||||
| 			, clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) |  | ||||||
| 		{ |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		GraphicsDevice::~GraphicsDevice() |  | ||||||
| 		{ |  | ||||||
| 			SafeRelease(fps_text_format_); |  | ||||||
| 			SafeRelease(fps_text_layout_); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void GraphicsDevice::BeginDraw(HWND hwnd) | 		void GraphicsDevice::BeginDraw(HWND hwnd) | ||||||
| 		{ | 		{ | ||||||
| 			render::CreateDeviceResources(hwnd); | 			CreateDeviceResources(hwnd); | ||||||
| 			render::D2D.HwndRenderTarget->BeginDraw(); | 
 | ||||||
| 			render::D2D.HwndRenderTarget->Clear(clear_color_); | 			d2d.HwndRenderTarget->BeginDraw(); | ||||||
|  | 			d2d.HwndRenderTarget->Clear(clear_color_); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void GraphicsDevice::EndDraw() | 		void GraphicsDevice::EndDraw() | ||||||
| 		{ | 		{ | ||||||
| 			HRESULT hr = render::D2D.HwndRenderTarget->EndDraw(); | 			HRESULT hr = d2d.HwndRenderTarget->EndDraw(); | ||||||
| 
 | 
 | ||||||
| 			if (hr == D2DERR_RECREATE_TARGET) | 			if (hr == D2DERR_RECREATE_TARGET) | ||||||
| 			{ | 			{ | ||||||
|  | @ -208,14 +155,426 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 				SafeRelease(fps_text_format_); | 				SafeRelease(fps_text_format_); | ||||||
| 				SafeRelease(fps_text_layout_); | 				SafeRelease(fps_text_layout_); | ||||||
| 				SafeRelease(render::D2D.TextRenderer); | 				SafeRelease(d2d.TextRenderer); | ||||||
| 				SafeRelease(render::D2D.SolidColorBrush); | 				SafeRelease(d2d.SolidColorBrush); | ||||||
| 				SafeRelease(render::D2D.HwndRenderTarget); | 				SafeRelease(d2d.HwndRenderTarget); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			ThrowIfFailed(hr); | 			ThrowIfFailed(hr); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		HRESULT GraphicsDevice::CreateRectGeometry( | ||||||
|  | 			const math::Matrix& matrix, | ||||||
|  | 			const Size& size, | ||||||
|  | 			ID2D1Geometry** geometry | ||||||
|  | 		) const | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.Factory) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			HRESULT hr; | ||||||
|  | 
 | ||||||
|  | 			ID2D1RectangleGeometry * rectangle = nullptr; | ||||||
|  | 			ID2D1TransformedGeometry * transformed = nullptr; | ||||||
|  | 			 | ||||||
|  | 			hr = d2d.Factory->CreateRectangleGeometry( | ||||||
|  | 				D2D1::RectF(0, 0, size.width, size.height), | ||||||
|  | 				&rectangle | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				hr = d2d.Factory->CreateTransformedGeometry( | ||||||
|  | 					rectangle, | ||||||
|  | 					matrix, | ||||||
|  | 					&transformed | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				*geometry = transformed; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			SafeRelease(rectangle); | ||||||
|  | 			return hr; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::CreateTextFormat(IDWriteTextFormat ** text_format, const Font & font) const | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.DWriteFactory) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			return d2d.DWriteFactory->CreateTextFormat( | ||||||
|  | 				font.family.c_str(), | ||||||
|  | 				nullptr, | ||||||
|  | 				DWRITE_FONT_WEIGHT(font.weight), | ||||||
|  | 				font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, | ||||||
|  | 				DWRITE_FONT_STRETCH_NORMAL, | ||||||
|  | 				font.size, | ||||||
|  | 				L"", | ||||||
|  | 				text_format | ||||||
|  | 			); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::CreateTextLayout(IDWriteTextLayout ** text_layout, const String & text, IDWriteTextFormat * text_format, float wrap_width) const | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.DWriteFactory) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			UINT32 length = static_cast<UINT32>(text.length()); | ||||||
|  | 			return d2d.DWriteFactory->CreateTextLayout( | ||||||
|  | 				text.c_str(), | ||||||
|  | 				length, | ||||||
|  | 				text_format, | ||||||
|  | 				wrap_width, | ||||||
|  | 				0, | ||||||
|  | 				text_layout | ||||||
|  | 			); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::CreateLayer(ID2D1Layer ** layer) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			return d2d.HwndRenderTarget->CreateLayer(layer); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::DrawGeometry( | ||||||
|  | 			ID2D1Geometry * geometry, | ||||||
|  | 			const Color & border_color, | ||||||
|  | 			float opacity, | ||||||
|  | 			float stroke_width, | ||||||
|  | 			StrokeStyle stroke | ||||||
|  | 		) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.SolidColorBrush || | ||||||
|  | 				!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.SolidColorBrush->SetColor(border_color); | ||||||
|  | 			d2d.SolidColorBrush->SetOpacity(opacity); | ||||||
|  | 			d2d.HwndRenderTarget->DrawGeometry( | ||||||
|  | 				geometry, | ||||||
|  | 				d2d.SolidColorBrush, | ||||||
|  | 				stroke_width, | ||||||
|  | 				GetStrokeStyle(stroke) | ||||||
|  | 			); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ID2D1StrokeStyle * GraphicsDevice::GetStrokeStyle(StrokeStyle stroke) const | ||||||
|  | 		{ | ||||||
|  | 			ID2D1StrokeStyle * stroke_style = nullptr; | ||||||
|  | 			switch (stroke) | ||||||
|  | 			{ | ||||||
|  | 			case StrokeStyle::Miter: | ||||||
|  | 				stroke_style = d2d.MiterStrokeStyle; | ||||||
|  | 				break; | ||||||
|  | 			case StrokeStyle::Bevel: | ||||||
|  | 				stroke_style = d2d.BevelStrokeStyle; | ||||||
|  | 				break; | ||||||
|  | 			case StrokeStyle::Round: | ||||||
|  | 				stroke_style = d2d.RoundStrokeStyle; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			return stroke_style; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::DrawImage( | ||||||
|  | 			Image * image, | ||||||
|  | 			float opacity, | ||||||
|  | 			const Rect & dest_rect, | ||||||
|  | 			const Rect & source_rect | ||||||
|  | 		) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->DrawBitmap( | ||||||
|  | 				image->GetBitmap(), | ||||||
|  | 				dest_rect, | ||||||
|  | 				opacity, | ||||||
|  | 				D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | ||||||
|  | 				source_rect | ||||||
|  | 			); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::DrawTextLayout(IDWriteTextLayout * text_layout) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.TextRenderer) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			return text_layout->Draw(nullptr, d2d.TextRenderer, 0, 0); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::PushClip(const math::Matrix & clip_matrix, const Size & clip_size) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->SetTransform(clip_matrix); | ||||||
|  | 			d2d.HwndRenderTarget->PushAxisAlignedClip( | ||||||
|  | 				D2D1::RectF(0, 0, clip_size.width, clip_size.height), | ||||||
|  | 				D2D1_ANTIALIAS_MODE_PER_PRIMITIVE | ||||||
|  | 			); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::PopClip() | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->PopAxisAlignedClip(); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::PushLayer(ID2D1Layer * layer, LayerProperties properties) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget || | ||||||
|  | 				!d2d.SolidColorBrush) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->PushLayer( | ||||||
|  | 				D2D1::LayerParameters( | ||||||
|  | 					properties.area, | ||||||
|  | 					nullptr, | ||||||
|  | 					D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, | ||||||
|  | 					D2D1::Matrix3x2F::Identity(), | ||||||
|  | 					properties.opacity, | ||||||
|  | 					d2d.SolidColorBrush, | ||||||
|  | 					D2D1_LAYER_OPTIONS_NONE | ||||||
|  | 				), | ||||||
|  | 				layer | ||||||
|  | 			); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::PopLayer() | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->PopLayer(); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::CreateBitmapFromFile(const String & file_path, ID2D1Bitmap ** bitmap) | ||||||
|  | 		{ | ||||||
|  | 			if (d2d.WICImagingFactory == nullptr || | ||||||
|  | 				d2d.HwndRenderTarget == nullptr) | ||||||
|  | 			{ | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (bitmap == nullptr) | ||||||
|  | 			{ | ||||||
|  | 				return E_POINTER; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			IWICBitmapDecoder*		decoder = nullptr; | ||||||
|  | 			IWICBitmapFrameDecode*	source = nullptr; | ||||||
|  | 			IWICStream*				stream = nullptr; | ||||||
|  | 			IWICFormatConverter*	converter = nullptr; | ||||||
|  | 
 | ||||||
|  | 			// 创建解码器
 | ||||||
|  | 			HRESULT hr = d2d.WICImagingFactory->CreateDecoderFromFilename( | ||||||
|  | 				file_path.c_str(), | ||||||
|  | 				nullptr, | ||||||
|  | 				GENERIC_READ, | ||||||
|  | 				WICDecodeMetadataCacheOnLoad, | ||||||
|  | 				&decoder | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 创建初始化框架
 | ||||||
|  | 				hr = decoder->GetFrame(0, &source); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 创建图片格式转换器
 | ||||||
|  | 				hr = d2d.WICImagingFactory->CreateFormatConverter(&converter); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 图片格式转换成 32bppPBGRA
 | ||||||
|  | 				hr = converter->Initialize( | ||||||
|  | 					source, | ||||||
|  | 					GUID_WICPixelFormat32bppPBGRA, | ||||||
|  | 					WICBitmapDitherTypeNone, | ||||||
|  | 					nullptr, | ||||||
|  | 					0.f, | ||||||
|  | 					WICBitmapPaletteTypeMedianCut | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 从 WIC 位图创建一个 Direct2D 位图
 | ||||||
|  | 				hr = d2d.HwndRenderTarget->CreateBitmapFromWicBitmap( | ||||||
|  | 					converter, | ||||||
|  | 					nullptr, | ||||||
|  | 					bitmap | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// 释放相关资源
 | ||||||
|  | 			SafeRelease(decoder); | ||||||
|  | 			SafeRelease(source); | ||||||
|  | 			SafeRelease(stream); | ||||||
|  | 			SafeRelease(converter); | ||||||
|  | 
 | ||||||
|  | 			return hr; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::CreateBitmapFromResource(Resource & res, ID2D1Bitmap ** bitmap) | ||||||
|  | 		{ | ||||||
|  | 			if (d2d.WICImagingFactory == nullptr || | ||||||
|  | 				d2d.HwndRenderTarget == nullptr) | ||||||
|  | 			{ | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (bitmap == nullptr) | ||||||
|  | 			{ | ||||||
|  | 				return E_POINTER; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			HRESULT hr; | ||||||
|  | 
 | ||||||
|  | 			HINSTANCE				hinstance = GetModuleHandle(nullptr); | ||||||
|  | 			IWICBitmapDecoder*		decoder = nullptr; | ||||||
|  | 			IWICBitmapFrameDecode*	source = nullptr; | ||||||
|  | 			IWICStream*				stream = nullptr; | ||||||
|  | 			IWICFormatConverter*	converter = nullptr; | ||||||
|  | 			 | ||||||
|  | 			// 加载资源
 | ||||||
|  | 			hr = res.Load() ? S_OK : E_FAIL; | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 创建 WIC 流
 | ||||||
|  | 				hr = d2d.WICImagingFactory->CreateStream(&stream); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 初始化流
 | ||||||
|  | 				hr = stream->InitializeFromMemory( | ||||||
|  | 					static_cast<WICInProcPointer>(res.GetData()), | ||||||
|  | 					res.GetDataSize() | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 创建流的解码器
 | ||||||
|  | 				hr = d2d.WICImagingFactory->CreateDecoderFromStream( | ||||||
|  | 					stream, | ||||||
|  | 					nullptr, | ||||||
|  | 					WICDecodeMetadataCacheOnLoad, | ||||||
|  | 					&decoder | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 创建初始化框架
 | ||||||
|  | 				hr = decoder->GetFrame(0, &source); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 创建图片格式转换器
 | ||||||
|  | 				hr = d2d.WICImagingFactory->CreateFormatConverter(&converter); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 图片格式转换成 32bppPBGRA
 | ||||||
|  | 				hr = converter->Initialize( | ||||||
|  | 					source, | ||||||
|  | 					GUID_WICPixelFormat32bppPBGRA, | ||||||
|  | 					WICBitmapDitherTypeNone, | ||||||
|  | 					nullptr, | ||||||
|  | 					0.f, | ||||||
|  | 					WICBitmapPaletteTypeMedianCut | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (SUCCEEDED(hr)) | ||||||
|  | 			{ | ||||||
|  | 				// 从 WIC 位图创建一个 Direct2D 位图
 | ||||||
|  | 				hr = d2d.HwndRenderTarget->CreateBitmapFromWicBitmap( | ||||||
|  | 					converter, | ||||||
|  | 					nullptr, | ||||||
|  | 					bitmap | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// 释放相关资源
 | ||||||
|  | 			SafeRelease(decoder); | ||||||
|  | 			SafeRelease(source); | ||||||
|  | 			SafeRelease(stream); | ||||||
|  | 			SafeRelease(converter); | ||||||
|  | 
 | ||||||
|  | 			return hr; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->Resize(D2D1::SizeU(width, height)); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::SetTransform(const math::Matrix & matrix) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.HwndRenderTarget->SetTransform(matrix); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::SetBrushOpacity(float opacity) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.SolidColorBrush->SetOpacity(opacity); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		HRESULT GraphicsDevice::SetTextStyle( | ||||||
|  | 			const Color & color, | ||||||
|  | 			bool has_outline, | ||||||
|  | 			const Color & outline_color, | ||||||
|  | 			float outline_width, | ||||||
|  | 			StrokeStyle outline_stroke | ||||||
|  | 		) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.TextRenderer) | ||||||
|  | 				return E_UNEXPECTED; | ||||||
|  | 
 | ||||||
|  | 			d2d.TextRenderer->SetTextStyle( | ||||||
|  | 				color, | ||||||
|  | 				has_outline, | ||||||
|  | 				outline_color, | ||||||
|  | 				outline_width, | ||||||
|  | 				static_cast<D2D1_LINE_JOIN>(outline_stroke) | ||||||
|  | 			); | ||||||
|  | 			return S_OK; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		void GraphicsDevice::SetBackgroundColor(const Color& color) | 		void GraphicsDevice::SetBackgroundColor(const Color& color) | ||||||
| 		{ | 		{ | ||||||
| 			clear_color_ = color; | 			clear_color_ = color; | ||||||
|  | @ -231,7 +590,7 @@ namespace easy2d | ||||||
| 			if (!fps_text_format_) | 			if (!fps_text_format_) | ||||||
| 			{ | 			{ | ||||||
| 				ThrowIfFailed( | 				ThrowIfFailed( | ||||||
| 					render::D2D.DWriteFactory->CreateTextFormat( | 					d2d.DWriteFactory->CreateTextFormat( | ||||||
| 						L"", | 						L"", | ||||||
| 						nullptr, | 						nullptr, | ||||||
| 						DWRITE_FONT_WEIGHT_NORMAL, | 						DWRITE_FONT_WEIGHT_NORMAL, | ||||||
|  | @ -262,7 +621,7 @@ namespace easy2d | ||||||
| 				SafeRelease(fps_text_layout_); | 				SafeRelease(fps_text_layout_); | ||||||
| 
 | 
 | ||||||
| 				ThrowIfFailed( | 				ThrowIfFailed( | ||||||
| 					render::D2D.DWriteFactory->CreateTextLayout( | 					d2d.DWriteFactory->CreateTextLayout( | ||||||
| 						fps_text, | 						fps_text, | ||||||
| 						static_cast<UINT32>(len), | 						static_cast<UINT32>(len), | ||||||
| 						fps_text_format_, | 						fps_text_format_, | ||||||
|  | @ -275,9 +634,9 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 			if (fps_text_layout_) | 			if (fps_text_layout_) | ||||||
| 			{ | 			{ | ||||||
| 				render::D2D.HwndRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); | 				d2d.HwndRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); | ||||||
| 				render::D2D.SolidColorBrush->SetOpacity(1.0f); | 				d2d.SolidColorBrush->SetOpacity(1.0f); | ||||||
| 				render::D2D.TextRenderer->SetTextStyle( | 				d2d.TextRenderer->SetTextStyle( | ||||||
| 					D2D1::ColorF(D2D1::ColorF::White), | 					D2D1::ColorF(D2D1::ColorF::White), | ||||||
| 					TRUE, | 					TRUE, | ||||||
| 					D2D1::ColorF(D2D1::ColorF::Black, 0.4f), | 					D2D1::ColorF(D2D1::ColorF::Black, 0.4f), | ||||||
|  | @ -285,7 +644,56 @@ namespace easy2d | ||||||
| 					D2D1_LINE_JOIN_ROUND | 					D2D1_LINE_JOIN_ROUND | ||||||
| 				); | 				); | ||||||
| 
 | 
 | ||||||
| 				fps_text_layout_->Draw(nullptr, render::D2D.TextRenderer, 10, 0); | 				fps_text_layout_->Draw(nullptr, d2d.TextRenderer, 10, 0); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		void GraphicsDevice::CreateDeviceResources(HWND hwnd) | ||||||
|  | 		{ | ||||||
|  | 			if (!d2d.HwndRenderTarget) | ||||||
|  | 			{ | ||||||
|  | 				RECT rc; | ||||||
|  | 				::GetClientRect(hwnd, &rc); | ||||||
|  | 
 | ||||||
|  | 				D2D1_SIZE_U size = D2D1::SizeU( | ||||||
|  | 					rc.right - rc.left, | ||||||
|  | 					rc.bottom - rc.top | ||||||
|  | 				); | ||||||
|  | 
 | ||||||
|  | 				// 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建
 | ||||||
|  | 				// 创建一个 Direct2D 渲染目标
 | ||||||
|  | 				ThrowIfFailed( | ||||||
|  | 					d2d.Factory->CreateHwndRenderTarget( | ||||||
|  | 						D2D1::RenderTargetProperties(), | ||||||
|  | 						D2D1::HwndRenderTargetProperties( | ||||||
|  | 							hwnd, | ||||||
|  | 							size, | ||||||
|  | 							D2D1_PRESENT_OPTIONS_NONE), | ||||||
|  | 						&d2d.HwndRenderTarget | ||||||
|  | 					) | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (!d2d.SolidColorBrush) | ||||||
|  | 			{ | ||||||
|  | 				ThrowIfFailed( | ||||||
|  | 					d2d.HwndRenderTarget->CreateSolidColorBrush( | ||||||
|  | 						D2D1::ColorF(D2D1::ColorF::White), | ||||||
|  | 						&d2d.SolidColorBrush | ||||||
|  | 					) | ||||||
|  | 				); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (!d2d.TextRenderer) | ||||||
|  | 			{ | ||||||
|  | 				ThrowIfFailed( | ||||||
|  | 					ITextRenderer::Create( | ||||||
|  | 						&d2d.TextRenderer, | ||||||
|  | 						d2d.Factory, | ||||||
|  | 						d2d.HwndRenderTarget, | ||||||
|  | 						d2d.SolidColorBrush | ||||||
|  | 					) | ||||||
|  | 				); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -20,7 +20,11 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "base.h" | #include "base.h" | ||||||
|  | #include "Font.h" | ||||||
|  | #include "Resource.h" | ||||||
|  | #include "Image.h" | ||||||
| #include "TextRenderer.h" | #include "TextRenderer.h" | ||||||
|  | #include "../math/Matrix.hpp" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -37,15 +41,13 @@ namespace easy2d | ||||||
| 			ID2D1StrokeStyle*		MiterStrokeStyle; | 			ID2D1StrokeStyle*		MiterStrokeStyle; | ||||||
| 			ID2D1StrokeStyle*		BevelStrokeStyle; | 			ID2D1StrokeStyle*		BevelStrokeStyle; | ||||||
| 			ID2D1StrokeStyle*		RoundStrokeStyle; | 			ID2D1StrokeStyle*		RoundStrokeStyle; | ||||||
| 		} _D2D_Resource; | 		} D2DResources; | ||||||
| 
 | 
 | ||||||
| 		extern _D2D_Resource D2D; | 		typedef struct | ||||||
| 
 | 		{ | ||||||
| 		void Initialize(HWND hwnd); | 			Rect area; | ||||||
| 
 | 			float opacity; | ||||||
| 		void CreateDeviceResources(HWND hwnd); | 		} LayerProperties; | ||||||
| 
 |  | ||||||
| 		void Uninitialize(); |  | ||||||
| 
 | 
 | ||||||
| 		class GraphicsDevice | 		class GraphicsDevice | ||||||
| 		{ | 		{ | ||||||
|  | @ -54,24 +56,121 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 			~GraphicsDevice(); | 			~GraphicsDevice(); | ||||||
| 
 | 
 | ||||||
|  | 			void Initialize(HWND hwnd); | ||||||
|  | 
 | ||||||
|  | 			void Uninitialize(); | ||||||
|  | 
 | ||||||
| 			// ¿ªÊ¼äÖȾ
 | 			// ¿ªÊ¼äÖȾ
 | ||||||
| 			void BeginDraw(HWND hwnd); | 			void BeginDraw(HWND hwnd); | ||||||
| 
 | 
 | ||||||
| 			// ½áÊøäÖȾ
 | 			// ½áÊøäÖȾ
 | ||||||
| 			void EndDraw(); | 			void EndDraw(); | ||||||
| 
 | 
 | ||||||
| 			// 渲染调试信息
 |  | ||||||
| 			void DrawDebugInfo(); |  | ||||||
| 
 |  | ||||||
| 			// ÉèÖñ³¾°É«
 | 			// ÉèÖñ³¾°É«
 | ||||||
| 			void SetBackgroundColor( | 			void SetBackgroundColor( | ||||||
| 				const Color& color | 				const Color& color | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
|  | 			// äÖȾµ÷ÊÔÐÅÏ¢
 | ||||||
|  | 			void DrawDebugInfo(); | ||||||
|  | 
 | ||||||
|  | 			void CreateDeviceResources(HWND hwnd); | ||||||
|  | 
 | ||||||
|  | 			HRESULT CreateRectGeometry( | ||||||
|  | 				const math::Matrix& matrix, | ||||||
|  | 				const Size& size, | ||||||
|  | 				ID2D1Geometry** geometry | ||||||
|  | 			) const; | ||||||
|  | 
 | ||||||
|  | 			HRESULT CreateTextFormat( | ||||||
|  | 				IDWriteTextFormat** text_format, | ||||||
|  | 				const Font& font | ||||||
|  | 			) const; | ||||||
|  | 
 | ||||||
|  | 			HRESULT CreateTextLayout( | ||||||
|  | 				IDWriteTextLayout** text_layout, | ||||||
|  | 				const String& text, | ||||||
|  | 				IDWriteTextFormat* text_format, | ||||||
|  | 				float wrap_width | ||||||
|  | 			) const; | ||||||
|  | 
 | ||||||
|  | 			HRESULT CreateLayer( | ||||||
|  | 				ID2D1Layer** layer | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			ID2D1StrokeStyle* GetStrokeStyle( | ||||||
|  | 				StrokeStyle stroke | ||||||
|  | 			) const; | ||||||
|  | 
 | ||||||
|  | 			HRESULT SetTransform( | ||||||
|  | 				const math::Matrix& matrix | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT SetBrushOpacity( | ||||||
|  | 				float opacity | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT SetTextStyle( | ||||||
|  | 				const Color& color, | ||||||
|  | 				bool has_outline, | ||||||
|  | 				const Color& outline_color, | ||||||
|  | 				float outline_width, | ||||||
|  | 				StrokeStyle outline_stroke | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT DrawGeometry( | ||||||
|  | 				ID2D1Geometry* geometry, | ||||||
|  | 				const Color& border_color, | ||||||
|  | 				float opacity, | ||||||
|  | 				float stroke_width, | ||||||
|  | 				StrokeStyle stroke = StrokeStyle::Miter | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT DrawImage( | ||||||
|  | 				Image* image, | ||||||
|  | 				float opacity, | ||||||
|  | 				const Rect& dest_rect, | ||||||
|  | 				const Rect& source_rect | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT DrawTextLayout( | ||||||
|  | 				IDWriteTextLayout* text_layout | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT PushClip( | ||||||
|  | 				const math::Matrix& clip_matrix, | ||||||
|  | 				const Size& clip_size | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT PopClip(); | ||||||
|  | 
 | ||||||
|  | 			HRESULT PushLayer( | ||||||
|  | 				ID2D1Layer* layer, | ||||||
|  | 				LayerProperties properties | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT PopLayer(); | ||||||
|  | 
 | ||||||
|  | 			HRESULT CreateBitmapFromFile( | ||||||
|  | 				const String& file_path, | ||||||
|  | 				ID2D1Bitmap** bitmap | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT CreateBitmapFromResource( | ||||||
|  | 				Resource& res, | ||||||
|  | 				ID2D1Bitmap** bitmap | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			HRESULT Resize( | ||||||
|  | 				UINT32 width, | ||||||
|  | 				UINT32 height | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
| 		protected: | 		protected: | ||||||
| 			D2D1_COLOR_F		clear_color_; | 			D2D1_COLOR_F		clear_color_; | ||||||
| 			IDWriteTextFormat*	fps_text_format_; | 			IDWriteTextFormat*	fps_text_format_; | ||||||
| 			IDWriteTextLayout*	fps_text_layout_; | 			IDWriteTextLayout*	fps_text_layout_; | ||||||
|  | 			D2DResources		d2d; | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		extern GraphicsDevice instance; | 		extern GraphicsDevice instance; | ||||||
|  |  | ||||||
|  | @ -173,21 +173,16 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		std::wstring easy2d::time::Duration::ToString() const | 		std::wstring easy2d::time::Duration::ToString() const | ||||||
| 		{ | 		{ | ||||||
| 			std::wstring result; | 			if (milliseconds_ == 0LL) | ||||||
| 			int64_t ms = milliseconds_ % Second.milliseconds_; |  | ||||||
| 			int64_t sec = milliseconds_ / Second.milliseconds_; |  | ||||||
| 			int64_t min = milliseconds_ / Minute.milliseconds_; |  | ||||||
| 			int64_t hour = milliseconds_ / Hour.milliseconds_; |  | ||||||
| 
 |  | ||||||
| 			min -= hour * 60; |  | ||||||
| 			sec -= (hour * 60 * 60 + min * 60); |  | ||||||
| 
 |  | ||||||
| 			auto float_to_str = [](float val) -> std::wstring |  | ||||||
| 			{ | 			{ | ||||||
| 				wchar_t buf[10] = {}; | 				return std::wstring(L"0s"); | ||||||
| 				::swprintf_s(buf, L"%.2f", val); | 			} | ||||||
| 				return std::wstring(buf); | 
 | ||||||
| 			}; | 			std::wstring result; | ||||||
|  | 			int64_t hour = milliseconds_ / Hour.milliseconds_; | ||||||
|  | 			int64_t min = milliseconds_ / Minute.milliseconds_ - hour * 60; | ||||||
|  | 			int64_t sec = milliseconds_ / Second.milliseconds_ - (hour * 60 * 60 + min * 60); | ||||||
|  | 			int64_t ms = milliseconds_ % Second.milliseconds_; | ||||||
| 
 | 
 | ||||||
| 			if (milliseconds_ < 0) | 			if (milliseconds_ < 0) | ||||||
| 				result.append(L"-"); | 				result.append(L"-"); | ||||||
|  | @ -202,19 +197,22 @@ namespace easy2d | ||||||
| 				result.append(std::to_wstring(min)).append(L"m"); | 				result.append(std::to_wstring(min)).append(L"m"); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (sec == 0 && ms == 0) | 			if (ms != 0) | ||||||
| 			{ | 			{ | ||||||
| 				result.append(L"0s"); | 				auto float_to_str = [](float val) -> std::wstring | ||||||
| 			} |  | ||||||
| 			else if (ms == 0) |  | ||||||
| 			{ |  | ||||||
| 				result.append(std::to_wstring(sec)).append(L"s"); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 				{ | 				{ | ||||||
|  | 					wchar_t buf[10] = {}; | ||||||
|  | 					::swprintf_s(buf, L"%.2f", val); | ||||||
|  | 					return std::wstring(buf); | ||||||
|  | 				}; | ||||||
|  | 
 | ||||||
| 				result.append(float_to_str(static_cast<float>(sec) + static_cast<float>(ms) / 1000.f)) | 				result.append(float_to_str(static_cast<float>(sec) + static_cast<float>(ms) / 1000.f)) | ||||||
| 					.append(L"s"); | 					.append(L"s"); | ||||||
| 			} | 			} | ||||||
|  | 			else if (sec != 0) | ||||||
|  | 			{ | ||||||
|  | 				result.append(std::to_wstring(sec)).append(L"s"); | ||||||
|  | 			} | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -306,11 +306,7 @@ namespace easy2d | ||||||
| 					// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
 | 					// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
 | ||||||
| 					// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
 | 					// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
 | ||||||
| 					// 错误,因为这个错误将在下一次调用 EndDraw 时产生
 | 					// 错误,因为这个错误将在下一次调用 EndDraw 时产生
 | ||||||
| 					auto render_target = render::D2D.HwndRenderTarget; | 					render::instance.Resize(width, height); | ||||||
| 					if (render_target) |  | ||||||
| 					{ |  | ||||||
| 						render_target->Resize(D2D1::SizeU(width, height)); |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "vector.hpp" | #include "vector.hpp" | ||||||
|  | #include <d2d1.h> | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -73,6 +74,15 @@ namespace easy2d | ||||||
| 				); | 				); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			inline operator D2D1_MATRIX_3X2_F () const | ||||||
|  | 			{ | ||||||
|  | 				return D2D1_MATRIX_3X2_F{ | ||||||
|  | 					_11, _12, | ||||||
|  | 					_21, _22, | ||||||
|  | 					_31, _32 | ||||||
|  | 				}; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			inline Matrix& Identity() | 			inline Matrix& Identity() | ||||||
| 			{ | 			{ | ||||||
| 				_11 = 1.f; | 				_11 = 1.f; | ||||||
|  | @ -90,12 +100,24 @@ namespace easy2d | ||||||
| 				return *this; | 				return *this; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			inline Matrix& Translate(float x, float y) | ||||||
|  | 			{ | ||||||
|  | 				*this = *this * Matrix::Translation(x, y); | ||||||
|  | 				return *this; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			inline Matrix& Scale(const Vector2& v, const Vector2& center) | 			inline Matrix& Scale(const Vector2& v, const Vector2& center) | ||||||
| 			{ | 			{ | ||||||
| 				*this = *this * Matrix::Scaling(v, center); | 				*this = *this * Matrix::Scaling(v, center); | ||||||
| 				return *this; | 				return *this; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			inline Matrix& Scale(float xscale, float yscale, const Vector2& center) | ||||||
|  | 			{ | ||||||
|  | 				*this = *this * Matrix::Scaling(xscale, yscale, center); | ||||||
|  | 				return *this; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			inline Matrix& Rotate(float angle, const Vector2& center) | 			inline Matrix& Rotate(float angle, const Vector2& center) | ||||||
| 			{ | 			{ | ||||||
| 				*this = *this * Matrix::Rotation(angle, center); | 				*this = *this * Matrix::Rotation(angle, center); | ||||||
|  |  | ||||||
|  | @ -37,25 +37,13 @@ namespace easy2d | ||||||
| 		{ | 		{ | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		Transform::operator D2D1::Matrix3x2F() const | 		Matrix Transform::ToMatrix() const | ||||||
| 		{ | 		{ | ||||||
| 			auto pivot = D2D1::Point2F(size.width * pivot_x, size.height * pivot_y); | 			auto pivot = Vector2(size.width * pivot_x, size.height * pivot_y); | ||||||
| 			auto matrix = D2D1::Matrix3x2F::Scale( | 			return Matrix().Scale(scale_x, scale_y, pivot) | ||||||
| 				scale_x, | 				.Skew(skew_x, skew_y, pivot) | ||||||
| 				scale_y, | 				.Rotate(rotation, pivot) | ||||||
| 				pivot | 				.Translate(position - pivot); | ||||||
| 			) * D2D1::Matrix3x2F::Skew( |  | ||||||
| 				skew_x, |  | ||||||
| 				skew_y, |  | ||||||
| 				pivot |  | ||||||
| 			) * D2D1::Matrix3x2F::Rotation( |  | ||||||
| 				rotation, |  | ||||||
| 				pivot |  | ||||||
| 			) * D2D1::Matrix3x2F::Translation( |  | ||||||
| 				position.x - pivot.x, |  | ||||||
| 				position.y - pivot.y |  | ||||||
| 			); |  | ||||||
| 			return matrix; |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool Transform::operator==(const Transform & other) const | 		bool Transform::operator==(const Transform & other) const | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "../base/BaseTypes.h" | #include "../base/BaseTypes.h" | ||||||
| #include "../base/Size.h" | #include "../base/Size.h" | ||||||
| #include <d2d1.h> | #include "Matrix.hpp" | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -43,7 +43,7 @@ namespace easy2d | ||||||
| 		public: | 		public: | ||||||
| 			Transform(); | 			Transform(); | ||||||
| 
 | 
 | ||||||
| 			explicit operator D2D1::Matrix3x2F() const; | 			Matrix ToMatrix() const; | ||||||
| 
 | 
 | ||||||
| 			bool operator== (const Transform& other) const; | 			bool operator== (const Transform& other) const; | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "scalar.hpp" | #include "scalar.hpp" | ||||||
|  | #include <d2d1.h> | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
|  | @ -85,6 +86,11 @@ namespace easy2d | ||||||
| 			{ | 			{ | ||||||
| 				return Vector2(x - v.x, y - v.y).Length(); | 				return Vector2(x - v.x, y - v.y).Length(); | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			inline operator D2D1_POINT_2F () const | ||||||
|  | 			{ | ||||||
|  | 				return D2D1_POINT_2F{ x, y }; | ||||||
|  | 			} | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
		Loading…
	
		Reference in New Issue