update: modern singleton pattern
This commit is contained in:
parent
2b366e42be
commit
d2532c09db
|
|
@ -38,6 +38,8 @@ namespace easy2d
|
|||
friend class Sequence;
|
||||
friend class Spawn;
|
||||
|
||||
E2D_DISABLE_COPY(Action);
|
||||
|
||||
public:
|
||||
Action();
|
||||
|
||||
|
|
@ -92,9 +94,6 @@ namespace easy2d
|
|||
// 获取动作结束状态
|
||||
virtual bool IsDone() const;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Action);
|
||||
|
||||
protected:
|
||||
String name_;
|
||||
bool running_;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace easy2d
|
|||
// Loop
|
||||
//-------------------------------------------------------
|
||||
|
||||
Loop::Loop(Action * action, int times /* = -1 */)
|
||||
Loop::Loop(Action * action, int times)
|
||||
: action_(action)
|
||||
, times_(0)
|
||||
, total_times_(times)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace easy2d
|
|||
class Loop
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(Loop);
|
||||
|
||||
public:
|
||||
explicit Loop(
|
||||
Action * action, /* 执行循环的动作 */
|
||||
|
|
@ -45,8 +47,6 @@ namespace easy2d
|
|||
virtual void Reset() override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Loop);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -67,6 +67,8 @@ namespace easy2d
|
|||
class Sequence
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(Sequence);
|
||||
|
||||
public:
|
||||
typedef std::vector<Action*> Actions;
|
||||
|
||||
|
|
@ -98,8 +100,6 @@ namespace easy2d
|
|||
virtual void Reset() override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Sequence);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -119,6 +119,8 @@ namespace easy2d
|
|||
class Spawn
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(Spawn);
|
||||
|
||||
public:
|
||||
typedef std::vector<Action*> Actions;
|
||||
|
||||
|
|
@ -150,8 +152,6 @@ namespace easy2d
|
|||
virtual void Reset() override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Spawn);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace easy2d
|
|||
class FiniteTimeAction
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(FiniteTimeAction);
|
||||
|
||||
public:
|
||||
// 创建特定时长的持续动作
|
||||
explicit FiniteTimeAction(
|
||||
|
|
@ -37,8 +39,6 @@ namespace easy2d
|
|||
virtual void Reset() override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(FiniteTimeAction);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -58,6 +58,8 @@ namespace easy2d
|
|||
class MoveBy
|
||||
: public FiniteTimeAction
|
||||
{
|
||||
E2D_DISABLE_COPY(MoveBy);
|
||||
|
||||
public:
|
||||
explicit MoveBy(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -71,8 +73,6 @@ namespace easy2d
|
|||
virtual MoveBy * Reverse() const override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(MoveBy);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -90,6 +90,8 @@ namespace easy2d
|
|||
class MoveTo
|
||||
: public MoveBy
|
||||
{
|
||||
E2D_DISABLE_COPY(MoveTo);
|
||||
|
||||
public:
|
||||
explicit MoveTo(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -107,8 +109,6 @@ namespace easy2d
|
|||
}
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(MoveTo);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -121,6 +121,8 @@ namespace easy2d
|
|||
class JumpBy
|
||||
: public FiniteTimeAction
|
||||
{
|
||||
E2D_DISABLE_COPY(JumpBy);
|
||||
|
||||
public:
|
||||
explicit JumpBy(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -136,8 +138,6 @@ namespace easy2d
|
|||
virtual JumpBy * Reverse() const override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(JumpBy);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -157,6 +157,8 @@ namespace easy2d
|
|||
class JumpTo
|
||||
: public JumpBy
|
||||
{
|
||||
E2D_DISABLE_COPY(JumpTo);
|
||||
|
||||
public:
|
||||
explicit JumpTo(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -176,8 +178,6 @@ namespace easy2d
|
|||
}
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(JumpTo);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -190,6 +190,8 @@ namespace easy2d
|
|||
class ScaleBy
|
||||
: public FiniteTimeAction
|
||||
{
|
||||
E2D_DISABLE_COPY(ScaleBy);
|
||||
|
||||
public:
|
||||
explicit ScaleBy(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -209,8 +211,6 @@ namespace easy2d
|
|||
virtual ScaleBy * Reverse() const override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(ScaleBy);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -229,6 +229,8 @@ namespace easy2d
|
|||
class ScaleTo
|
||||
: public ScaleBy
|
||||
{
|
||||
E2D_DISABLE_COPY(ScaleTo);
|
||||
|
||||
public:
|
||||
explicit ScaleTo(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -252,8 +254,6 @@ namespace easy2d
|
|||
}
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(ScaleTo);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -267,6 +267,8 @@ namespace easy2d
|
|||
class OpacityBy
|
||||
: public FiniteTimeAction
|
||||
{
|
||||
E2D_DISABLE_COPY(OpacityBy);
|
||||
|
||||
public:
|
||||
explicit OpacityBy(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -280,8 +282,6 @@ namespace easy2d
|
|||
virtual OpacityBy * Reverse() const override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(OpacityBy);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -298,6 +298,8 @@ namespace easy2d
|
|||
class OpacityTo
|
||||
: public OpacityBy
|
||||
{
|
||||
E2D_DISABLE_COPY(OpacityTo);
|
||||
|
||||
public:
|
||||
explicit OpacityTo(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -315,8 +317,6 @@ namespace easy2d
|
|||
}
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(OpacityTo);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -329,14 +329,13 @@ namespace easy2d
|
|||
class FadeIn
|
||||
: public OpacityTo
|
||||
{
|
||||
E2D_DISABLE_COPY(FadeIn);
|
||||
|
||||
public:
|
||||
// 创建淡入动作
|
||||
explicit FadeIn(
|
||||
float duration /* 持续时长 */
|
||||
);
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(FadeIn);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -344,14 +343,13 @@ namespace easy2d
|
|||
class FadeOut
|
||||
: public OpacityTo
|
||||
{
|
||||
E2D_DISABLE_COPY(FadeOut);
|
||||
|
||||
public:
|
||||
// 创建淡出动作
|
||||
explicit FadeOut(
|
||||
float duration /* 持续时长 */
|
||||
);
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(FadeOut);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -359,6 +357,8 @@ namespace easy2d
|
|||
class RotateBy
|
||||
: public FiniteTimeAction
|
||||
{
|
||||
E2D_DISABLE_COPY(RotateBy);
|
||||
|
||||
public:
|
||||
explicit RotateBy(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -372,8 +372,6 @@ namespace easy2d
|
|||
virtual RotateBy * Reverse() const override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(RotateBy);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -390,6 +388,8 @@ namespace easy2d
|
|||
class RotateTo
|
||||
: public RotateBy
|
||||
{
|
||||
E2D_DISABLE_COPY(RotateTo);
|
||||
|
||||
public:
|
||||
explicit RotateTo(
|
||||
float duration, /* 持续时长 */
|
||||
|
|
@ -407,8 +407,6 @@ namespace easy2d
|
|||
}
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(RotateTo);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
@ -421,6 +419,8 @@ namespace easy2d
|
|||
class Delay
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(Delay);
|
||||
|
||||
public:
|
||||
explicit Delay(
|
||||
float duration /* 延迟时长(秒) */
|
||||
|
|
@ -436,8 +436,6 @@ namespace easy2d
|
|||
virtual void Reset() override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Delay);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ namespace easy2d
|
|||
class Animation
|
||||
: public RefCounter
|
||||
{
|
||||
E2D_DISABLE_COPY(Animation);
|
||||
|
||||
public:
|
||||
typedef std::vector<Image*> Images;
|
||||
|
||||
|
|
@ -75,9 +77,6 @@ namespace easy2d
|
|||
// 获取帧动画的倒转
|
||||
Animation * Reverse() const;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Animation);
|
||||
|
||||
protected:
|
||||
float interval_;
|
||||
Images frames_;
|
||||
|
|
@ -88,6 +87,8 @@ namespace easy2d
|
|||
class Animate
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(Animate);
|
||||
|
||||
public:
|
||||
Animate();
|
||||
|
||||
|
|
@ -115,8 +116,6 @@ namespace easy2d
|
|||
virtual void Reset() override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Animate);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "../math/vector.hpp"
|
||||
#include "Color.h"
|
||||
#include "Size.h"
|
||||
#include "Rect.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -33,9 +34,9 @@ namespace easy2d
|
|||
// 计算两点间距离: float distance = p1.Distance(p2);
|
||||
// 坐标可以相加减: Point p = Point(10, 10) + Point(20, 20); // p 的坐标是 (30, 30)
|
||||
//
|
||||
typedef math::Vector2 Point;
|
||||
using Point = math::Vector2;
|
||||
|
||||
typedef std::wstring String;
|
||||
using String = std::wstring;
|
||||
|
||||
// 方向
|
||||
enum class Direction : int
|
||||
|
|
@ -138,4 +139,11 @@ namespace easy2d
|
|||
Right = VK_RBUTTON, /* 鼠标右键 */
|
||||
Middle = VK_MBUTTON /* 鼠标中键 */
|
||||
};
|
||||
|
||||
// 图层属性
|
||||
struct LayerProperties
|
||||
{
|
||||
Rect area;
|
||||
float opacity;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ namespace easy2d
|
|||
class CallFunc
|
||||
: public Action
|
||||
{
|
||||
E2D_DISABLE_COPY(CallFunc);
|
||||
|
||||
typedef std::function<void()> Callback;
|
||||
|
||||
public:
|
||||
|
|
@ -42,8 +44,6 @@ namespace easy2d
|
|||
virtual CallFunc *Reverse() const override;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(CallFunc);
|
||||
|
||||
// 初始化动作
|
||||
virtual void Initialize() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ namespace easy2d
|
|||
{
|
||||
SafeRelease(stroke_style_);
|
||||
|
||||
stroke_style_ = render::instance.GetStrokeStyle(stroke);
|
||||
stroke_style_ = devices::Graphics::Instance().GetStrokeStyle(stroke);
|
||||
|
||||
if (stroke_style_)
|
||||
stroke_style_->AddRef();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ namespace easy2d
|
|||
class Canvas
|
||||
: public Node
|
||||
{
|
||||
E2D_DISABLE_COPY(Canvas);
|
||||
|
||||
public:
|
||||
Canvas(
|
||||
float width,
|
||||
|
|
@ -124,12 +126,9 @@ namespace easy2d
|
|||
float radius_y
|
||||
);
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Canvas);
|
||||
|
||||
private:
|
||||
float stroke_width_;
|
||||
StrokeStyle stroke_;
|
||||
StrokeStyle stroke_;
|
||||
ID2D1RenderTarget* render_target_;
|
||||
ID2D1SolidColorBrush* fill_brush_;
|
||||
ID2D1SolidColorBrush* line_brush_;
|
||||
|
|
|
|||
|
|
@ -34,16 +34,6 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
Game * instance = nullptr;
|
||||
}
|
||||
|
||||
Game * Game::GetInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
Game::Game()
|
||||
: quit_(true)
|
||||
, curr_scene_(nullptr)
|
||||
|
|
@ -51,12 +41,6 @@ namespace easy2d
|
|||
, transition_(nullptr)
|
||||
, debug_mode_(false)
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
throw std::runtime_error("同时只能存在一个游戏实例");
|
||||
}
|
||||
instance = this;
|
||||
|
||||
::CoInitialize(nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -66,25 +50,14 @@ namespace easy2d
|
|||
SafeRelease(curr_scene_);
|
||||
SafeRelease(next_scene_);
|
||||
|
||||
Image::ClearCache();
|
||||
Player::ClearCache();
|
||||
|
||||
render::instance.Uninitialize();
|
||||
audio::instance.Uninitialize();
|
||||
window::instance.Destroy();
|
||||
modules::Uninitialize();
|
||||
|
||||
instance = nullptr;
|
||||
|
||||
::CoUninitialize();
|
||||
}
|
||||
|
||||
void Game::Initialize(const window::Property& property)
|
||||
void Game::Initialize(const Options& options)
|
||||
{
|
||||
modules::Initialize();
|
||||
window::instance.Initialize(property);
|
||||
render::instance.Initialize(window::instance.handle);
|
||||
audio::instance.Initialize();
|
||||
Window::Instance().Initialize(options.title, options.width, options.height, options.icon, options.debug);
|
||||
devices::Graphics::Instance().Initialize(Window::Instance().GetHandle());
|
||||
devices::Audio::Instance().Initialize();
|
||||
|
||||
// 若开启了调试模式,打开控制台
|
||||
HWND console = ::GetConsoleWindow();
|
||||
|
|
@ -117,7 +90,7 @@ namespace easy2d
|
|||
}
|
||||
|
||||
::SetWindowLongPtrW(
|
||||
window::instance.handle,
|
||||
Window::Instance().GetHandle(),
|
||||
GWLP_USERDATA,
|
||||
PtrToUlong(this)
|
||||
);
|
||||
|
|
@ -134,8 +107,8 @@ namespace easy2d
|
|||
next_scene_ = nullptr;
|
||||
}
|
||||
|
||||
::ShowWindow(window::instance.handle, SW_SHOWNORMAL);
|
||||
::UpdateWindow(window::instance.handle);
|
||||
::ShowWindow(Window::Instance().GetHandle(), SW_SHOWNORMAL);
|
||||
::UpdateWindow(Window::Instance().GetHandle());
|
||||
|
||||
const int64_t min_interval = 5;
|
||||
auto last = time::Now();
|
||||
|
|
@ -151,10 +124,10 @@ namespace easy2d
|
|||
float dt = (now - last).Seconds();
|
||||
last = now;
|
||||
|
||||
input::instance.Update(
|
||||
window::instance.handle,
|
||||
window::instance.xscale,
|
||||
window::instance.yscale
|
||||
devices::Input::Instance().Update(
|
||||
Window::Instance().GetHandle(),
|
||||
Window::Instance().GetContentScaleX(),
|
||||
Window::Instance().GetContentScaleY()
|
||||
);
|
||||
|
||||
OnUpdate(dt);
|
||||
|
|
@ -277,7 +250,7 @@ namespace easy2d
|
|||
|
||||
void Game::DrawScene()
|
||||
{
|
||||
render::instance.BeginDraw(window::instance.handle);
|
||||
devices::Graphics::Instance().BeginDraw(Window::Instance().GetHandle());
|
||||
|
||||
if (transition_)
|
||||
{
|
||||
|
|
@ -292,21 +265,21 @@ namespace easy2d
|
|||
{
|
||||
if (curr_scene_ && curr_scene_->GetRoot())
|
||||
{
|
||||
render::instance.SetTransform(math::Matrix());
|
||||
render::instance.SetBrushOpacity(1.f);
|
||||
devices::Graphics::Instance().SetTransform(math::Matrix());
|
||||
devices::Graphics::Instance().SetBrushOpacity(1.f);
|
||||
curr_scene_->GetRoot()->DrawBorder();
|
||||
}
|
||||
if (next_scene_ && next_scene_->GetRoot())
|
||||
{
|
||||
render::instance.SetTransform(math::Matrix());
|
||||
render::instance.SetBrushOpacity(1.f);
|
||||
devices::Graphics::Instance().SetTransform(math::Matrix());
|
||||
devices::Graphics::Instance().SetBrushOpacity(1.f);
|
||||
next_scene_->GetRoot()->DrawBorder();
|
||||
}
|
||||
|
||||
render::instance.DrawDebugInfo();
|
||||
devices::Graphics::Instance().DrawDebugInfo();
|
||||
}
|
||||
|
||||
render::instance.EndDraw();
|
||||
devices::Graphics::Instance().EndDraw();
|
||||
}
|
||||
|
||||
void Game::SetDebugMode(bool enabled)
|
||||
|
|
|
|||
|
|
@ -27,12 +27,32 @@ namespace easy2d
|
|||
class Scene;
|
||||
class Transition;
|
||||
|
||||
struct Options
|
||||
{
|
||||
String title; /* 标题 */
|
||||
int width; /* 宽度 */
|
||||
int height; /* 高度 */
|
||||
LPCWSTR icon; /* 图标 */
|
||||
bool debug; /* 调试模式 */
|
||||
|
||||
Options()
|
||||
: title(L"Easy2D Game")
|
||||
, width(640)
|
||||
, height(480)
|
||||
, icon(nullptr)
|
||||
, debug(false)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
class Game
|
||||
{
|
||||
E2D_DISABLE_COPY(Game);
|
||||
|
||||
public:
|
||||
Game();
|
||||
|
||||
~Game();
|
||||
virtual ~Game();
|
||||
|
||||
// 更新时
|
||||
virtual void OnUpdate(float dt) {}
|
||||
|
|
@ -46,7 +66,7 @@ namespace easy2d
|
|||
|
||||
// 初始化
|
||||
void Initialize(
|
||||
const window::Property& property /* 窗口属性 */
|
||||
const Options& options /* 属性 */
|
||||
);
|
||||
|
||||
// 运行
|
||||
|
|
@ -80,12 +100,6 @@ namespace easy2d
|
|||
float dt
|
||||
);
|
||||
|
||||
// 获取实例
|
||||
static Game * GetInstance();
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Game);
|
||||
|
||||
private:
|
||||
bool debug_mode_;
|
||||
bool quit_;
|
||||
|
|
|
|||
|
|
@ -25,11 +25,6 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::map<size_t, ID2D1Bitmap*> bitmap_cache_;
|
||||
}
|
||||
|
||||
Image::Image()
|
||||
: bitmap_(nullptr)
|
||||
, crop_rect_()
|
||||
|
|
@ -73,13 +68,12 @@ namespace easy2d
|
|||
|
||||
bool Image::Load(Resource& res)
|
||||
{
|
||||
if (!Image::CacheBitmap(res))
|
||||
HRESULT hr = devices::Graphics::Instance().CreateBitmapFromResource(res, &bitmap_);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
E2D_WARNING("Load Image from file failed!");
|
||||
logs::Trace(L"Load Image from resource failed!", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
this->SetBitmap(bitmap_cache_.at(res.GetHashCode()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -87,16 +81,23 @@ namespace easy2d
|
|||
{
|
||||
E2D_WARNING_IF(file_name.empty(), "Image Load failed! Invalid file name.");
|
||||
|
||||
if (file_name.empty())
|
||||
return false;
|
||||
|
||||
if (!Image::CacheBitmap(file_name))
|
||||
File image_file;
|
||||
if (!image_file.Open(file_name))
|
||||
{
|
||||
E2D_WARNING("Load Image from file failed!");
|
||||
E2D_WARNING("Image file not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->SetBitmap(bitmap_cache_.at(std::hash<String>{}(file_name)));
|
||||
// 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加
|
||||
// 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
|
||||
String image_file_path = image_file.GetPath();
|
||||
|
||||
HRESULT hr = devices::Graphics::Instance().CreateBitmapFromFile(image_file_path, &bitmap_);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
logs::Trace(L"Load Image from file failed!", hr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -186,70 +187,6 @@ namespace easy2d
|
|||
return bitmap_;
|
||||
}
|
||||
|
||||
bool Image::CacheBitmap(Resource& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ID2D1Bitmap* bitmap = nullptr;
|
||||
HRESULT hr = render::instance.CreateBitmapFromResource(res, &bitmap);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||
}
|
||||
else
|
||||
{
|
||||
logs::Trace(L"CreateBitmapFromFile", hr);
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
bool Image::CacheBitmap(const String & file_name)
|
||||
{
|
||||
size_t hash_code = std::hash<String>{}(file_name);
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
return true;
|
||||
|
||||
File image_file;
|
||||
if (!image_file.Open(file_name))
|
||||
return false;
|
||||
|
||||
// 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加
|
||||
// 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
|
||||
String image_file_path = image_file.GetPath();
|
||||
|
||||
ID2D1Bitmap* bitmap = nullptr;
|
||||
HRESULT hr = render::instance.CreateBitmapFromFile(file_name, &bitmap);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||
}
|
||||
else
|
||||
{
|
||||
logs::Trace(L"CreateBitmapFromFile", hr);
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void Image::ClearCache()
|
||||
{
|
||||
if (bitmap_cache_.empty())
|
||||
return;
|
||||
|
||||
for (const auto& bitmap : bitmap_cache_)
|
||||
{
|
||||
bitmap.second->Release();
|
||||
}
|
||||
bitmap_cache_.clear();
|
||||
}
|
||||
|
||||
void Image::SetBitmap(ID2D1Bitmap * bitmap)
|
||||
{
|
||||
if (bitmap_ == bitmap)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ namespace easy2d
|
|||
class Image
|
||||
: public RefCounter
|
||||
{
|
||||
E2D_DISABLE_COPY(Image);
|
||||
|
||||
public:
|
||||
Image();
|
||||
|
||||
|
|
@ -100,22 +102,7 @@ namespace easy2d
|
|||
// 获取 ID2D1Bitmap 对象
|
||||
ID2D1Bitmap * GetBitmap() const;
|
||||
|
||||
// 헌왕뻠닸
|
||||
static void ClearCache();
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Image);
|
||||
|
||||
// 뻠닸 Bitmap 栗都
|
||||
static bool CacheBitmap(
|
||||
const String& file_name
|
||||
);
|
||||
|
||||
// 뻠닸 Bitmap 栗都
|
||||
static bool CacheBitmap(
|
||||
Resource& res
|
||||
);
|
||||
|
||||
// 设置 Bitmap
|
||||
void SetBitmap(
|
||||
ID2D1Bitmap * bitmap
|
||||
|
|
|
|||
|
|
@ -22,10 +22,8 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace input
|
||||
namespace devices
|
||||
{
|
||||
InputDevice instance;
|
||||
|
||||
InputDevice::InputDevice()
|
||||
{
|
||||
ZeroMemory(keys_, sizeof(keys_));
|
||||
|
|
@ -35,7 +33,7 @@ namespace easy2d
|
|||
{
|
||||
}
|
||||
|
||||
void InputDevice::Update(HWND hwnd, float xscale, float yscale)
|
||||
void InputDevice::Update(HWND hwnd, float scale_x, float scale_y)
|
||||
{
|
||||
::GetKeyboardState(keys_);
|
||||
|
||||
|
|
@ -43,7 +41,7 @@ namespace easy2d
|
|||
::GetCursorPos(&client_cursor_pos);
|
||||
::ScreenToClient(hwnd, &client_cursor_pos);
|
||||
|
||||
mouse_pos_ = Point(client_cursor_pos.x * xscale, client_cursor_pos.y * yscale);
|
||||
mouse_pos_ = Point(client_cursor_pos.x * scale_x, client_cursor_pos.y * scale_y);
|
||||
}
|
||||
|
||||
bool InputDevice::IsDown(KeyCode code)
|
||||
|
|
|
|||
|
|
@ -20,14 +20,18 @@
|
|||
|
||||
#pragma once
|
||||
#include "base.h"
|
||||
#include "Singleton.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace input
|
||||
namespace devices
|
||||
{
|
||||
// 输入设备
|
||||
class InputDevice
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(InputDevice);
|
||||
|
||||
E2D_DISABLE_COPY(InputDevice);
|
||||
|
||||
public:
|
||||
InputDevice();
|
||||
|
||||
|
|
@ -55,8 +59,8 @@ namespace easy2d
|
|||
// 刷新设备状态
|
||||
void Update(
|
||||
HWND hwnd,
|
||||
float xscale,
|
||||
float yscale
|
||||
float scale_x,
|
||||
float scale_y
|
||||
);
|
||||
|
||||
protected:
|
||||
|
|
@ -64,6 +68,6 @@ namespace easy2d
|
|||
Point mouse_pos_;
|
||||
};
|
||||
|
||||
extern InputDevice instance;
|
||||
E2D_DECLARE_SINGLETON_TYPE(InputDevice, Input);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,19 +32,19 @@ namespace easy2d
|
|||
|
||||
float MouseEvent::GetX() const
|
||||
{
|
||||
return ((float)(short)LOWORD(l_param_)) * window::instance.xscale;
|
||||
return ((float)(short)LOWORD(l_param_)) * Window::Instance().GetContentScaleX();
|
||||
}
|
||||
|
||||
float MouseEvent::GetY() const
|
||||
{
|
||||
return ((float)(short)HIWORD(l_param_)) * window::instance.yscale;
|
||||
return ((float)(short)HIWORD(l_param_)) * Window::Instance().GetContentScaleY();
|
||||
}
|
||||
|
||||
Point MouseEvent::GetPosition() const
|
||||
{
|
||||
return Point(
|
||||
((float)(short)LOWORD(l_param_)) * window::instance.xscale,
|
||||
((float)(short)HIWORD(l_param_)) * window::instance.yscale
|
||||
((float)(short)LOWORD(l_param_)) * Window::Instance().GetContentScaleX(),
|
||||
((float)(short)HIWORD(l_param_)) * Window::Instance().GetContentScaleY()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "Music.h"
|
||||
#include "Transcoder.h"
|
||||
#include "File.h"
|
||||
#include "../base/modules.h"
|
||||
#include "../base/audio.h"
|
||||
#include "../base/logs.h"
|
||||
#include "../utils/Transcoder.h"
|
||||
#include "../utils/File.h"
|
||||
#include "modules.h"
|
||||
#include "audio.h"
|
||||
#include "logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -71,7 +71,7 @@ namespace easy2d
|
|||
File music_file;
|
||||
if (!music_file.Open(file_path))
|
||||
{
|
||||
E2D_WARNING("Media file not found.");
|
||||
logs::Trace(L"Media file not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -80,12 +80,14 @@ namespace easy2d
|
|||
String music_file_path = music_file.GetPath();
|
||||
|
||||
Transcoder transcoder;
|
||||
if (!transcoder.LoadMediaFile(music_file_path.c_str(), &wave_data_, &size_))
|
||||
HRESULT hr = transcoder.LoadMediaFile(music_file_path.c_str(), &wave_data_, &size_);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
logs::Trace(L"Load media from file failed.", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = audio::instance.CreateVoice(&voice_, transcoder.GetWaveFormatEx());
|
||||
hr = devices::Audio::Instance().CreateVoice(&voice_, transcoder.GetWaveFormatEx());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (wave_data_)
|
||||
|
|
@ -109,12 +111,15 @@ namespace easy2d
|
|||
}
|
||||
|
||||
Transcoder transcoder;
|
||||
if (!transcoder.LoadMediaResource(res, &wave_data_, &size_))
|
||||
HRESULT hr = transcoder.LoadMediaResource(res, &wave_data_, &size_);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
logs::Trace(L"Load media from resource failed.", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = audio::instance.CreateVoice(&voice_, transcoder.GetWaveFormatEx());
|
||||
hr = devices::Audio::Instance().CreateVoice(&voice_, transcoder.GetWaveFormatEx());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (wave_data_)
|
||||
|
|
@ -134,48 +139,26 @@ namespace easy2d
|
|||
{
|
||||
if (!opened_)
|
||||
{
|
||||
E2D_WARNING("Music must be opened first!");
|
||||
logs::Trace(L"Music must be opened first!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (voice_ == nullptr)
|
||||
{
|
||||
E2D_WARNING("IXAudio2SourceVoice Null pointer exception!");
|
||||
return false;
|
||||
}
|
||||
|
||||
XAUDIO2_VOICE_STATE state;
|
||||
voice_->GetState(&state);
|
||||
if (state.BuffersQueued)
|
||||
{
|
||||
UINT32 buffers_queued = 0;
|
||||
voice_.GetBuffersQueued(&buffers_queued);
|
||||
if (buffers_queued)
|
||||
Stop();
|
||||
}
|
||||
|
||||
if (loop_count < 0)
|
||||
{
|
||||
loop_count = XAUDIO2_LOOP_INFINITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
loop_count = std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1);
|
||||
}
|
||||
|
||||
// Ìá½» wave Ñù±¾Êý¾Ý
|
||||
XAUDIO2_BUFFER buffer = { 0 };
|
||||
buffer.pAudioData = wave_data_;
|
||||
buffer.Flags = XAUDIO2_END_OF_STREAM;
|
||||
buffer.AudioBytes = size_;
|
||||
buffer.LoopCount = loop_count;
|
||||
|
||||
HRESULT hr;
|
||||
if (FAILED(hr = voice_->SubmitSourceBuffer(&buffer)))
|
||||
HRESULT hr = voice_.Play(wave_data_, size_, static_cast<UINT32>(loop_count));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
logs::Trace(L"Submitting source buffer error", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = voice_->Start(0);
|
||||
|
||||
playing_ = SUCCEEDED(hr);
|
||||
|
||||
return playing_;
|
||||
|
|
@ -183,48 +166,25 @@ namespace easy2d
|
|||
|
||||
void Music::Pause()
|
||||
{
|
||||
if (voice_)
|
||||
{
|
||||
if (SUCCEEDED(voice_->Stop()))
|
||||
{
|
||||
playing_ = false;
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(voice_.Pause()))
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
void Music::Resume()
|
||||
{
|
||||
if (voice_)
|
||||
{
|
||||
if (SUCCEEDED(voice_->Start()))
|
||||
{
|
||||
playing_ = true;
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(voice_.Resume()))
|
||||
playing_ = true;
|
||||
}
|
||||
|
||||
void Music::Stop()
|
||||
{
|
||||
if (voice_)
|
||||
{
|
||||
if (SUCCEEDED(voice_->Stop()))
|
||||
{
|
||||
voice_->ExitLoop();
|
||||
voice_->FlushSourceBuffers();
|
||||
playing_ = false;
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(voice_.Stop()))
|
||||
playing_ = false;
|
||||
}
|
||||
|
||||
void Music::Close()
|
||||
{
|
||||
if (voice_)
|
||||
{
|
||||
voice_->Stop();
|
||||
voice_->FlushSourceBuffers();
|
||||
voice_->DestroyVoice();
|
||||
voice_ = nullptr;
|
||||
}
|
||||
voice_.Destroy();
|
||||
|
||||
if (wave_data_)
|
||||
{
|
||||
|
|
@ -238,11 +198,11 @@ namespace easy2d
|
|||
|
||||
bool Music::IsPlaying() const
|
||||
{
|
||||
if (opened_ && voice_)
|
||||
if (opened_)
|
||||
{
|
||||
XAUDIO2_VOICE_STATE state;
|
||||
voice_->GetState(&state);
|
||||
if (state.BuffersQueued && playing_)
|
||||
UINT32 buffers_queued = 0;
|
||||
voice_.GetBuffersQueued(&buffers_queued);
|
||||
if (buffers_queued && playing_)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -250,27 +210,13 @@ namespace easy2d
|
|||
|
||||
float Music::GetVolume() const
|
||||
{
|
||||
if (voice_)
|
||||
{
|
||||
float volume = 0.f;
|
||||
voice_->GetVolume(&volume);
|
||||
return volume;
|
||||
}
|
||||
return 0.f;
|
||||
float volume = 0.f;
|
||||
voice_.GetVolume(&volume);
|
||||
return volume;
|
||||
}
|
||||
|
||||
bool Music::SetVolume(float volume)
|
||||
{
|
||||
if (voice_)
|
||||
{
|
||||
volume = std::min(std::max(volume, -224.f), 224.f);
|
||||
return SUCCEEDED(voice_->SetVolume(volume));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IXAudio2SourceVoice * Music::GetSourceVoice() const
|
||||
{
|
||||
return voice_;
|
||||
return SUCCEEDED(voice_.SetVolume(volume));
|
||||
}
|
||||
}
|
||||
|
|
@ -19,9 +19,10 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../base/base.h"
|
||||
#include "../base/RefCounter.h"
|
||||
#include "../base/Resource.h"
|
||||
#include "base.h"
|
||||
#include "audio.h"
|
||||
#include "RefCounter.h"
|
||||
#include "Resource.h"
|
||||
#include <xaudio2.h>
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -30,6 +31,8 @@ namespace easy2d
|
|||
class Music
|
||||
: public RefCounter
|
||||
{
|
||||
E2D_DISABLE_COPY(Music);
|
||||
|
||||
public:
|
||||
Music();
|
||||
|
||||
|
|
@ -81,17 +84,11 @@ namespace easy2d
|
|||
float volume /* 1 为原始音量, 大于 1 为放大音量, 0 为最小音量 */
|
||||
);
|
||||
|
||||
// 获取 IXAudio2SourceVoice 对象
|
||||
IXAudio2SourceVoice * GetSourceVoice() const;
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Music);
|
||||
|
||||
protected:
|
||||
bool opened_;
|
||||
bool playing_;
|
||||
UINT32 size_;
|
||||
BYTE* wave_data_;
|
||||
IXAudio2SourceVoice* voice_;
|
||||
bool opened_;
|
||||
bool playing_;
|
||||
UINT32 size_;
|
||||
BYTE* wave_data_;
|
||||
Voice voice_;
|
||||
};
|
||||
}
|
||||
|
|
@ -77,12 +77,12 @@ namespace easy2d
|
|||
|
||||
if (clip_enabled_)
|
||||
{
|
||||
render::instance.PushClip(final_matrix_, transform_.size);
|
||||
devices::Graphics::Instance().PushClip(final_matrix_, transform_.size);
|
||||
}
|
||||
|
||||
if (children_.empty())
|
||||
{
|
||||
render::instance.SetTransform(final_matrix_);
|
||||
devices::Graphics::Instance().SetTransform(final_matrix_);
|
||||
OnDraw();
|
||||
}
|
||||
else
|
||||
|
|
@ -114,7 +114,7 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
render::instance.SetTransform(final_matrix_);
|
||||
devices::Graphics::Instance().SetTransform(final_matrix_);
|
||||
OnDraw();
|
||||
|
||||
// 访问剩余节点
|
||||
|
|
@ -124,7 +124,7 @@ namespace easy2d
|
|||
|
||||
if (clip_enabled_)
|
||||
{
|
||||
render::instance.PopClip();
|
||||
devices::Graphics::Instance().PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ namespace easy2d
|
|||
{
|
||||
if (border_)
|
||||
{
|
||||
render::instance.DrawGeometry(border_, border_color_, 1.f, 1.5f);
|
||||
devices::Graphics::Instance().DrawGeometry(border_, border_color_, 1.f, 1.5f);
|
||||
}
|
||||
|
||||
for (const auto& child : children_)
|
||||
|
|
@ -212,7 +212,7 @@ namespace easy2d
|
|||
SafeRelease(border_);
|
||||
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateRectGeometry(final_matrix_, transform_.size, &border_)
|
||||
devices::Graphics::Instance().CreateRectGeometry(final_matrix_, transform_.size, &border_)
|
||||
);
|
||||
|
||||
// 通知子节点进行转换
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ namespace easy2d
|
|||
friend class Game;
|
||||
friend class Scene;
|
||||
|
||||
E2D_DISABLE_COPY(Node);
|
||||
|
||||
public:
|
||||
typedef std::vector<Node*> Nodes;
|
||||
typedef std::vector<Action*> Actions;
|
||||
|
|
@ -418,8 +420,6 @@ namespace easy2d
|
|||
);
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Node);
|
||||
|
||||
// 渲染节点边缘
|
||||
void DrawBorder();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "BaseTypes.h"
|
||||
#include "../math/vector.hpp"
|
||||
#include "Size.h"
|
||||
#include <d2d1.h>
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -34,9 +35,11 @@ namespace easy2d
|
|||
//
|
||||
class Rect
|
||||
{
|
||||
using Point = math::Vector2;
|
||||
|
||||
public:
|
||||
Point origin; // 左上角坐标
|
||||
Size size; // 宽度和高度
|
||||
Point origin; // 左上角坐标
|
||||
Size size; // 宽度和高度
|
||||
|
||||
public:
|
||||
Rect() {}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ namespace easy2d
|
|||
class Scene
|
||||
: public RefCounter
|
||||
{
|
||||
E2D_DISABLE_COPY(Scene);
|
||||
|
||||
public:
|
||||
Scene();
|
||||
|
||||
|
|
@ -79,9 +81,6 @@ namespace easy2d
|
|||
// »ñȡת»»¾ØÕó
|
||||
const math::Matrix& GetTransform() const;
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Scene);
|
||||
|
||||
private:
|
||||
Node* root_;
|
||||
math::Matrix transform_;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
template <typename T>
|
||||
class ISingleton
|
||||
{
|
||||
public:
|
||||
static inline T& Instance();
|
||||
|
||||
static inline void Destroy();
|
||||
|
||||
private:
|
||||
ISingleton() {}
|
||||
|
||||
~ISingleton() {}
|
||||
|
||||
ISingleton(const ISingleton&) = delete;
|
||||
|
||||
ISingleton & operator= (const ISingleton &) = delete;
|
||||
|
||||
static std::unique_ptr<T> instance_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T & easy2d::ISingleton<T>::Instance()
|
||||
{
|
||||
if (!instance_)
|
||||
instance_.reset(new (std::nothrow) T);
|
||||
return *instance_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void easy2d::ISingleton<T>::Destroy()
|
||||
{
|
||||
if (instance_)
|
||||
instance_.reset();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::unique_ptr<T> easy2d::ISingleton<T>::instance_;
|
||||
}
|
||||
|
||||
// Class that will implement the singleton mode,
|
||||
// must use the macro in it's delare file
|
||||
|
||||
#ifndef E2D_DECLARE_SINGLETON
|
||||
#define E2D_DECLARE_SINGLETON( type ) \
|
||||
friend class ::std::unique_ptr< type >; \
|
||||
friend struct ::std::default_delete< type >;\
|
||||
friend class ::easy2d::ISingleton< type >
|
||||
#endif
|
||||
|
||||
#ifndef E2D_DECLARE_SINGLETON_TYPE
|
||||
#define E2D_DECLARE_SINGLETON_TYPE( type, singleton_type ) using singleton_type = ::easy2d::ISingleton< type >
|
||||
#endif
|
||||
|
|
@ -135,7 +135,7 @@ namespace easy2d
|
|||
if (image_ && image_->GetBitmap())
|
||||
{
|
||||
auto crop_pos = image_->GetCropPos();
|
||||
render::instance.DrawImage(
|
||||
devices::Graphics::Instance().DrawImage(
|
||||
image_,
|
||||
GetDisplayOpacity(),
|
||||
Rect(Point(), GetTransform().size),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ namespace easy2d
|
|||
class Sprite
|
||||
: public Node
|
||||
{
|
||||
E2D_DISABLE_COPY(Sprite);
|
||||
|
||||
public:
|
||||
Sprite();
|
||||
|
||||
|
|
@ -81,9 +83,6 @@ namespace easy2d
|
|||
// äÖČžžŤÁé
|
||||
virtual void OnDraw() const override;
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Sprite);
|
||||
|
||||
private:
|
||||
Image* image_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -318,16 +318,16 @@ namespace easy2d
|
|||
// 创建文本区域
|
||||
D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height);
|
||||
// 设置画刷颜色和透明度
|
||||
render::instance.SetBrushOpacity(GetDisplayOpacity());
|
||||
devices::Graphics::Instance().SetBrushOpacity(GetDisplayOpacity());
|
||||
// 获取文本渲染器
|
||||
render::instance.SetTextStyle(
|
||||
devices::Graphics::Instance().SetTextStyle(
|
||||
style_.color,
|
||||
style_.outline,
|
||||
style_.outline_color,
|
||||
style_.outline_width,
|
||||
style_.outline_stroke
|
||||
);
|
||||
render::instance.DrawTextLayout(text_layout_);
|
||||
devices::Graphics::Instance().DrawTextLayout(text_layout_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -344,7 +344,7 @@ namespace easy2d
|
|||
SafeRelease(text_format_);
|
||||
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateTextFormat(
|
||||
devices::Graphics::Instance().CreateTextFormat(
|
||||
&text_format_,
|
||||
font_
|
||||
)
|
||||
|
|
@ -399,7 +399,7 @@ namespace easy2d
|
|||
if (style_.wrap)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateTextLayout(
|
||||
devices::Graphics::Instance().CreateTextLayout(
|
||||
&text_layout_,
|
||||
text_,
|
||||
text_format_,
|
||||
|
|
@ -416,7 +416,7 @@ namespace easy2d
|
|||
{
|
||||
// 为防止文本对齐问题,根据先创建 layout 以获取宽度
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateTextLayout(
|
||||
devices::Graphics::Instance().CreateTextLayout(
|
||||
&text_layout_,
|
||||
text_,
|
||||
text_format_,
|
||||
|
|
@ -433,7 +433,7 @@ namespace easy2d
|
|||
// 重新创建 layout
|
||||
SafeRelease(text_layout_);
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateTextLayout(
|
||||
devices::Graphics::Instance().CreateTextLayout(
|
||||
&text_layout_,
|
||||
text_,
|
||||
text_format_,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ namespace easy2d
|
|||
class Text
|
||||
: public Node
|
||||
{
|
||||
E2D_DISABLE_COPY(Text);
|
||||
|
||||
public:
|
||||
// 文本对齐方式
|
||||
enum class Align
|
||||
|
|
@ -221,8 +223,6 @@ namespace easy2d
|
|||
virtual void OnDraw() const override;
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Text);
|
||||
|
||||
// 重新排版文字
|
||||
void Reset();
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace easy2d
|
|||
bShowOutline_ = outline;
|
||||
sOutlineColor_ = outline_color;
|
||||
fOutlineWidth = 2 * outline_width;
|
||||
pCurrStrokeStyle_ = render::instance.GetStrokeStyle(StrokeStyle(outlineJoin));
|
||||
pCurrStrokeStyle_ = devices::Graphics::Instance().GetStrokeStyle(StrokeStyle(outlineJoin));
|
||||
}
|
||||
|
||||
STDMETHODIMP ITextRenderer::DrawGlyphRun(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "Node.h"
|
||||
#include "Scene.h"
|
||||
#include "window.h"
|
||||
#include "render.h"
|
||||
#include "../math/Matrix.hpp"
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -73,22 +74,19 @@ namespace easy2d
|
|||
if (in_scene_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateLayer(&in_layer_)
|
||||
devices::Graphics::Instance().CreateLayer(&in_layer_)
|
||||
);
|
||||
}
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
render::instance.CreateLayer(&out_layer_)
|
||||
devices::Graphics::Instance().CreateLayer(&out_layer_)
|
||||
);
|
||||
}
|
||||
|
||||
window_size_ = window::instance.GetSize();
|
||||
out_layer_prop_ = in_layer_prop_ = render::LayerProperties{
|
||||
Rect(Point(), window_size_),
|
||||
1.f
|
||||
};
|
||||
window_size_ = Window::Instance().GetSize();
|
||||
out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f };
|
||||
}
|
||||
|
||||
void Transition::Update()
|
||||
|
|
@ -113,30 +111,30 @@ namespace easy2d
|
|||
{
|
||||
if (out_scene_)
|
||||
{
|
||||
render::instance.PushClip(
|
||||
devices::Graphics::Instance().PushClip(
|
||||
out_scene_->GetTransform(),
|
||||
window_size_
|
||||
);
|
||||
render::instance.PushLayer(out_layer_, out_layer_prop_);
|
||||
devices::Graphics::Instance().PushLayer(out_layer_, out_layer_prop_);
|
||||
|
||||
out_scene_->Draw();
|
||||
|
||||
render::instance.PopLayer();
|
||||
render::instance.PopClip();
|
||||
devices::Graphics::Instance().PopLayer();
|
||||
devices::Graphics::Instance().PopClip();
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
render::instance.PushClip(
|
||||
devices::Graphics::Instance().PushClip(
|
||||
in_scene_->GetTransform(),
|
||||
window_size_
|
||||
);
|
||||
render::instance.PushLayer(in_layer_, in_layer_prop_);
|
||||
devices::Graphics::Instance().PushLayer(in_layer_, in_layer_prop_);
|
||||
|
||||
in_scene_->Draw();
|
||||
|
||||
render::instance.PopLayer();
|
||||
render::instance.PopClip();
|
||||
devices::Graphics::Instance().PopLayer();
|
||||
devices::Graphics::Instance().PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#pragma once
|
||||
#include "base.h"
|
||||
#include "time.h"
|
||||
#include "render.h"
|
||||
#include "RefCounter.h"
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -75,8 +74,8 @@ namespace easy2d
|
|||
Scene* in_scene_;
|
||||
ID2D1Layer* out_layer_;
|
||||
ID2D1Layer* in_layer_;
|
||||
render::LayerProperties out_layer_prop_;
|
||||
render::LayerProperties in_layer_prop_;
|
||||
LayerProperties out_layer_prop_;
|
||||
LayerProperties in_layer_prop_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,18 +27,161 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace audio
|
||||
//-------------------------------------------------------
|
||||
// Voice
|
||||
//-------------------------------------------------------
|
||||
|
||||
Voice::Voice()
|
||||
: source_voice_(nullptr)
|
||||
{
|
||||
AudioDevice instance;
|
||||
}
|
||||
|
||||
Voice::Voice(IXAudio2SourceVoice * source_voice)
|
||||
: source_voice_(source_voice)
|
||||
{
|
||||
}
|
||||
|
||||
Voice::~Voice()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
devices::Audio::Instance().DeleteVoice(this);
|
||||
}
|
||||
|
||||
HRESULT Voice::Play(const BYTE * wave_data, UINT32 data_size, UINT32 loop_count)
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
XAUDIO2_BUFFER buffer = { 0 };
|
||||
buffer.pAudioData = wave_data;
|
||||
buffer.Flags = XAUDIO2_END_OF_STREAM;
|
||||
buffer.AudioBytes = data_size;
|
||||
buffer.LoopCount = loop_count;
|
||||
|
||||
HRESULT hr = source_voice_->SubmitSourceBuffer(&buffer);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = source_voice_->Start();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Voice::Pause()
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return source_voice_->Stop();
|
||||
}
|
||||
|
||||
HRESULT Voice::Resume()
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return source_voice_->Start();
|
||||
}
|
||||
|
||||
HRESULT Voice::Stop()
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr = source_voice_->Stop();
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = source_voice_->ExitLoop();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = source_voice_->FlushSourceBuffers();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Voice::GetVolume(float * volume) const
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (volume == nullptr)
|
||||
return E_POINTER;
|
||||
|
||||
source_voice_->GetVolume(volume);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Voice::SetVolume(float volume)
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
volume = std::min(std::max(volume, -224.f), 224.f);
|
||||
return source_voice_->SetVolume(volume);
|
||||
}
|
||||
|
||||
HRESULT Voice::GetBuffersQueued(UINT32 * queued) const
|
||||
{
|
||||
if (!source_voice_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (queued == nullptr)
|
||||
return E_POINTER;
|
||||
|
||||
XAUDIO2_VOICE_STATE state;
|
||||
source_voice_->GetState(&state);
|
||||
*queued = state.BuffersQueued;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Voice::Destroy()
|
||||
{
|
||||
if (source_voice_)
|
||||
{
|
||||
source_voice_->Stop();
|
||||
source_voice_->FlushSourceBuffers();
|
||||
source_voice_->DestroyVoice();
|
||||
source_voice_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::SetSourceVoice(IXAudio2SourceVoice * source_voice)
|
||||
{
|
||||
Destroy();
|
||||
source_voice_ = source_voice;
|
||||
}
|
||||
|
||||
|
||||
namespace devices
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// AudioDevice
|
||||
//-------------------------------------------------------
|
||||
|
||||
AudioDevice::AudioDevice()
|
||||
: x_audio2_(nullptr)
|
||||
, mastering_voice_(nullptr)
|
||||
{
|
||||
modules::Initialize();
|
||||
}
|
||||
|
||||
AudioDevice::~AudioDevice()
|
||||
{
|
||||
ClearVoiceCache();
|
||||
|
||||
if (mastering_voice_)
|
||||
{
|
||||
mastering_voice_->DestroyVoice();
|
||||
mastering_voice_ = nullptr;
|
||||
}
|
||||
|
||||
SafeRelease(x_audio2_);
|
||||
|
||||
modules::MediaFoundation.MFShutdown();
|
||||
|
||||
modules::Destroy();
|
||||
}
|
||||
|
||||
void AudioDevice::Initialize()
|
||||
|
|
@ -56,22 +199,42 @@ namespace easy2d
|
|||
);
|
||||
}
|
||||
|
||||
void AudioDevice::Uninitialize()
|
||||
HRESULT AudioDevice::CreateVoice(Voice* voice, WAVEFORMATEX * wfx)
|
||||
{
|
||||
if (mastering_voice_)
|
||||
HRESULT hr;
|
||||
IXAudio2SourceVoice* source_voice;
|
||||
|
||||
if (!voice)
|
||||
return E_POINTER;
|
||||
|
||||
hr = x_audio2_->CreateSourceVoice(&source_voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
mastering_voice_->DestroyVoice();
|
||||
mastering_voice_ = nullptr;
|
||||
voice->SetSourceVoice(source_voice);
|
||||
voice_cache_.push_back(voice);
|
||||
}
|
||||
|
||||
SafeRelease(x_audio2_);
|
||||
|
||||
modules::MediaFoundation.MFShutdown();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT AudioDevice::CreateVoice(IXAudio2SourceVoice ** voice, WAVEFORMATEX * wfx)
|
||||
void AudioDevice::DeleteVoice(Voice * voice)
|
||||
{
|
||||
return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
||||
for (auto iter = voice_cache_.begin(); iter != voice_cache_.end(); ++iter)
|
||||
{
|
||||
if (*iter == voice)
|
||||
{
|
||||
voice_cache_.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDevice::ClearVoiceCache()
|
||||
{
|
||||
for (auto voice : voice_cache_)
|
||||
{
|
||||
voice->Destroy();
|
||||
}
|
||||
voice_cache_.clear();
|
||||
}
|
||||
|
||||
void AudioDevice::Open()
|
||||
|
|
|
|||
|
|
@ -20,41 +20,97 @@
|
|||
|
||||
#pragma once
|
||||
#include "macros.h"
|
||||
#include "Singleton.hpp"
|
||||
#include <xaudio2.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace audio
|
||||
class Voice
|
||||
{
|
||||
E2D_DISABLE_COPY(Voice);
|
||||
|
||||
public:
|
||||
Voice();
|
||||
|
||||
Voice(
|
||||
IXAudio2SourceVoice* source_voice
|
||||
);
|
||||
|
||||
~Voice();
|
||||
|
||||
HRESULT Play(
|
||||
const BYTE* wave_data,
|
||||
UINT32 data_size,
|
||||
UINT32 loop_count
|
||||
);
|
||||
|
||||
HRESULT Pause();
|
||||
|
||||
HRESULT Resume();
|
||||
|
||||
HRESULT Stop();
|
||||
|
||||
HRESULT GetVolume(
|
||||
float* volume
|
||||
) const;
|
||||
|
||||
HRESULT SetVolume(
|
||||
float volume
|
||||
);
|
||||
|
||||
HRESULT GetBuffersQueued(
|
||||
UINT32* queued
|
||||
) const;
|
||||
|
||||
void Destroy();
|
||||
|
||||
void SetSourceVoice(
|
||||
IXAudio2SourceVoice* source_voice
|
||||
);
|
||||
|
||||
protected:
|
||||
IXAudio2SourceVoice* source_voice_;
|
||||
};
|
||||
|
||||
namespace devices
|
||||
{
|
||||
// 音频设备
|
||||
class AudioDevice
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(AudioDevice);
|
||||
|
||||
E2D_DISABLE_COPY(AudioDevice);
|
||||
|
||||
public:
|
||||
AudioDevice();
|
||||
|
||||
~AudioDevice();
|
||||
|
||||
void Initialize();
|
||||
|
||||
void Uninitialize();
|
||||
|
||||
// 开启设备
|
||||
void Open();
|
||||
|
||||
// 关闭设备
|
||||
void Close();
|
||||
|
||||
// 创建音源
|
||||
HRESULT CreateVoice(
|
||||
IXAudio2SourceVoice ** voice,
|
||||
Voice* voice,
|
||||
WAVEFORMATEX * wfx
|
||||
);
|
||||
|
||||
void DeleteVoice(
|
||||
Voice* voice
|
||||
);
|
||||
|
||||
void ClearVoiceCache();
|
||||
|
||||
protected:
|
||||
AudioDevice();
|
||||
|
||||
~AudioDevice();
|
||||
|
||||
protected:
|
||||
IXAudio2 * x_audio2_;
|
||||
IXAudio2MasteringVoice* mastering_voice_;
|
||||
std::list<Voice*> voice_cache_;
|
||||
};
|
||||
|
||||
extern AudioDevice instance;
|
||||
E2D_DECLARE_SINGLETON_TYPE(AudioDevice, Audio);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#pragma once
|
||||
#include "BaseTypes.h"
|
||||
#include "Rect.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace easy2d
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@
|
|||
#include <list>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#if VS_VER >= VS_2015
|
||||
|
|
@ -89,9 +90,10 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define E2D_DISABLE_COPY(Class) \
|
||||
Class(const Class &) = delete; \
|
||||
Class & operator= (const Class &) = delete
|
||||
#define E2D_DISABLE_COPY(Class) \
|
||||
private: \
|
||||
Class(const Class &) = delete; \
|
||||
Class & operator= (const Class &) = delete
|
||||
|
||||
|
||||
#if defined( DEBUG ) || defined( _DEBUG )
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ namespace easy2d
|
|||
{
|
||||
namespace
|
||||
{
|
||||
int initialize_count = 0;
|
||||
|
||||
inline void SafeFreeLibrary(HMODULE instance)
|
||||
{
|
||||
if (instance)
|
||||
|
|
@ -38,6 +40,10 @@ namespace easy2d
|
|||
|
||||
void Initialize()
|
||||
{
|
||||
initialize_count++;
|
||||
if (initialize_count > 1)
|
||||
return;
|
||||
|
||||
const auto xaudio2_dll_names =
|
||||
{
|
||||
L"xaudio2_9.dll",
|
||||
|
|
@ -86,8 +92,12 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
void Uninitialize()
|
||||
void Destroy()
|
||||
{
|
||||
initialize_count--;
|
||||
if (initialize_count > 0)
|
||||
return;
|
||||
|
||||
SafeFreeLibrary(XAudio2.instance);
|
||||
SafeFreeLibrary(MediaFoundation.mfplat);
|
||||
SafeFreeLibrary(MediaFoundation.mfreadwrite);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ namespace easy2d
|
|||
{
|
||||
namespace modules
|
||||
{
|
||||
// modules can be initialized multiple times,
|
||||
// but it needs to be destroyed every time
|
||||
void Initialize();
|
||||
|
||||
void Destroy();
|
||||
|
||||
// XAudio2 functions
|
||||
typedef HRESULT(WINAPI *PFN_XAudio2Create)(IXAudio2**, UINT32, XAUDIO2_PROCESSOR);
|
||||
|
||||
|
|
@ -66,13 +72,5 @@ namespace easy2d
|
|||
};
|
||||
|
||||
extern Module_MediaFoundation MediaFoundation;
|
||||
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
|
||||
void Initialize();
|
||||
|
||||
void Uninitialize();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "render.h"
|
||||
#include "time.h"
|
||||
#include "base.h"
|
||||
#include "modules.h"
|
||||
|
||||
#pragma comment(lib, "d2d1.lib")
|
||||
#pragma comment(lib, "dwrite.lib")
|
||||
|
|
@ -28,33 +29,49 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace render
|
||||
namespace devices
|
||||
{
|
||||
GraphicsDevice instance;
|
||||
|
||||
GraphicsDevice::GraphicsDevice()
|
||||
: fps_text_format_(nullptr)
|
||||
, fps_text_layout_(nullptr)
|
||||
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
|
||||
{
|
||||
ZeroMemory(&d2d, sizeof(D2DResources));
|
||||
|
||||
modules::Initialize();
|
||||
}
|
||||
|
||||
GraphicsDevice::~GraphicsDevice()
|
||||
{
|
||||
ClearImageCache();
|
||||
|
||||
SafeRelease(fps_text_format_);
|
||||
SafeRelease(fps_text_layout_);
|
||||
|
||||
SafeRelease(d2d.text_renderer);
|
||||
SafeRelease(d2d.solid_brush);
|
||||
SafeRelease(d2d.render_target);
|
||||
|
||||
SafeRelease(d2d.miter_stroke_style);
|
||||
SafeRelease(d2d.bevel_stroke_style);
|
||||
SafeRelease(d2d.round_stroke_style);
|
||||
|
||||
SafeRelease(d2d.imaging_factory);
|
||||
SafeRelease(d2d.write_factory);
|
||||
SafeRelease(d2d.factory);
|
||||
|
||||
modules::Destroy();
|
||||
}
|
||||
|
||||
void GraphicsDevice::Initialize(HWND hwnd)
|
||||
{
|
||||
if (d2d.Factory)
|
||||
if (d2d.factory)
|
||||
return;
|
||||
|
||||
ThrowIfFailed(
|
||||
D2D1CreateFactory(
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
&d2d.Factory
|
||||
&d2d.factory
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -64,7 +81,7 @@ namespace easy2d
|
|||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IWICImagingFactory,
|
||||
reinterpret_cast<void**>(&d2d.WICImagingFactory)
|
||||
reinterpret_cast<void**>(&d2d.imaging_factory)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -72,7 +89,7 @@ namespace easy2d
|
|||
DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof(IDWriteFactory),
|
||||
reinterpret_cast<IUnknown**>(&d2d.DWriteFactory)
|
||||
reinterpret_cast<IUnknown**>(&d2d.write_factory)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -87,65 +104,50 @@ namespace easy2d
|
|||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
d2d.Factory->CreateStrokeStyle(
|
||||
d2d.factory->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&d2d.MiterStrokeStyle
|
||||
&d2d.miter_stroke_style
|
||||
)
|
||||
);
|
||||
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
|
||||
|
||||
ThrowIfFailed(
|
||||
d2d.Factory->CreateStrokeStyle(
|
||||
d2d.factory->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&d2d.BevelStrokeStyle
|
||||
&d2d.bevel_stroke_style
|
||||
)
|
||||
);
|
||||
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
|
||||
|
||||
ThrowIfFailed(
|
||||
d2d.Factory->CreateStrokeStyle(
|
||||
d2d.factory->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&d2d.RoundStrokeStyle
|
||||
&d2d.round_stroke_style
|
||||
)
|
||||
);
|
||||
|
||||
CreateDeviceResources(hwnd);
|
||||
}
|
||||
|
||||
void GraphicsDevice::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);
|
||||
}
|
||||
|
||||
void GraphicsDevice::BeginDraw(HWND hwnd)
|
||||
{
|
||||
CreateDeviceResources(hwnd);
|
||||
|
||||
d2d.HwndRenderTarget->BeginDraw();
|
||||
d2d.HwndRenderTarget->Clear(clear_color_);
|
||||
d2d.render_target->BeginDraw();
|
||||
d2d.render_target->Clear(clear_color_);
|
||||
}
|
||||
|
||||
void GraphicsDevice::EndDraw()
|
||||
{
|
||||
HRESULT hr = d2d.HwndRenderTarget->EndDraw();
|
||||
HRESULT hr = d2d.render_target->EndDraw();
|
||||
|
||||
if (hr == D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
|
|
@ -155,36 +157,48 @@ namespace easy2d
|
|||
|
||||
SafeRelease(fps_text_format_);
|
||||
SafeRelease(fps_text_layout_);
|
||||
SafeRelease(d2d.TextRenderer);
|
||||
SafeRelease(d2d.SolidColorBrush);
|
||||
SafeRelease(d2d.HwndRenderTarget);
|
||||
SafeRelease(d2d.text_renderer);
|
||||
SafeRelease(d2d.solid_brush);
|
||||
SafeRelease(d2d.render_target);
|
||||
}
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void GraphicsDevice::ClearImageCache()
|
||||
{
|
||||
if (bitmap_cache_.empty())
|
||||
return;
|
||||
|
||||
for (const auto& bitmap : bitmap_cache_)
|
||||
{
|
||||
bitmap.second->Release();
|
||||
}
|
||||
bitmap_cache_.clear();
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::CreateRectGeometry(
|
||||
const math::Matrix& matrix,
|
||||
const Size& size,
|
||||
ID2D1Geometry** geometry
|
||||
) const
|
||||
{
|
||||
if (!d2d.Factory)
|
||||
if (!d2d.factory)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
ID2D1RectangleGeometry * rectangle = nullptr;
|
||||
ID2D1TransformedGeometry * transformed = nullptr;
|
||||
|
||||
hr = d2d.Factory->CreateRectangleGeometry(
|
||||
|
||||
hr = d2d.factory->CreateRectangleGeometry(
|
||||
D2D1::RectF(0, 0, size.width, size.height),
|
||||
&rectangle
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d2d.Factory->CreateTransformedGeometry(
|
||||
hr = d2d.factory->CreateTransformedGeometry(
|
||||
rectangle,
|
||||
matrix,
|
||||
&transformed
|
||||
|
|
@ -202,10 +216,10 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateTextFormat(IDWriteTextFormat ** text_format, const Font & font) const
|
||||
{
|
||||
if (!d2d.DWriteFactory)
|
||||
if (!d2d.write_factory)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return d2d.DWriteFactory->CreateTextFormat(
|
||||
return d2d.write_factory->CreateTextFormat(
|
||||
font.family.c_str(),
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT(font.weight),
|
||||
|
|
@ -219,11 +233,11 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateTextLayout(IDWriteTextLayout ** text_layout, const String & text, IDWriteTextFormat * text_format, float wrap_width) const
|
||||
{
|
||||
if (!d2d.DWriteFactory)
|
||||
if (!d2d.write_factory)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
UINT32 length = static_cast<UINT32>(text.length());
|
||||
return d2d.DWriteFactory->CreateTextLayout(
|
||||
return d2d.write_factory->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format,
|
||||
|
|
@ -235,10 +249,10 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateLayer(ID2D1Layer ** layer)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return d2d.HwndRenderTarget->CreateLayer(layer);
|
||||
return d2d.render_target->CreateLayer(layer);
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::DrawGeometry(
|
||||
|
|
@ -249,15 +263,15 @@ namespace easy2d
|
|||
StrokeStyle stroke
|
||||
)
|
||||
{
|
||||
if (!d2d.SolidColorBrush ||
|
||||
!d2d.HwndRenderTarget)
|
||||
if (!d2d.solid_brush ||
|
||||
!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.SolidColorBrush->SetColor(border_color);
|
||||
d2d.SolidColorBrush->SetOpacity(opacity);
|
||||
d2d.HwndRenderTarget->DrawGeometry(
|
||||
d2d.solid_brush->SetColor(border_color);
|
||||
d2d.solid_brush->SetOpacity(opacity);
|
||||
d2d.render_target->DrawGeometry(
|
||||
geometry,
|
||||
d2d.SolidColorBrush,
|
||||
d2d.solid_brush,
|
||||
stroke_width,
|
||||
GetStrokeStyle(stroke)
|
||||
);
|
||||
|
|
@ -270,13 +284,13 @@ namespace easy2d
|
|||
switch (stroke)
|
||||
{
|
||||
case StrokeStyle::Miter:
|
||||
stroke_style = d2d.MiterStrokeStyle;
|
||||
stroke_style = d2d.miter_stroke_style;
|
||||
break;
|
||||
case StrokeStyle::Bevel:
|
||||
stroke_style = d2d.BevelStrokeStyle;
|
||||
stroke_style = d2d.bevel_stroke_style;
|
||||
break;
|
||||
case StrokeStyle::Round:
|
||||
stroke_style = d2d.RoundStrokeStyle;
|
||||
stroke_style = d2d.round_stroke_style;
|
||||
break;
|
||||
}
|
||||
return stroke_style;
|
||||
|
|
@ -289,10 +303,10 @@ namespace easy2d
|
|||
const Rect & source_rect
|
||||
)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->DrawBitmap(
|
||||
d2d.render_target->DrawBitmap(
|
||||
image->GetBitmap(),
|
||||
dest_rect,
|
||||
opacity,
|
||||
|
|
@ -304,19 +318,19 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::DrawTextLayout(IDWriteTextLayout * text_layout)
|
||||
{
|
||||
if (!d2d.TextRenderer)
|
||||
if (!d2d.text_renderer)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return text_layout->Draw(nullptr, d2d.TextRenderer, 0, 0);
|
||||
return text_layout->Draw(nullptr, d2d.text_renderer, 0, 0);
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::PushClip(const math::Matrix & clip_matrix, const Size & clip_size)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->SetTransform(clip_matrix);
|
||||
d2d.HwndRenderTarget->PushAxisAlignedClip(
|
||||
d2d.render_target->SetTransform(clip_matrix);
|
||||
d2d.render_target->PushAxisAlignedClip(
|
||||
D2D1::RectF(0, 0, clip_size.width, clip_size.height),
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
|
||||
);
|
||||
|
|
@ -325,27 +339,27 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::PopClip()
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->PopAxisAlignedClip();
|
||||
d2d.render_target->PopAxisAlignedClip();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::PushLayer(ID2D1Layer * layer, LayerProperties properties)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget ||
|
||||
!d2d.SolidColorBrush)
|
||||
if (!d2d.render_target ||
|
||||
!d2d.solid_brush)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->PushLayer(
|
||||
d2d.render_target->PushLayer(
|
||||
D2D1::LayerParameters(
|
||||
properties.area,
|
||||
nullptr,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
properties.opacity,
|
||||
d2d.SolidColorBrush,
|
||||
d2d.solid_brush,
|
||||
D2D1_LAYER_OPTIONS_NONE
|
||||
),
|
||||
layer
|
||||
|
|
@ -355,17 +369,17 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::PopLayer()
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->PopLayer();
|
||||
d2d.render_target->PopLayer();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::CreateBitmapFromFile(const String & file_path, ID2D1Bitmap ** bitmap)
|
||||
{
|
||||
if (d2d.WICImagingFactory == nullptr ||
|
||||
d2d.HwndRenderTarget == nullptr)
|
||||
if (d2d.imaging_factory == nullptr ||
|
||||
d2d.render_target == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -375,13 +389,20 @@ namespace easy2d
|
|||
return E_POINTER;
|
||||
}
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
*bitmap = bitmap_cache_[hash_code];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IWICBitmapDecoder* decoder = nullptr;
|
||||
IWICBitmapFrameDecode* source = nullptr;
|
||||
IWICStream* stream = nullptr;
|
||||
IWICFormatConverter* converter = nullptr;
|
||||
|
||||
// 创建解码器
|
||||
HRESULT hr = d2d.WICImagingFactory->CreateDecoderFromFilename(
|
||||
HRESULT hr = d2d.imaging_factory->CreateDecoderFromFilename(
|
||||
file_path.c_str(),
|
||||
nullptr,
|
||||
GENERIC_READ,
|
||||
|
|
@ -398,7 +419,7 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// 创建图片格式转换器
|
||||
hr = d2d.WICImagingFactory->CreateFormatConverter(&converter);
|
||||
hr = d2d.imaging_factory->CreateFormatConverter(&converter);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -417,13 +438,18 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// 从 WIC 位图创建一个 Direct2D 位图
|
||||
hr = d2d.HwndRenderTarget->CreateBitmapFromWicBitmap(
|
||||
hr = d2d.render_target->CreateBitmapFromWicBitmap(
|
||||
converter,
|
||||
nullptr,
|
||||
bitmap
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, *bitmap));
|
||||
}
|
||||
|
||||
// 释放相关资源
|
||||
SafeRelease(decoder);
|
||||
SafeRelease(source);
|
||||
|
|
@ -435,8 +461,8 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateBitmapFromResource(Resource & res, ID2D1Bitmap ** bitmap)
|
||||
{
|
||||
if (d2d.WICImagingFactory == nullptr ||
|
||||
d2d.HwndRenderTarget == nullptr)
|
||||
if (d2d.imaging_factory == nullptr ||
|
||||
d2d.render_target == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -446,6 +472,13 @@ namespace easy2d
|
|||
return E_POINTER;
|
||||
}
|
||||
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
*bitmap = bitmap_cache_[hash_code];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||
|
|
@ -453,14 +486,14 @@ namespace easy2d
|
|||
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);
|
||||
hr = d2d.imaging_factory->CreateStream(&stream);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -475,7 +508,7 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// 创建流的解码器
|
||||
hr = d2d.WICImagingFactory->CreateDecoderFromStream(
|
||||
hr = d2d.imaging_factory->CreateDecoderFromStream(
|
||||
stream,
|
||||
nullptr,
|
||||
WICDecodeMetadataCacheOnLoad,
|
||||
|
|
@ -492,7 +525,7 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// 创建图片格式转换器
|
||||
hr = d2d.WICImagingFactory->CreateFormatConverter(&converter);
|
||||
hr = d2d.imaging_factory->CreateFormatConverter(&converter);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -511,13 +544,18 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// 从 WIC 位图创建一个 Direct2D 位图
|
||||
hr = d2d.HwndRenderTarget->CreateBitmapFromWicBitmap(
|
||||
hr = d2d.render_target->CreateBitmapFromWicBitmap(
|
||||
converter,
|
||||
nullptr,
|
||||
bitmap
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, *bitmap));
|
||||
}
|
||||
|
||||
// 释放相关资源
|
||||
SafeRelease(decoder);
|
||||
SafeRelease(source);
|
||||
|
|
@ -529,28 +567,28 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->Resize(D2D1::SizeU(width, height));
|
||||
d2d.render_target->Resize(D2D1::SizeU(width, height));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::SetTransform(const math::Matrix & matrix)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.HwndRenderTarget->SetTransform(matrix);
|
||||
d2d.render_target->SetTransform(matrix);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::SetBrushOpacity(float opacity)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.SolidColorBrush->SetOpacity(opacity);
|
||||
d2d.solid_brush->SetOpacity(opacity);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -562,10 +600,10 @@ namespace easy2d
|
|||
StrokeStyle outline_stroke
|
||||
)
|
||||
{
|
||||
if (!d2d.TextRenderer)
|
||||
if (!d2d.text_renderer)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
d2d.TextRenderer->SetTextStyle(
|
||||
d2d.text_renderer->SetTextStyle(
|
||||
color,
|
||||
has_outline,
|
||||
outline_color,
|
||||
|
|
@ -590,7 +628,7 @@ namespace easy2d
|
|||
if (!fps_text_format_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
d2d.DWriteFactory->CreateTextFormat(
|
||||
d2d.write_factory->CreateTextFormat(
|
||||
L"",
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
|
|
@ -621,7 +659,7 @@ namespace easy2d
|
|||
SafeRelease(fps_text_layout_);
|
||||
|
||||
ThrowIfFailed(
|
||||
d2d.DWriteFactory->CreateTextLayout(
|
||||
d2d.write_factory->CreateTextLayout(
|
||||
fps_text,
|
||||
static_cast<UINT32>(len),
|
||||
fps_text_format_,
|
||||
|
|
@ -634,9 +672,9 @@ namespace easy2d
|
|||
|
||||
if (fps_text_layout_)
|
||||
{
|
||||
d2d.HwndRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
d2d.SolidColorBrush->SetOpacity(1.0f);
|
||||
d2d.TextRenderer->SetTextStyle(
|
||||
d2d.render_target->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
d2d.solid_brush->SetOpacity(1.0f);
|
||||
d2d.text_renderer->SetTextStyle(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
TRUE,
|
||||
D2D1::ColorF(D2D1::ColorF::Black, 0.4f),
|
||||
|
|
@ -644,13 +682,13 @@ namespace easy2d
|
|||
D2D1_LINE_JOIN_ROUND
|
||||
);
|
||||
|
||||
fps_text_layout_->Draw(nullptr, d2d.TextRenderer, 10, 0);
|
||||
fps_text_layout_->Draw(nullptr, d2d.text_renderer, 10, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsDevice::CreateDeviceResources(HWND hwnd)
|
||||
{
|
||||
if (!d2d.HwndRenderTarget)
|
||||
if (!d2d.render_target)
|
||||
{
|
||||
RECT rc;
|
||||
::GetClientRect(hwnd, &rc);
|
||||
|
|
@ -663,35 +701,35 @@ namespace easy2d
|
|||
// 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建
|
||||
// 创建一个 Direct2D 渲染目标
|
||||
ThrowIfFailed(
|
||||
d2d.Factory->CreateHwndRenderTarget(
|
||||
d2d.factory->CreateHwndRenderTarget(
|
||||
D2D1::RenderTargetProperties(),
|
||||
D2D1::HwndRenderTargetProperties(
|
||||
hwnd,
|
||||
size,
|
||||
D2D1_PRESENT_OPTIONS_NONE),
|
||||
&d2d.HwndRenderTarget
|
||||
&d2d.render_target
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!d2d.SolidColorBrush)
|
||||
if (!d2d.solid_brush)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
d2d.HwndRenderTarget->CreateSolidColorBrush(
|
||||
d2d.render_target->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&d2d.SolidColorBrush
|
||||
&d2d.solid_brush
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!d2d.TextRenderer)
|
||||
if (!d2d.text_renderer)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
ITextRenderer::Create(
|
||||
&d2d.TextRenderer,
|
||||
d2d.Factory,
|
||||
d2d.HwndRenderTarget,
|
||||
d2d.SolidColorBrush
|
||||
&d2d.text_renderer,
|
||||
d2d.factory,
|
||||
d2d.render_target,
|
||||
d2d.solid_brush
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#pragma once
|
||||
#include "base.h"
|
||||
#include "Singleton.hpp"
|
||||
#include "Font.h"
|
||||
#include "Resource.h"
|
||||
#include "Image.h"
|
||||
|
|
@ -28,38 +29,31 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace render
|
||||
namespace devices
|
||||
{
|
||||
typedef struct
|
||||
struct D2DResources
|
||||
{
|
||||
ID2D1Factory* Factory;
|
||||
IWICImagingFactory* WICImagingFactory;
|
||||
IDWriteFactory* DWriteFactory;
|
||||
ITextRenderer* TextRenderer;
|
||||
ID2D1SolidColorBrush* SolidColorBrush;
|
||||
ID2D1HwndRenderTarget* HwndRenderTarget;
|
||||
ID2D1StrokeStyle* MiterStrokeStyle;
|
||||
ID2D1StrokeStyle* BevelStrokeStyle;
|
||||
ID2D1StrokeStyle* RoundStrokeStyle;
|
||||
} D2DResources;
|
||||
ID2D1Factory* factory;
|
||||
IWICImagingFactory* imaging_factory;
|
||||
IDWriteFactory* write_factory;
|
||||
ITextRenderer* text_renderer;
|
||||
ID2D1SolidColorBrush* solid_brush;
|
||||
ID2D1HwndRenderTarget* render_target;
|
||||
ID2D1StrokeStyle* miter_stroke_style;
|
||||
ID2D1StrokeStyle* bevel_stroke_style;
|
||||
ID2D1StrokeStyle* round_stroke_style;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rect area;
|
||||
float opacity;
|
||||
} LayerProperties;
|
||||
|
||||
class GraphicsDevice
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(GraphicsDevice);
|
||||
|
||||
E2D_DISABLE_COPY(GraphicsDevice);
|
||||
|
||||
public:
|
||||
GraphicsDevice();
|
||||
|
||||
~GraphicsDevice();
|
||||
|
||||
void Initialize(HWND hwnd);
|
||||
|
||||
void Uninitialize();
|
||||
|
||||
// ¿ªÊ¼äÖȾ
|
||||
void BeginDraw(HWND hwnd);
|
||||
|
||||
|
|
@ -166,13 +160,21 @@ namespace easy2d
|
|||
UINT32 height
|
||||
);
|
||||
|
||||
void ClearImageCache();
|
||||
|
||||
protected:
|
||||
D2D1_COLOR_F clear_color_;
|
||||
IDWriteTextFormat* fps_text_format_;
|
||||
IDWriteTextLayout* fps_text_layout_;
|
||||
D2DResources d2d;
|
||||
GraphicsDevice();
|
||||
|
||||
~GraphicsDevice();
|
||||
|
||||
protected:
|
||||
D2DResources d2d;
|
||||
D2D1_COLOR_F clear_color_;
|
||||
IDWriteTextFormat* fps_text_format_;
|
||||
IDWriteTextLayout* fps_text_layout_;
|
||||
std::map<size_t, ID2D1Bitmap*> bitmap_cache_;
|
||||
};
|
||||
|
||||
extern GraphicsDevice instance;
|
||||
E2D_DECLARE_SINGLETON_TYPE(GraphicsDevice, Graphics);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,332 +33,342 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace window
|
||||
namespace
|
||||
{
|
||||
namespace
|
||||
void GetContentScale(float* scale_x, float* scale_y);
|
||||
|
||||
Rect LocateWindow(int width, int height, float scale_x, float scale_y);
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param);
|
||||
}
|
||||
|
||||
WindowInfo::WindowInfo()
|
||||
: handle(nullptr)
|
||||
, scale_x(1.f)
|
||||
, scale_y(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
WindowInfo::~WindowInfo()
|
||||
{
|
||||
if (handle)
|
||||
::DestroyWindow(handle);
|
||||
}
|
||||
|
||||
void WindowInfo::Initialize(String title, int width, int height, LPCWSTR icon, bool debug)
|
||||
{
|
||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||
WNDCLASSEX wcex = { 0 };
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.lpszClassName = REGISTER_CLASS;
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = sizeof(LONG_PTR);
|
||||
wcex.hInstance = hinstance;
|
||||
wcex.hbrBackground = nullptr;
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
|
||||
|
||||
if (icon)
|
||||
{
|
||||
void GetContentScale(float* xscale, float* yscale);
|
||||
|
||||
Rect LocateWindow(int width, int height);
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param);
|
||||
}
|
||||
|
||||
WindowInfo instance;
|
||||
|
||||
WindowInfo::WindowInfo()
|
||||
: handle(nullptr)
|
||||
, xscale(1.f)
|
||||
, yscale(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
void WindowInfo::Initialize(const Property& property)
|
||||
{
|
||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||
WNDCLASSEX wcex = { 0 };
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.lpszClassName = REGISTER_CLASS;
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = sizeof(LONG_PTR);
|
||||
wcex.hInstance = hinstance;
|
||||
wcex.hbrBackground = nullptr;
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
|
||||
|
||||
if (property.icon)
|
||||
{
|
||||
wcex.hIcon = (HICON)::LoadImage(
|
||||
hinstance,
|
||||
property.icon,
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
||||
);
|
||||
}
|
||||
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
GetContentScale(&xscale, &yscale);
|
||||
|
||||
// 计算窗口大小
|
||||
Rect client_rect = LocateWindow(property.width, property.height);
|
||||
|
||||
// 创建窗口
|
||||
handle = ::CreateWindowEx(
|
||||
NULL,
|
||||
REGISTER_CLASS,
|
||||
property.title.c_str(),
|
||||
WINDOW_STYLE,
|
||||
static_cast<int>(client_rect.origin.x),
|
||||
static_cast<int>(client_rect.origin.y),
|
||||
static_cast<int>(client_rect.size.width),
|
||||
static_cast<int>(client_rect.size.height),
|
||||
nullptr,
|
||||
nullptr,
|
||||
wcex.hIcon = (HICON)::LoadImage(
|
||||
hinstance,
|
||||
this
|
||||
icon,
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
||||
);
|
||||
|
||||
if (handle == nullptr)
|
||||
{
|
||||
::UnregisterClass(REGISTER_CLASS, hinstance);
|
||||
throw std::runtime_error("Create window failed");
|
||||
}
|
||||
|
||||
// 禁用输入法
|
||||
::ImmAssociateContext(handle, nullptr);
|
||||
}
|
||||
|
||||
void WindowInfo::Destroy()
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
GetContentScale(&scale_x, &scale_y);
|
||||
|
||||
// 计算窗口大小
|
||||
Rect client_rect = LocateWindow(width, height, scale_x, scale_y);
|
||||
|
||||
// 创建窗口
|
||||
handle = ::CreateWindowEx(
|
||||
NULL,
|
||||
REGISTER_CLASS,
|
||||
title.c_str(),
|
||||
WINDOW_STYLE,
|
||||
static_cast<int>(client_rect.origin.x),
|
||||
static_cast<int>(client_rect.origin.y),
|
||||
static_cast<int>(client_rect.size.width),
|
||||
static_cast<int>(client_rect.size.height),
|
||||
nullptr,
|
||||
nullptr,
|
||||
hinstance,
|
||||
this
|
||||
);
|
||||
|
||||
if (handle == nullptr)
|
||||
{
|
||||
if (handle)
|
||||
::DestroyWindow(handle);
|
||||
::UnregisterClass(REGISTER_CLASS, hinstance);
|
||||
throw std::runtime_error("Create window failed");
|
||||
}
|
||||
|
||||
String WindowInfo::GetTitle() const
|
||||
// 禁用输入法
|
||||
::ImmAssociateContext(handle, nullptr);
|
||||
}
|
||||
|
||||
String WindowInfo::GetTitle() const
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
wchar_t title[256];
|
||||
GetWindowTextW(handle, title, 256);
|
||||
return title;
|
||||
}
|
||||
return String();
|
||||
wchar_t title[256];
|
||||
GetWindowTextW(handle, title, 256);
|
||||
return title;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
void WindowInfo::SetTitle(const String& title)
|
||||
void WindowInfo::SetTitle(const String& title)
|
||||
{
|
||||
if (handle)
|
||||
::SetWindowText(handle, title.c_str());
|
||||
}
|
||||
|
||||
Size WindowInfo::GetSize() const
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
if (handle)
|
||||
::SetWindowText(handle, title.c_str());
|
||||
RECT rect;
|
||||
GetClientRect(handle, &rect);
|
||||
return Size(
|
||||
static_cast<float>(rect.right - rect.left),
|
||||
static_cast<float>(rect.bottom - rect.top)
|
||||
);
|
||||
}
|
||||
return Size();
|
||||
}
|
||||
|
||||
Size WindowInfo::GetSize() const
|
||||
float WindowInfo::GetWidth() const
|
||||
{
|
||||
return GetSize().width;
|
||||
}
|
||||
|
||||
float WindowInfo::GetHeight() const
|
||||
{
|
||||
return GetSize().height;
|
||||
}
|
||||
|
||||
void WindowInfo::SetSize(int width, int height)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(handle, &rect);
|
||||
return Size(
|
||||
static_cast<float>(rect.right - rect.left),
|
||||
static_cast<float>(rect.bottom - rect.top)
|
||||
);
|
||||
}
|
||||
return Size();
|
||||
}
|
||||
|
||||
float WindowInfo::GetWidth() const
|
||||
{
|
||||
return GetSize().width;
|
||||
}
|
||||
|
||||
float WindowInfo::GetHeight() const
|
||||
{
|
||||
return GetSize().height;
|
||||
}
|
||||
|
||||
void WindowInfo::SetSize(int width, int height)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
Rect rect = LocateWindow(width, height);
|
||||
::MoveWindow(
|
||||
handle,
|
||||
static_cast<int>(rect.origin.x),
|
||||
static_cast<int>(rect.origin.y),
|
||||
static_cast<int>(rect.size.width),
|
||||
static_cast<int>(rect.size.height),
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowInfo::SetIcon(LPCWSTR icon_resource)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||
HICON icon = (HICON)::LoadImage(
|
||||
hinstance,
|
||||
icon_resource,
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
||||
);
|
||||
|
||||
::SendMessage(handle, WM_SETICON, ICON_BIG, (LPARAM)icon);
|
||||
::SendMessage(handle, WM_SETICON, ICON_SMALL, (LPARAM)icon);
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void GetContentScale(float* xscale, float* yscale)
|
||||
{
|
||||
const float DEFAULT_SCREEN_DPI = 96.f;
|
||||
const HDC dc = GetDC(NULL);
|
||||
float xdpi = static_cast<float>(GetDeviceCaps(dc, LOGPIXELSX));
|
||||
float ydpi = static_cast<float>(GetDeviceCaps(dc, LOGPIXELSY));
|
||||
ReleaseDC(NULL, dc);
|
||||
|
||||
if (xscale)
|
||||
*xscale = xdpi / DEFAULT_SCREEN_DPI;
|
||||
if (yscale)
|
||||
*yscale = ydpi / DEFAULT_SCREEN_DPI;
|
||||
}
|
||||
|
||||
Rect LocateWindow(int width, int height)
|
||||
{
|
||||
int max_width = ::GetSystemMetrics(SM_CXSCREEN);
|
||||
int max_height = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
RECT rect =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
static_cast<LONG>(math::Ceil(width * instance.xscale)),
|
||||
static_cast<LONG>(math::Ceil(height * instance.yscale))
|
||||
};
|
||||
|
||||
// 计算合适的窗口大小
|
||||
::AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, NULL);
|
||||
width = static_cast<int>(rect.right - rect.left);
|
||||
height = static_cast<int>(rect.bottom - rect.top);
|
||||
|
||||
// 当输入的窗口大小比分辨率大时,给出警告
|
||||
E2D_WARNING_IF(max_width < width || max_height < height, "The window Is larger than screen!");
|
||||
width = std::min(width, max_width);
|
||||
height = std::min(height, max_height);
|
||||
|
||||
return Rect(
|
||||
static_cast<float>((max_width - width) / 2),
|
||||
static_cast<float>((max_height - height) / 2),
|
||||
static_cast<float>(width),
|
||||
static_cast<float>(height)
|
||||
);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
||||
{
|
||||
LRESULT result = 0;
|
||||
bool was_handled = false;
|
||||
|
||||
Game * game = reinterpret_cast<Game*>(
|
||||
static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA))
|
||||
);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
|
||||
// 处理鼠标消息
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
if (game->IsTransitioning())
|
||||
break;
|
||||
|
||||
auto curr_scene = game->GetCurrentScene();
|
||||
if (curr_scene)
|
||||
{
|
||||
curr_scene->Dispatch(MouseEvent(msg, w_param, l_param));
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 处理按键消息
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
if (game->IsTransitioning())
|
||||
break;
|
||||
|
||||
auto curr_scene = game->GetCurrentScene();
|
||||
if (curr_scene)
|
||||
{
|
||||
curr_scene->Dispatch(KeyEvent(msg, w_param, l_param));
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 处理窗口大小变化消息
|
||||
case WM_SIZE:
|
||||
{
|
||||
UINT width = LOWORD(l_param);
|
||||
UINT height = HIWORD(l_param);
|
||||
|
||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
|
||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||
render::instance.Resize(width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
// 处理分辨率变化消息
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
// 重绘客户区
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 重绘窗口
|
||||
case WM_PAINT:
|
||||
{
|
||||
game->DrawScene();
|
||||
::ValidateRect(hwnd, nullptr);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 窗口关闭消息
|
||||
case WM_CLOSE:
|
||||
{
|
||||
if (game->OnClose())
|
||||
{
|
||||
game->Quit();
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 窗口销毁消息
|
||||
case WM_DESTROY:
|
||||
{
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
result = 1;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!was_handled)
|
||||
{
|
||||
result = ::DefWindowProc(hwnd, msg, w_param, l_param);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Rect rect = LocateWindow(width, height, scale_x, scale_y);
|
||||
::MoveWindow(
|
||||
handle,
|
||||
static_cast<int>(rect.origin.x),
|
||||
static_cast<int>(rect.origin.y),
|
||||
static_cast<int>(rect.size.width),
|
||||
static_cast<int>(rect.size.height),
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowInfo::SetIcon(LPCWSTR icon_resource)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||
HICON icon = (HICON)::LoadImage(
|
||||
hinstance,
|
||||
icon_resource,
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
||||
);
|
||||
|
||||
::SendMessage(handle, WM_SETICON, ICON_BIG, (LPARAM)icon);
|
||||
::SendMessage(handle, WM_SETICON, ICON_SMALL, (LPARAM)icon);
|
||||
}
|
||||
}
|
||||
|
||||
HWND WindowInfo::GetHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
float WindowInfo::GetContentScaleX() const
|
||||
{
|
||||
return scale_x;
|
||||
}
|
||||
|
||||
float WindowInfo::GetContentScaleY() const
|
||||
{
|
||||
return scale_y;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void GetContentScale(float* scale_x, float* scale_y)
|
||||
{
|
||||
const float DEFAULT_SCREEN_DPI = 96.f;
|
||||
const HDC dc = GetDC(NULL);
|
||||
float xdpi = static_cast<float>(GetDeviceCaps(dc, LOGPIXELSX));
|
||||
float ydpi = static_cast<float>(GetDeviceCaps(dc, LOGPIXELSY));
|
||||
ReleaseDC(NULL, dc);
|
||||
|
||||
if (scale_x)
|
||||
*scale_x = xdpi / DEFAULT_SCREEN_DPI;
|
||||
if (scale_y)
|
||||
*scale_y = ydpi / DEFAULT_SCREEN_DPI;
|
||||
}
|
||||
|
||||
Rect LocateWindow(int width, int height, float scale_x, float scale_y)
|
||||
{
|
||||
int max_width = ::GetSystemMetrics(SM_CXSCREEN);
|
||||
int max_height = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
RECT rect =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
static_cast<LONG>(math::Ceil(width * scale_x)),
|
||||
static_cast<LONG>(math::Ceil(height * scale_y))
|
||||
};
|
||||
|
||||
// 计算合适的窗口大小
|
||||
::AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, NULL);
|
||||
width = static_cast<int>(rect.right - rect.left);
|
||||
height = static_cast<int>(rect.bottom - rect.top);
|
||||
|
||||
// 当输入的窗口大小比分辨率大时,给出警告
|
||||
E2D_WARNING_IF(max_width < width || max_height < height, "The window Is larger than screen!");
|
||||
width = std::min(width, max_width);
|
||||
height = std::min(height, max_height);
|
||||
|
||||
return Rect(
|
||||
static_cast<float>((max_width - width) / 2),
|
||||
static_cast<float>((max_height - height) / 2),
|
||||
static_cast<float>(width),
|
||||
static_cast<float>(height)
|
||||
);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
||||
{
|
||||
LRESULT result = 0;
|
||||
bool was_handled = false;
|
||||
|
||||
Game * game = reinterpret_cast<Game*>(
|
||||
static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA))
|
||||
);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
|
||||
// 处理鼠标消息
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
if (game->IsTransitioning())
|
||||
break;
|
||||
|
||||
auto curr_scene = game->GetCurrentScene();
|
||||
if (curr_scene)
|
||||
{
|
||||
curr_scene->Dispatch(MouseEvent(msg, w_param, l_param));
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 处理按键消息
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
if (game->IsTransitioning())
|
||||
break;
|
||||
|
||||
auto curr_scene = game->GetCurrentScene();
|
||||
if (curr_scene)
|
||||
{
|
||||
curr_scene->Dispatch(KeyEvent(msg, w_param, l_param));
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 处理窗口大小变化消息
|
||||
case WM_SIZE:
|
||||
{
|
||||
UINT width = LOWORD(l_param);
|
||||
UINT height = HIWORD(l_param);
|
||||
|
||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
|
||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||
devices::Graphics::Instance().Resize(width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
// 处理分辨率变化消息
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
// 重绘客户区
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 重绘窗口
|
||||
case WM_PAINT:
|
||||
{
|
||||
game->DrawScene();
|
||||
::ValidateRect(hwnd, nullptr);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 窗口关闭消息
|
||||
case WM_CLOSE:
|
||||
{
|
||||
if (game->OnClose())
|
||||
{
|
||||
game->Quit();
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 窗口销毁消息
|
||||
case WM_DESTROY:
|
||||
{
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
result = 1;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!was_handled)
|
||||
{
|
||||
result = ::DefWindowProc(hwnd, msg, w_param, l_param);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,64 +20,64 @@
|
|||
|
||||
#pragma once
|
||||
#include "base.h"
|
||||
#include "Singleton.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace window
|
||||
|
||||
|
||||
class WindowInfo
|
||||
{
|
||||
typedef struct Property
|
||||
{
|
||||
String title; /* 标题 */
|
||||
int width; /* 宽度 */
|
||||
int height; /* 高度 */
|
||||
LPCWSTR icon; /* 图标 */
|
||||
E2D_DECLARE_SINGLETON(WindowInfo);
|
||||
|
||||
Property()
|
||||
: title(L"Easy2D Game")
|
||||
, width(640)
|
||||
, height(480)
|
||||
, icon(nullptr)
|
||||
{}
|
||||
} Property;
|
||||
E2D_DISABLE_COPY(WindowInfo);
|
||||
|
||||
class WindowInfo
|
||||
{
|
||||
public:
|
||||
HWND handle;
|
||||
float xscale;
|
||||
float yscale;
|
||||
public:
|
||||
void Initialize(
|
||||
String title,
|
||||
int width,
|
||||
int height,
|
||||
LPCWSTR icon,
|
||||
bool debug
|
||||
);
|
||||
|
||||
public:
|
||||
WindowInfo();
|
||||
// 获取标题
|
||||
String GetTitle() const;
|
||||
|
||||
void Initialize(
|
||||
const Property& property
|
||||
);
|
||||
// 设置标题
|
||||
void SetTitle(const String& title);
|
||||
|
||||
void Destroy();
|
||||
// 获取窗口大小
|
||||
Size GetSize() const;
|
||||
|
||||
// 获取标题
|
||||
String GetTitle() const;
|
||||
// 获取窗口宽度
|
||||
float GetWidth() const;
|
||||
|
||||
// 设置标题
|
||||
void SetTitle(const String& title);
|
||||
// 获取窗口高度
|
||||
float GetHeight() const;
|
||||
|
||||
// 获取窗口大小
|
||||
Size GetSize() const;
|
||||
// 重设窗口大小
|
||||
void SetSize(int width, int height);
|
||||
|
||||
// 获取窗口宽度
|
||||
float GetWidth() const;
|
||||
// 设置窗口图标
|
||||
void SetIcon(LPCWSTR icon_resource);
|
||||
|
||||
// 获取窗口高度
|
||||
float GetHeight() const;
|
||||
HWND GetHandle() const;
|
||||
|
||||
// 重设窗口大小
|
||||
void SetSize(int width, int height);
|
||||
float GetContentScaleX() const;
|
||||
|
||||
// 设置窗口图标
|
||||
void SetIcon(LPCWSTR icon_resource);
|
||||
};
|
||||
float GetContentScaleY() const;
|
||||
|
||||
extern WindowInfo instance;
|
||||
}
|
||||
protected:
|
||||
WindowInfo();
|
||||
|
||||
~WindowInfo();
|
||||
|
||||
private:
|
||||
HWND handle;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
};
|
||||
|
||||
E2D_DECLARE_SINGLETON_TYPE(WindowInfo, Window);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "base/CallFunc.h"
|
||||
#include "base/Canvas.h"
|
||||
#include "base/Transition.h"
|
||||
#include "base/Music.h"
|
||||
|
||||
#include "base/KeyEvent.h"
|
||||
#include "base/MouseEvent.h"
|
||||
|
|
@ -85,9 +86,8 @@
|
|||
#include "utils/Path.h"
|
||||
#include "utils/Data.h"
|
||||
#include "utils/File.h"
|
||||
#include "utils/Transcoder.h"
|
||||
#include "utils/Music.h"
|
||||
#include "utils/Player.h"
|
||||
#include "utils/Transcoder.h"
|
||||
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ namespace easy2d
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Scale(float xscale, float yscale, const Vector2& center)
|
||||
inline Matrix& Scale(float scale_x, float scale_y, const Vector2& center)
|
||||
{
|
||||
*this = *this * Matrix::Scaling(xscale, yscale, center);
|
||||
*this = *this * Matrix::Scaling(scale_x, scale_y, center);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,16 @@ namespace easy2d
|
|||
, y(other.y)
|
||||
{}
|
||||
|
||||
inline float Length() const
|
||||
{
|
||||
return math::Sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
inline float Distance(const Vector2& v)
|
||||
{
|
||||
return Vector2(x - v.x, y - v.y).Length();
|
||||
}
|
||||
|
||||
inline Vector2 operator + (const Vector2 & other) const
|
||||
{
|
||||
return Vector2(x + other.x, y + other.y);
|
||||
|
|
@ -80,13 +90,6 @@ namespace easy2d
|
|||
return (x == other.x) && (y == other.y);
|
||||
}
|
||||
|
||||
inline float Length() const { return math::Sqrt(x * x + y * y); }
|
||||
|
||||
inline float Distance(const Vector2& v)
|
||||
{
|
||||
return Vector2(x - v.x, y - v.y).Length();
|
||||
}
|
||||
|
||||
inline operator D2D1_POINT_2F () const
|
||||
{
|
||||
return D2D1_POINT_2F{ x, y };
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ namespace easy2d
|
|||
if (IsVisible() &&
|
||||
!enabled_ &&
|
||||
normal_ &&
|
||||
normal_->ContainsPoint(input::instance.GetMousePos()))
|
||||
normal_->ContainsPoint(devices::Input::Instance().GetMousePos()))
|
||||
{
|
||||
HCURSOR hcursor = ::LoadCursor(nullptr, IDC_NO);
|
||||
if (hcursor)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ namespace easy2d
|
|||
class Button
|
||||
: public Node
|
||||
{
|
||||
E2D_DISABLE_COPY(Button);
|
||||
|
||||
typedef std::function<void()> Callback;
|
||||
|
||||
public:
|
||||
|
|
@ -101,8 +103,6 @@ namespace easy2d
|
|||
) override;
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Button);
|
||||
|
||||
// °´Å¥×´Ì¬Ã¶¾Ù
|
||||
enum class Status { Normal, Mouseover, Selected };
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ namespace easy2d
|
|||
class Menu
|
||||
: public Node
|
||||
{
|
||||
E2D_DISABLE_COPY(Menu);
|
||||
|
||||
public:
|
||||
Menu();
|
||||
|
||||
|
|
@ -61,9 +63,6 @@ namespace easy2d
|
|||
// 获取所有按钮
|
||||
const std::vector<Button*>& GetAllButtons() const;
|
||||
|
||||
private:
|
||||
E2D_DISABLE_COPY(Menu);
|
||||
|
||||
private:
|
||||
bool enabled_;
|
||||
std::vector<Button*> buttons_;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace easy2d
|
|||
{
|
||||
// 设置数据的保存路径
|
||||
String local_app_data_path = Path::GetLocalAppDataPath();
|
||||
String title = window::instance.GetTitle();
|
||||
String title = Window::Instance().GetTitle();
|
||||
String folder_name = std::to_wstring(std::hash<String>{}(title));
|
||||
|
||||
if (!local_app_data_path.empty())
|
||||
|
|
@ -90,7 +90,7 @@ namespace easy2d
|
|||
{
|
||||
// 设置临时文件保存路径
|
||||
wchar_t path[_MAX_PATH];
|
||||
String title = window::instance.GetTitle();
|
||||
String title = Window::Instance().GetTitle();
|
||||
String folder_name = std::to_wstring(std::hash<String>{}(title));
|
||||
|
||||
if (0 != ::GetTempPath(_MAX_PATH, path))
|
||||
|
|
|
|||
|
|
@ -19,15 +19,10 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "Player.h"
|
||||
#include "Music.h"
|
||||
#include "../base/Music.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::map<size_t, Music*> musics_;
|
||||
}
|
||||
|
||||
Player::Player()
|
||||
: volume_(1.f)
|
||||
{
|
||||
|
|
@ -35,6 +30,7 @@ namespace easy2d
|
|||
|
||||
Player::~Player()
|
||||
{
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
bool Player::Load(const String & file_path)
|
||||
|
|
@ -51,7 +47,7 @@ namespace easy2d
|
|||
music->SetVolume(volume_);
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
musics_.insert(std::make_pair(hash_code, music));
|
||||
musics_cache_.insert(std::make_pair(hash_code, music));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -69,7 +65,7 @@ namespace easy2d
|
|||
|
||||
if (Load(file_path))
|
||||
{
|
||||
auto music = musics_[std::hash<String>{}(file_path)];
|
||||
auto music = musics_cache_[std::hash<String>{}(file_path)];
|
||||
if (music->Play(loop_count))
|
||||
{
|
||||
return true;
|
||||
|
|
@ -84,8 +80,8 @@ namespace easy2d
|
|||
return;
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
musics_[hash_code]->Pause();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Pause();
|
||||
}
|
||||
|
||||
void Player::Resume(const String & file_path)
|
||||
|
|
@ -94,8 +90,8 @@ namespace easy2d
|
|||
return;
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
musics_[hash_code]->Resume();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Resume();
|
||||
}
|
||||
|
||||
void Player::Stop(const String & file_path)
|
||||
|
|
@ -104,8 +100,8 @@ namespace easy2d
|
|||
return;
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
musics_[hash_code]->Stop();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Stop();
|
||||
}
|
||||
|
||||
bool Player::IsPlaying(const String & file_path)
|
||||
|
|
@ -114,15 +110,15 @@ namespace easy2d
|
|||
return false;
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
return musics_[hash_code]->IsPlaying();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
return musics_cache_[hash_code]->IsPlaying();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::Load(Resource& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
return true;
|
||||
|
||||
Music * music = new (std::nothrow) Music();
|
||||
|
|
@ -132,7 +128,7 @@ namespace easy2d
|
|||
if (music->Load(res))
|
||||
{
|
||||
music->SetVolume(volume_);
|
||||
musics_.insert(std::make_pair(hash_code, music));
|
||||
musics_cache_.insert(std::make_pair(hash_code, music));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -148,7 +144,7 @@ namespace easy2d
|
|||
if (Load(res))
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
auto music = musics_[hash_code];
|
||||
auto music = musics_cache_[hash_code];
|
||||
if (music->Play(loop_count))
|
||||
{
|
||||
return true;
|
||||
|
|
@ -160,29 +156,29 @@ namespace easy2d
|
|||
void Player::Pause(Resource& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
musics_[hash_code]->Pause();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Pause();
|
||||
}
|
||||
|
||||
void Player::Resume(Resource& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
musics_[hash_code]->Resume();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Resume();
|
||||
}
|
||||
|
||||
void Player::Stop(Resource& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
musics_[hash_code]->Stop();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
musics_cache_[hash_code]->Stop();
|
||||
}
|
||||
|
||||
bool Player::IsPlaying(Resource& res)
|
||||
{
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (musics_.end() != musics_.find(hash_code))
|
||||
return musics_[hash_code]->IsPlaying();
|
||||
if (musics_cache_.end() != musics_cache_.find(hash_code))
|
||||
return musics_cache_[hash_code]->IsPlaying();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +190,7 @@ namespace easy2d
|
|||
void Player::SetVolume(float volume)
|
||||
{
|
||||
volume_ = std::min(std::max(volume, -224.f), 224.f);
|
||||
for (const auto& pair : musics_)
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->SetVolume(volume_);
|
||||
}
|
||||
|
|
@ -202,7 +198,7 @@ namespace easy2d
|
|||
|
||||
void Player::PauseAll()
|
||||
{
|
||||
for (const auto& pair : musics_)
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Pause();
|
||||
}
|
||||
|
|
@ -210,7 +206,7 @@ namespace easy2d
|
|||
|
||||
void Player::ResumeAll()
|
||||
{
|
||||
for (const auto& pair : musics_)
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Resume();
|
||||
}
|
||||
|
|
@ -218,7 +214,7 @@ namespace easy2d
|
|||
|
||||
void Player::StopAll()
|
||||
{
|
||||
for (const auto& pair : musics_)
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Stop();
|
||||
}
|
||||
|
|
@ -226,13 +222,13 @@ namespace easy2d
|
|||
|
||||
void Player::ClearCache()
|
||||
{
|
||||
if (musics_.empty())
|
||||
if (musics_cache_.empty())
|
||||
return;
|
||||
|
||||
for (const auto& pair : musics_)
|
||||
for (const auto& pair : musics_cache_)
|
||||
{
|
||||
pair.second->Release();
|
||||
}
|
||||
musics_.clear();
|
||||
musics_cache_.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -24,9 +24,13 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
class Music;
|
||||
|
||||
// 稜있꺄렴포
|
||||
class Player
|
||||
{
|
||||
E2D_DISABLE_COPY(Player);
|
||||
|
||||
public:
|
||||
Player();
|
||||
|
||||
|
|
@ -112,12 +116,10 @@ namespace easy2d
|
|||
void StopAll();
|
||||
|
||||
// 헌뇜뻠닸
|
||||
static void ClearCache();
|
||||
|
||||
protected:
|
||||
E2D_DISABLE_COPY(Player);
|
||||
void ClearCache();
|
||||
|
||||
protected:
|
||||
float volume_;
|
||||
std::map<size_t, Music*> musics_cache_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace easy2d
|
|||
return wave_format_;
|
||||
}
|
||||
|
||||
bool Transcoder::LoadMediaFile(LPCWSTR file_path, BYTE** wave_data, UINT32* wave_data_size)
|
||||
HRESULT Transcoder::LoadMediaFile(LPCWSTR file_path, BYTE** wave_data, UINT32* wave_data_size)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
|
|
@ -64,10 +64,10 @@ namespace easy2d
|
|||
|
||||
SafeRelease(reader);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool Transcoder::LoadMediaResource(Resource& res, BYTE** wave_data, UINT32* wave_data_size)
|
||||
HRESULT Transcoder::LoadMediaResource(Resource& res, BYTE** wave_data, UINT32* wave_data_size)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ namespace easy2d
|
|||
if (stream == nullptr)
|
||||
{
|
||||
logs::Trace(L"SHCreateMemStream");
|
||||
return false;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -112,7 +112,7 @@ namespace easy2d
|
|||
SafeRelease(byte_stream);
|
||||
SafeRelease(reader);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Transcoder::ReadSource(IMFSourceReader* reader, BYTE** wave_data, UINT32* wave_data_size)
|
||||
|
|
|
|||
|
|
@ -38,13 +38,13 @@ namespace easy2d
|
|||
|
||||
WAVEFORMATEX* GetWaveFormatEx() const;
|
||||
|
||||
bool LoadMediaFile(
|
||||
HRESULT LoadMediaFile(
|
||||
LPCWSTR file_path,
|
||||
BYTE** wave_data,
|
||||
UINT32* wave_data_size
|
||||
);
|
||||
|
||||
bool LoadMediaResource(
|
||||
HRESULT LoadMediaResource(
|
||||
Resource& res,
|
||||
BYTE** wave_data,
|
||||
UINT32* wave_data_size
|
||||
|
|
|
|||
|
|
@ -38,12 +38,14 @@
|
|||
<ClInclude Include="..\..\core\base\macros.h" />
|
||||
<ClInclude Include="..\..\core\base\modules.h" />
|
||||
<ClInclude Include="..\..\core\base\MouseEvent.h" />
|
||||
<ClInclude Include="..\..\core\base\Music.h" />
|
||||
<ClInclude Include="..\..\core\base\Node.h" />
|
||||
<ClInclude Include="..\..\core\base\Rect.hpp" />
|
||||
<ClInclude Include="..\..\core\base\RefCounter.h" />
|
||||
<ClInclude Include="..\..\core\base\render.h" />
|
||||
<ClInclude Include="..\..\core\base\Resource.h" />
|
||||
<ClInclude Include="..\..\core\base\Scene.h" />
|
||||
<ClInclude Include="..\..\core\base\Singleton.hpp" />
|
||||
<ClInclude Include="..\..\core\base\Size.h" />
|
||||
<ClInclude Include="..\..\core\base\Sprite.h" />
|
||||
<ClInclude Include="..\..\core\base\Task.h" />
|
||||
|
|
@ -62,7 +64,6 @@
|
|||
<ClInclude Include="..\..\core\ui\Menu.h" />
|
||||
<ClInclude Include="..\..\core\utils\Data.h" />
|
||||
<ClInclude Include="..\..\core\utils\File.h" />
|
||||
<ClInclude Include="..\..\core\utils\Music.h" />
|
||||
<ClInclude Include="..\..\core\utils\Path.h" />
|
||||
<ClInclude Include="..\..\core\utils\Player.h" />
|
||||
<ClInclude Include="..\..\core\utils\Transcoder.h" />
|
||||
|
|
@ -83,6 +84,7 @@
|
|||
<ClCompile Include="..\..\core\base\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\base\modules.cpp" />
|
||||
<ClCompile Include="..\..\core\base\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\base\Music.cpp" />
|
||||
<ClCompile Include="..\..\core\base\Node.cpp" />
|
||||
<ClCompile Include="..\..\core\base\RefCounter.cpp" />
|
||||
<ClCompile Include="..\..\core\base\render.cpp" />
|
||||
|
|
@ -102,7 +104,6 @@
|
|||
<ClCompile Include="..\..\core\ui\Menu.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Data.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\File.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Music.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Path.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Player.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Transcoder.cpp" />
|
||||
|
|
|
|||
|
|
@ -122,9 +122,6 @@
|
|||
<ClInclude Include="..\..\core\utils\File.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\utils\Music.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\utils\Path.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -140,6 +137,12 @@
|
|||
<ClInclude Include="..\..\core\ui\Menu.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\Music.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\Singleton.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="base">
|
||||
|
|
@ -252,9 +255,6 @@
|
|||
<ClCompile Include="..\..\core\utils\File.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\utils\Music.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\utils\Path.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -270,5 +270,8 @@
|
|||
<ClCompile Include="..\..\core\ui\Menu.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\base\Music.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -38,12 +38,14 @@
|
|||
<ClInclude Include="..\..\core\base\macros.h" />
|
||||
<ClInclude Include="..\..\core\base\modules.h" />
|
||||
<ClInclude Include="..\..\core\base\MouseEvent.h" />
|
||||
<ClInclude Include="..\..\core\base\Music.h" />
|
||||
<ClInclude Include="..\..\core\base\Node.h" />
|
||||
<ClInclude Include="..\..\core\base\Rect.hpp" />
|
||||
<ClInclude Include="..\..\core\base\RefCounter.h" />
|
||||
<ClInclude Include="..\..\core\base\render.h" />
|
||||
<ClInclude Include="..\..\core\base\Resource.h" />
|
||||
<ClInclude Include="..\..\core\base\Scene.h" />
|
||||
<ClInclude Include="..\..\core\base\Singleton.hpp" />
|
||||
<ClInclude Include="..\..\core\base\Size.h" />
|
||||
<ClInclude Include="..\..\core\base\Sprite.h" />
|
||||
<ClInclude Include="..\..\core\base\Task.h" />
|
||||
|
|
@ -62,7 +64,6 @@
|
|||
<ClInclude Include="..\..\core\ui\Menu.h" />
|
||||
<ClInclude Include="..\..\core\utils\Data.h" />
|
||||
<ClInclude Include="..\..\core\utils\File.h" />
|
||||
<ClInclude Include="..\..\core\utils\Music.h" />
|
||||
<ClInclude Include="..\..\core\utils\Path.h" />
|
||||
<ClInclude Include="..\..\core\utils\Player.h" />
|
||||
<ClInclude Include="..\..\core\utils\Transcoder.h" />
|
||||
|
|
@ -83,6 +84,7 @@
|
|||
<ClCompile Include="..\..\core\base\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\base\modules.cpp" />
|
||||
<ClCompile Include="..\..\core\base\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\base\Music.cpp" />
|
||||
<ClCompile Include="..\..\core\base\Node.cpp" />
|
||||
<ClCompile Include="..\..\core\base\RefCounter.cpp" />
|
||||
<ClCompile Include="..\..\core\base\render.cpp" />
|
||||
|
|
@ -102,7 +104,6 @@
|
|||
<ClCompile Include="..\..\core\ui\Menu.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Data.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\File.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Music.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Path.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Player.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Transcoder.cpp" />
|
||||
|
|
|
|||
|
|
@ -122,9 +122,6 @@
|
|||
<ClInclude Include="..\..\core\utils\File.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\utils\Music.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\utils\Path.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -140,6 +137,12 @@
|
|||
<ClInclude Include="..\..\core\ui\Menu.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\Music.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\Singleton.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="base">
|
||||
|
|
@ -252,9 +255,6 @@
|
|||
<ClCompile Include="..\..\core\utils\File.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\utils\Music.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\utils\Path.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -270,5 +270,8 @@
|
|||
<ClCompile Include="..\..\core\ui\Menu.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\base\Music.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -38,12 +38,14 @@
|
|||
<ClInclude Include="..\..\core\base\macros.h" />
|
||||
<ClInclude Include="..\..\core\base\modules.h" />
|
||||
<ClInclude Include="..\..\core\base\MouseEvent.h" />
|
||||
<ClInclude Include="..\..\core\base\Music.h" />
|
||||
<ClInclude Include="..\..\core\base\Node.h" />
|
||||
<ClInclude Include="..\..\core\base\Rect.hpp" />
|
||||
<ClInclude Include="..\..\core\base\RefCounter.h" />
|
||||
<ClInclude Include="..\..\core\base\render.h" />
|
||||
<ClInclude Include="..\..\core\base\Resource.h" />
|
||||
<ClInclude Include="..\..\core\base\Scene.h" />
|
||||
<ClInclude Include="..\..\core\base\Singleton.hpp" />
|
||||
<ClInclude Include="..\..\core\base\Size.h" />
|
||||
<ClInclude Include="..\..\core\base\Sprite.h" />
|
||||
<ClInclude Include="..\..\core\base\Task.h" />
|
||||
|
|
@ -62,7 +64,6 @@
|
|||
<ClInclude Include="..\..\core\ui\Menu.h" />
|
||||
<ClInclude Include="..\..\core\utils\Data.h" />
|
||||
<ClInclude Include="..\..\core\utils\File.h" />
|
||||
<ClInclude Include="..\..\core\utils\Music.h" />
|
||||
<ClInclude Include="..\..\core\utils\Path.h" />
|
||||
<ClInclude Include="..\..\core\utils\Player.h" />
|
||||
<ClInclude Include="..\..\core\utils\Transcoder.h" />
|
||||
|
|
@ -83,6 +84,7 @@
|
|||
<ClCompile Include="..\..\core\base\KeyEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\base\modules.cpp" />
|
||||
<ClCompile Include="..\..\core\base\MouseEvent.cpp" />
|
||||
<ClCompile Include="..\..\core\base\Music.cpp" />
|
||||
<ClCompile Include="..\..\core\base\Node.cpp" />
|
||||
<ClCompile Include="..\..\core\base\RefCounter.cpp" />
|
||||
<ClCompile Include="..\..\core\base\render.cpp" />
|
||||
|
|
@ -102,7 +104,6 @@
|
|||
<ClCompile Include="..\..\core\ui\Menu.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Data.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\File.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Music.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Path.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Player.cpp" />
|
||||
<ClCompile Include="..\..\core\utils\Transcoder.cpp" />
|
||||
|
|
|
|||
|
|
@ -122,9 +122,6 @@
|
|||
<ClInclude Include="..\..\core\utils\File.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\utils\Music.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\utils\Path.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -140,6 +137,12 @@
|
|||
<ClInclude Include="..\..\core\ui\Menu.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\Music.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\core\base\Singleton.hpp">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="base">
|
||||
|
|
@ -252,9 +255,6 @@
|
|||
<ClCompile Include="..\..\core\utils\File.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\utils\Music.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\utils\Path.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -270,5 +270,8 @@
|
|||
<ClCompile Include="..\..\core\ui\Menu.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\base\Music.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Reference in New Issue