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;
|
ID2D1Bitmap* bitmap = nullptr;
|
||||||
|
HRESULT hr = render::instance.CreateBitmapFromResource(res, &bitmap);
|
||||||
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;
|
|
||||||
|
|
||||||
// 加载资源
|
|
||||||
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;
|
ID2D1Bitmap* bitmap = nullptr;
|
||||||
ID2D1HwndRenderTarget* render_target = render::D2D.HwndRenderTarget;
|
HRESULT hr = render::instance.CreateBitmapFromFile(file_name, &bitmap);
|
||||||
IWICBitmapDecoder* decoder = nullptr;
|
|
||||||
IWICBitmapFrameDecode* source = nullptr;
|
|
||||||
IWICStream* stream = nullptr;
|
|
||||||
IWICFormatConverter* converter = nullptr;
|
|
||||||
ID2D1Bitmap* bitmap = nullptr;
|
|
||||||
|
|
||||||
// 创建解码器
|
|
||||||
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
|
||||||
{
|
{
|
||||||
|
|
@ -446,9 +447,8 @@ namespace easy2d
|
||||||
void UpdateTime();
|
void UpdateTime();
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -65,17 +66,17 @@ namespace easy2d
|
||||||
virtual void Reset() { };
|
virtual void Reset() { };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool done_;
|
bool done_;
|
||||||
float duration_;
|
float duration_;
|
||||||
float process_;
|
float process_;
|
||||||
time::TimePoint started_;
|
time::TimePoint started_;
|
||||||
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");
|
|
||||||
}
|
|
||||||
else if (ms == 0)
|
|
||||||
{
|
|
||||||
result.append(std::to_wstring(sec)).append(L"s");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
auto float_to_str = [](float val) -> std::wstring
|
||||||
|
{
|
||||||
|
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