parent
b9ac2c3934
commit
bf25bd1d41
|
|
@ -96,7 +96,7 @@ namespace easy2d
|
|||
cache_expired_ = true;
|
||||
}
|
||||
|
||||
void Canvas::OnDraw()
|
||||
void Canvas::OnRender()
|
||||
{
|
||||
if (cache_expired_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ namespace easy2d
|
|||
// 导出为图片
|
||||
spImage ExportToImage() const;
|
||||
|
||||
virtual void OnDraw() override;
|
||||
virtual void OnRender() override;
|
||||
|
||||
protected:
|
||||
cpBitmap const& GetBitmap() const;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace easy2d
|
|||
texts_.clear();
|
||||
}
|
||||
|
||||
void DebugerNode::OnUpdate(Duration const & dt)
|
||||
void DebugerNode::Update(Duration const & dt)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace easy2d
|
|||
|
||||
void ClearDebugText();
|
||||
|
||||
void OnUpdate(Duration const& dt) override;
|
||||
void Update(Duration const& dt) override;
|
||||
|
||||
protected:
|
||||
spText debug_text_;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
namespace easy2d
|
||||
{
|
||||
FactoryImpl::FactoryImpl()
|
||||
: initialized_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -35,91 +34,90 @@ namespace easy2d
|
|||
E2D_LOG("Destroying device independent resources");
|
||||
}
|
||||
|
||||
void FactoryImpl::Init(bool debug)
|
||||
HRESULT FactoryImpl::Init(bool debug)
|
||||
{
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
E2D_LOG("Creating device independent resources");
|
||||
|
||||
D2D1_FACTORY_OPTIONS fact_options;
|
||||
fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE;
|
||||
ThrowIfFailed(
|
||||
modules::DirectX().D2D1CreateFactory(
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof(ID2D1Factory),
|
||||
&fact_options,
|
||||
reinterpret_cast<void**>(&factory)
|
||||
)
|
||||
HRESULT hr = modules::DirectX().D2D1CreateFactory(
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof(ID2D1Factory),
|
||||
&fact_options,
|
||||
reinterpret_cast<void**>(&factory_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CoCreateInstance(
|
||||
CLSID_WICImagingFactory,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IWICImagingFactory),
|
||||
reinterpret_cast<void**>(&imaging_factory)
|
||||
)
|
||||
);
|
||||
reinterpret_cast<void**>(&imaging_factory_)
|
||||
);
|
||||
}
|
||||
|
||||
ThrowIfFailed(
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
modules::DirectX().DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof(IDWriteFactory),
|
||||
reinterpret_cast<IUnknown**>(&write_factory)
|
||||
)
|
||||
);
|
||||
reinterpret_cast<IUnknown**>(&write_factory_)
|
||||
);
|
||||
}
|
||||
|
||||
auto stroke_style = D2D1::StrokeStyleProperties(
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_LINE_JOIN_MITER,
|
||||
2.0f,
|
||||
D2D1_DASH_STYLE_SOLID,
|
||||
0.0f
|
||||
);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto stroke_style = D2D1::StrokeStyleProperties(
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_LINE_JOIN_MITER,
|
||||
2.0f,
|
||||
D2D1_DASH_STYLE_SOLID,
|
||||
0.0f
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
factory->CreateStrokeStyle(
|
||||
hr = factory_->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&miter_stroke_style
|
||||
)
|
||||
);
|
||||
&miter_stroke_style_
|
||||
);
|
||||
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
|
||||
ThrowIfFailed(
|
||||
factory->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&bevel_stroke_style
|
||||
)
|
||||
);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
|
||||
hr = factory_->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&bevel_stroke_style_
|
||||
);
|
||||
}
|
||||
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
|
||||
ThrowIfFailed(
|
||||
factory->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&round_stroke_style
|
||||
)
|
||||
);
|
||||
|
||||
initialized_ = true;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
|
||||
hr = factory_->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&round_stroke_style_
|
||||
);
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT FactoryImpl::CreateHwndRenderTarget(cpHwndRenderTarget & hwnd_render_target, D2D1_RENDER_TARGET_PROPERTIES const & properties, D2D1_HWND_RENDER_TARGET_PROPERTIES const & hwnd_rt_properties) const
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpHwndRenderTarget hwnd_render_target_tmp;
|
||||
HRESULT hr = factory->CreateHwndRenderTarget(
|
||||
HRESULT hr = factory_->CreateHwndRenderTarget(
|
||||
properties,
|
||||
hwnd_rt_properties,
|
||||
&hwnd_render_target_tmp
|
||||
|
|
@ -136,13 +134,13 @@ namespace easy2d
|
|||
cpSolidColorBrush const& brush
|
||||
)
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpTextRenderer text_renderer_tmp;
|
||||
HRESULT hr = ITextRenderer::Create(
|
||||
&text_renderer_tmp,
|
||||
factory.Get(),
|
||||
factory_.Get(),
|
||||
render_target.Get(),
|
||||
brush.Get()
|
||||
);
|
||||
|
|
@ -154,7 +152,7 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreateBitmapFromFile(cpBitmap & bitmap, cpRenderTarget const & rt, String const & file_path)
|
||||
{
|
||||
if (imaging_factory == nullptr)
|
||||
if (imaging_factory_ == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -167,7 +165,7 @@ namespace easy2d
|
|||
SmartPointer<IWICFormatConverter> converter;
|
||||
SmartPointer<ID2D1Bitmap> bitmap_tmp;
|
||||
|
||||
HRESULT hr = imaging_factory->CreateDecoderFromFilename(
|
||||
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(
|
||||
file_path.c_str(),
|
||||
nullptr,
|
||||
GENERIC_READ,
|
||||
|
|
@ -182,7 +180,7 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = imaging_factory->CreateFormatConverter(&converter);
|
||||
hr = imaging_factory_->CreateFormatConverter(&converter);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -215,7 +213,7 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreateBitmapFromResource(cpBitmap & bitmap, cpRenderTarget const & rt, Resource const & res)
|
||||
{
|
||||
if (imaging_factory == nullptr)
|
||||
if (imaging_factory_ == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -234,7 +232,7 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = imaging_factory->CreateStream(&stream);
|
||||
hr = imaging_factory_->CreateStream(&stream);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -247,7 +245,7 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = imaging_factory->CreateDecoderFromStream(
|
||||
hr = imaging_factory_->CreateDecoderFromStream(
|
||||
stream.Get(),
|
||||
nullptr,
|
||||
WICDecodeMetadataCacheOnLoad,
|
||||
|
|
@ -262,7 +260,7 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = imaging_factory->CreateFormatConverter(&converter);
|
||||
hr = imaging_factory_->CreateFormatConverter(&converter);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -297,11 +295,11 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreateRectangleGeometry(cpRectangleGeometry & geo, Rect const& rect) const
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpRectangleGeometry rectangle;
|
||||
HRESULT hr = factory->CreateRectangleGeometry(
|
||||
HRESULT hr = factory_->CreateRectangleGeometry(
|
||||
rect,
|
||||
&rectangle
|
||||
);
|
||||
|
|
@ -313,11 +311,11 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreateRoundedRectangleGeometry(cpRoundedRectangleGeometry & geo, Rect const & rect, float radius_x, float radius_y) const
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpRoundedRectangleGeometry rounded_rect;
|
||||
HRESULT hr = factory->CreateRoundedRectangleGeometry(
|
||||
HRESULT hr = factory_->CreateRoundedRectangleGeometry(
|
||||
D2D1::RoundedRect(
|
||||
rect,
|
||||
radius_x,
|
||||
|
|
@ -333,11 +331,11 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreateEllipseGeometry(cpEllipseGeometry & geo, Point const & center, float radius_x, float radius_y) const
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpEllipseGeometry ellipse;
|
||||
HRESULT hr = factory->CreateEllipseGeometry(
|
||||
HRESULT hr = factory_->CreateEllipseGeometry(
|
||||
D2D1::Ellipse(
|
||||
center,
|
||||
radius_x,
|
||||
|
|
@ -357,11 +355,11 @@ namespace easy2d
|
|||
cpGeometry const& geo
|
||||
) const
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpTransformedGeometry transformed_tmp;
|
||||
HRESULT hr = factory->CreateTransformedGeometry(
|
||||
HRESULT hr = factory_->CreateTransformedGeometry(
|
||||
geo.Get(),
|
||||
ConvertToD2DMatrix(matrix),
|
||||
&transformed_tmp
|
||||
|
|
@ -376,19 +374,19 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreatePathGeometry(cpPathGeometry & geometry) const
|
||||
{
|
||||
if (!factory)
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return factory->CreatePathGeometry(&geometry);
|
||||
return factory_->CreatePathGeometry(&geometry);
|
||||
}
|
||||
|
||||
HRESULT FactoryImpl::CreateTextFormat(cpTextFormat & text_format, Font const & font, TextStyle const & text_style) const
|
||||
{
|
||||
if (!write_factory)
|
||||
if (!write_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
cpTextFormat text_format_tmp;
|
||||
HRESULT hr = write_factory->CreateTextFormat(
|
||||
HRESULT hr = write_factory_->CreateTextFormat(
|
||||
font.family.c_str(),
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT(font.weight),
|
||||
|
|
@ -422,7 +420,7 @@ namespace easy2d
|
|||
|
||||
HRESULT FactoryImpl::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const
|
||||
{
|
||||
if (!write_factory)
|
||||
if (!write_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
text_layout = nullptr;
|
||||
|
|
@ -433,7 +431,7 @@ namespace easy2d
|
|||
|
||||
if (text_style.wrap)
|
||||
{
|
||||
hr = write_factory->CreateTextLayout(
|
||||
hr = write_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.Get(),
|
||||
|
|
@ -444,7 +442,7 @@ namespace easy2d
|
|||
}
|
||||
else
|
||||
{
|
||||
hr = write_factory->CreateTextLayout(
|
||||
hr = write_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.Get(),
|
||||
|
|
@ -459,7 +457,7 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
text_layout_tmp = nullptr;
|
||||
hr = write_factory->CreateTextLayout(
|
||||
hr = write_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.Get(),
|
||||
|
|
@ -503,16 +501,16 @@ namespace easy2d
|
|||
switch (stroke)
|
||||
{
|
||||
case StrokeStyle::Miter:
|
||||
return miter_stroke_style;
|
||||
return miter_stroke_style_;
|
||||
break;
|
||||
case StrokeStyle::Bevel:
|
||||
return bevel_stroke_style;
|
||||
return bevel_stroke_style_;
|
||||
break;
|
||||
case StrokeStyle::Round:
|
||||
return round_stroke_style;
|
||||
return round_stroke_style_;
|
||||
break;
|
||||
}
|
||||
return miter_stroke_style;
|
||||
return miter_stroke_style_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace easy2d
|
|||
E2D_DECLARE_SINGLETON(FactoryImpl);
|
||||
|
||||
public:
|
||||
void Init(bool debug);
|
||||
HRESULT Init(bool debug);
|
||||
|
||||
HRESULT CreateHwndRenderTarget(
|
||||
cpHwndRenderTarget& hwnd_render_target,
|
||||
|
|
@ -114,13 +114,12 @@ namespace easy2d
|
|||
~FactoryImpl();
|
||||
|
||||
protected:
|
||||
bool initialized_;
|
||||
cpFactory factory;
|
||||
cpImagingFactory imaging_factory;
|
||||
cpWriteFactory write_factory;
|
||||
cpStrokeStyle miter_stroke_style;
|
||||
cpStrokeStyle bevel_stroke_style;
|
||||
cpStrokeStyle round_stroke_style;
|
||||
cpFactory factory_;
|
||||
cpImagingFactory imaging_factory_;
|
||||
cpWriteFactory write_factory_;
|
||||
cpStrokeStyle miter_stroke_style_;
|
||||
cpStrokeStyle bevel_stroke_style_;
|
||||
cpStrokeStyle round_stroke_style_;
|
||||
};
|
||||
|
||||
E2D_DECLARE_SINGLETON_TYPE(FactoryImpl, Factory);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#include "Game.h"
|
||||
#include "logs.h"
|
||||
#include "input.h"
|
||||
#include "audio.h"
|
||||
#include "modules.h"
|
||||
#include "Factory.h"
|
||||
#include "Scene.h"
|
||||
|
|
@ -35,13 +33,17 @@
|
|||
namespace easy2d
|
||||
{
|
||||
Game::Game()
|
||||
: curr_scene_(nullptr)
|
||||
: initialized_(false)
|
||||
, window_inactived_(false)
|
||||
, curr_scene_(nullptr)
|
||||
, next_scene_(nullptr)
|
||||
, transition_(nullptr)
|
||||
, window_(nullptr)
|
||||
, graphics_(nullptr)
|
||||
, input_(nullptr)
|
||||
, audio_(nullptr)
|
||||
, debug_enabled_(false)
|
||||
, initialized_(false)
|
||||
, hwnd_(nullptr)
|
||||
, window_inactived_(false)
|
||||
, time_scale_(1.f)
|
||||
{
|
||||
::CoInitialize(nullptr);
|
||||
}
|
||||
|
|
@ -64,72 +66,90 @@ namespace easy2d
|
|||
|
||||
debug_enabled_ = options.debug;
|
||||
|
||||
Window::Instance()->Init(
|
||||
options.title,
|
||||
options.width,
|
||||
options.height,
|
||||
options.icon,
|
||||
Game::WndProc,
|
||||
debug_enabled_
|
||||
window_ = Window::Instance();
|
||||
graphics_ = devices::Graphics::Instance();
|
||||
input_ = devices::Input::Instance();
|
||||
audio_ = devices::Audio::Instance();
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance()->Init(debug_enabled_)
|
||||
);
|
||||
|
||||
const auto window = Window::Instance();
|
||||
hwnd_ = window->GetHandle();
|
||||
ThrowIfFailed(
|
||||
window_->Init(
|
||||
options.title,
|
||||
options.width,
|
||||
options.height,
|
||||
options.icon,
|
||||
Game::WndProc,
|
||||
debug_enabled_
|
||||
)
|
||||
);
|
||||
|
||||
::SetWindowLongW(hwnd_, GWLP_USERDATA, PtrToUlong(this));
|
||||
HWND hwnd = window_->GetHandle();
|
||||
|
||||
Factory::Instance()->Init(debug_enabled_);
|
||||
devices::Graphics::Instance()->Init(hwnd_, options.graphics_options, debug_enabled_);
|
||||
devices::Input::Instance()->Init(hwnd_, window->GetContentScaleX(), window->GetContentScaleY(), debug_enabled_);
|
||||
devices::Audio::Instance()->Init(debug_enabled_);
|
||||
ThrowIfFailed(
|
||||
graphics_->Init(
|
||||
hwnd,
|
||||
options.vsync,
|
||||
debug_enabled_
|
||||
)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
input_->Init(
|
||||
hwnd,
|
||||
window_->GetContentScaleX(),
|
||||
window_->GetContentScaleY(),
|
||||
debug_enabled_
|
||||
)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
audio_->Init(debug_enabled_)
|
||||
);
|
||||
|
||||
// disable imm
|
||||
::ImmAssociateContext(hwnd_, nullptr);
|
||||
::ImmAssociateContext(hwnd, nullptr);
|
||||
|
||||
// show console if debug mode enabled
|
||||
HWND console = ::GetConsoleWindow();
|
||||
if (debug_enabled_)
|
||||
if (debug_enabled_ && !console)
|
||||
{
|
||||
if (console == nullptr)
|
||||
if (::AllocConsole())
|
||||
{
|
||||
if (::AllocConsole())
|
||||
{
|
||||
console = ::GetConsoleWindow();
|
||||
FILE * stdoutStream, *stdinStream, *stderrStream;
|
||||
freopen_s(&stdoutStream, "conout$", "w+t", stdout);
|
||||
freopen_s(&stdinStream, "conin$", "r+t", stdin);
|
||||
freopen_s(&stderrStream, "conout$", "w+t", stderr);
|
||||
}
|
||||
console = ::GetConsoleWindow();
|
||||
FILE * stdoutStream, *stdinStream, *stderrStream;
|
||||
freopen_s(&stdoutStream, "conout$", "w+t", stdout);
|
||||
freopen_s(&stdinStream, "conin$", "r+t", stdin);
|
||||
freopen_s(&stderrStream, "conout$", "w+t", stderr);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!debug_enabled_ && console)
|
||||
{
|
||||
if (console)
|
||||
{
|
||||
::ShowWindow(console, SW_HIDE);
|
||||
}
|
||||
::ShowWindow(console, SW_HIDE);
|
||||
}
|
||||
|
||||
// disable the close button of console
|
||||
if (console)
|
||||
{
|
||||
// disable the close button of console
|
||||
HMENU hmenu = ::GetSystemMenu(console, FALSE);
|
||||
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
||||
}
|
||||
|
||||
// use Game instance in message loop
|
||||
::SetWindowLongW(hwnd, GWLP_USERDATA, PtrToUlong(this));
|
||||
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
void Game::Run()
|
||||
{
|
||||
if (next_scene_)
|
||||
{
|
||||
next_scene_->OnEnter();
|
||||
curr_scene_ = next_scene_;
|
||||
next_scene_ = nullptr;
|
||||
}
|
||||
if (!initialized_)
|
||||
return;
|
||||
|
||||
::ShowWindow(hwnd_, SW_SHOWNORMAL);
|
||||
::UpdateWindow(hwnd_);
|
||||
::ShowWindow(window_->GetHandle(), SW_SHOWNORMAL);
|
||||
::UpdateWindow(window_->GetHandle());
|
||||
|
||||
MSG msg = {};
|
||||
while (::GetMessageW(&msg, nullptr, 0, 0))
|
||||
|
|
@ -141,7 +161,8 @@ namespace easy2d
|
|||
|
||||
void Game::Quit()
|
||||
{
|
||||
::DestroyWindow(hwnd_);
|
||||
if (window_)
|
||||
::DestroyWindow(window_->GetHandle());
|
||||
}
|
||||
|
||||
bool Game::EnterScene(spScene const & scene)
|
||||
|
|
@ -182,15 +203,20 @@ namespace easy2d
|
|||
return curr_scene_;
|
||||
}
|
||||
|
||||
void Game::SetTimeScale(float scale)
|
||||
{
|
||||
time_scale_ = scale;
|
||||
}
|
||||
|
||||
void Game::Update()
|
||||
{
|
||||
static auto last = time::Now();
|
||||
|
||||
const auto now = time::Now();
|
||||
const auto dt = now - last;
|
||||
const auto dt = (now - last) * time_scale_;
|
||||
last = now;
|
||||
|
||||
devices::Input::Instance()->Update();
|
||||
input_->Update();
|
||||
|
||||
if (curr_scene_)
|
||||
curr_scene_->Update(dt);
|
||||
|
|
@ -228,7 +254,10 @@ namespace easy2d
|
|||
void Game::Render()
|
||||
{
|
||||
auto graphics = devices::Graphics::Instance();
|
||||
graphics->BeginDraw(hwnd_);
|
||||
|
||||
ThrowIfFailed(
|
||||
graphics->BeginDraw(window_->GetHandle())
|
||||
);
|
||||
|
||||
if (transition_)
|
||||
{
|
||||
|
|
@ -236,7 +265,7 @@ namespace easy2d
|
|||
}
|
||||
else if (curr_scene_)
|
||||
{
|
||||
curr_scene_->Visit();
|
||||
curr_scene_->Render();
|
||||
}
|
||||
|
||||
if (debug_enabled_)
|
||||
|
|
@ -254,13 +283,15 @@ namespace easy2d
|
|||
next_scene_->DrawBorder();
|
||||
}
|
||||
|
||||
Debuger::Instance()->Visit();
|
||||
Debuger::Instance()->Render();
|
||||
}
|
||||
|
||||
graphics->EndDraw();
|
||||
ThrowIfFailed(
|
||||
graphics->EndDraw()
|
||||
);
|
||||
|
||||
if (!window_inactived_)
|
||||
::InvalidateRect(hwnd_, NULL, FALSE);
|
||||
::InvalidateRect(window_->GetHandle(), NULL, FALSE);
|
||||
}
|
||||
|
||||
void Game::Dispatch(MouseEvent const & e)
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
|
||||
#pragma once
|
||||
#include "base.hpp"
|
||||
#include "window.h"
|
||||
#include "time.h"
|
||||
#include "window.h"
|
||||
#include "render.h"
|
||||
#include "input.h"
|
||||
#include "audio.h"
|
||||
#include "KeyEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
|
||||
|
|
@ -34,17 +36,16 @@ namespace easy2d
|
|||
int width; // 宽度
|
||||
int height; // 高度
|
||||
LPCWSTR icon; // 图标
|
||||
bool vsync; // ´¹Ö±Í¬²½
|
||||
bool debug; // 调试模式
|
||||
|
||||
GraphicsOptions graphics_options; // ͼÐÎäÖȾѡÏî
|
||||
|
||||
Options()
|
||||
: title(L"Easy2D Game")
|
||||
, width(640)
|
||||
, height(480)
|
||||
, icon(nullptr)
|
||||
, vsync(true)
|
||||
, debug(false)
|
||||
, graphics_options()
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -93,6 +94,9 @@ namespace easy2d
|
|||
// 获取当前场景
|
||||
spScene const& GetCurrentScene();
|
||||
|
||||
// ÉèÖñäËÙ
|
||||
void SetTimeScale(float scale);
|
||||
|
||||
private:
|
||||
void Render();
|
||||
|
||||
|
|
@ -112,9 +116,14 @@ namespace easy2d
|
|||
bool initialized_;
|
||||
bool debug_enabled_;
|
||||
bool window_inactived_;
|
||||
HWND hwnd_;
|
||||
float time_scale_;
|
||||
spScene curr_scene_;
|
||||
spScene next_scene_;
|
||||
spTransition transition_;
|
||||
|
||||
WindowImpl* window_;
|
||||
devices::GraphicsDevice* graphics_;
|
||||
devices::InputDevice* input_;
|
||||
devices::AudioDevice* audio_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace easy2d
|
|||
outline_join_ = outline_join;
|
||||
}
|
||||
|
||||
void GeometryNode::OnDraw()
|
||||
void GeometryNode::OnRender()
|
||||
{
|
||||
if (geometry_ && geometry_->geo_)
|
||||
{
|
||||
|
|
@ -87,12 +87,4 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
void GeometryNode::DrawBorder()
|
||||
{
|
||||
if (visible_)
|
||||
{
|
||||
DrawChildrenBorder();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,10 +77,7 @@ namespace easy2d
|
|||
// ťńČĄĎßĚőĎཝŃůĘ˝
|
||||
StrokeStyle SetOutlineJoinStyle() const { return outline_join_; }
|
||||
|
||||
virtual void OnDraw() override;
|
||||
|
||||
protected:
|
||||
virtual void DrawBorder() override;
|
||||
virtual void OnRender() override;
|
||||
|
||||
protected:
|
||||
Color fill_color_;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ namespace easy2d
|
|||
namespace devices
|
||||
{
|
||||
InputDevice::InputDevice()
|
||||
: initialized_(false)
|
||||
, hwnd_(nullptr)
|
||||
: hwnd_(nullptr)
|
||||
, scale_x_(1.f)
|
||||
, scale_y_(1.f)
|
||||
{
|
||||
|
|
@ -41,18 +40,15 @@ namespace easy2d
|
|||
E2D_LOG("Destroying input device");
|
||||
}
|
||||
|
||||
void InputDevice::Init(HWND hwnd, float scale_x, float scale_y, bool debug)
|
||||
HRESULT InputDevice::Init(HWND hwnd, float scale_x, float scale_y, bool debug)
|
||||
{
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
E2D_LOG("Initing input device");
|
||||
|
||||
hwnd_ = hwnd;
|
||||
scale_x_ = scale_x;
|
||||
scale_y_ = scale_y;
|
||||
|
||||
initialized_ = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void InputDevice::Update()
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace easy2d
|
|||
E2D_DECLARE_SINGLETON(InputDevice);
|
||||
|
||||
public:
|
||||
void Init(HWND hwnd, float scale_x, float scale_y, bool debug);
|
||||
HRESULT Init(HWND hwnd, float scale_x, float scale_y, bool debug);
|
||||
|
||||
// 检测键盘某按键是否正被按下
|
||||
bool IsDown(
|
||||
|
|
@ -71,7 +71,6 @@ namespace easy2d
|
|||
~InputDevice();
|
||||
|
||||
protected:
|
||||
bool initialized_;
|
||||
HWND hwnd_;
|
||||
float scale_x_;
|
||||
float scale_y_;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace easy2d
|
|||
{
|
||||
float default_pivot_x = 0.f;
|
||||
float default_pivot_y = 0.f;
|
||||
bool border_enabled = false;
|
||||
}
|
||||
|
||||
void Node::SetDefaultPivot(float pivot_x, float pivot_y)
|
||||
|
|
@ -40,12 +41,23 @@ namespace easy2d
|
|||
default_pivot_y = pivot_y;
|
||||
}
|
||||
|
||||
void easy2d::Node::EnableBorder()
|
||||
{
|
||||
border_enabled = true;
|
||||
}
|
||||
|
||||
void easy2d::Node::DisableBorder()
|
||||
{
|
||||
border_enabled = false;
|
||||
}
|
||||
|
||||
Node::Node()
|
||||
: visible_(true)
|
||||
: inited_(false)
|
||||
, visible_(true)
|
||||
, dirty_sort_(false)
|
||||
, parent_(nullptr)
|
||||
, hash_name_(0)
|
||||
, dirty_sort_(false)
|
||||
, order_(0)
|
||||
, z_order_(0)
|
||||
, opacity_(1.f)
|
||||
, display_opacity_(1.f)
|
||||
, children_()
|
||||
|
|
@ -57,11 +69,36 @@ namespace easy2d
|
|||
{
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
void Node::Init()
|
||||
{
|
||||
inited_ = true;
|
||||
}
|
||||
|
||||
void Node::Visit()
|
||||
void Node::OnRender()
|
||||
{
|
||||
// normal node renders nothing
|
||||
}
|
||||
|
||||
void Node::Update(Duration const & dt)
|
||||
{
|
||||
if (!inited_)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
UpdateActions(this, dt);
|
||||
UpdateTasks(dt);
|
||||
|
||||
if (!children_.IsEmpty())
|
||||
{
|
||||
for (auto child = children_.First(); child; child = child->NextItem())
|
||||
{
|
||||
child->Update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Render()
|
||||
{
|
||||
if (!visible_)
|
||||
return;
|
||||
|
|
@ -74,26 +111,21 @@ namespace easy2d
|
|||
{
|
||||
graphics->SetTransform(final_matrix_);
|
||||
graphics->SetOpacity(display_opacity_);
|
||||
OnDraw();
|
||||
|
||||
OnRender();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dirty_sort_)
|
||||
{
|
||||
children_.Sort(
|
||||
[](spNode const& n1, spNode const& n2) { return n1->GetOrder() < n2->GetOrder(); }
|
||||
);
|
||||
|
||||
dirty_sort_ = false;
|
||||
}
|
||||
SortChildren();
|
||||
|
||||
// render children those are less than 0 in Z-Order
|
||||
spNode child = children_.First();
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
next = child->NextItem();
|
||||
if (child->GetOrder() < 0)
|
||||
if (child->GetZOrder() < 0)
|
||||
{
|
||||
child->Visit();
|
||||
child->Render();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -103,49 +135,13 @@ namespace easy2d
|
|||
|
||||
graphics->SetTransform(final_matrix_);
|
||||
graphics->SetOpacity(display_opacity_);
|
||||
OnDraw();
|
||||
|
||||
OnRender();
|
||||
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
next = child->NextItem();
|
||||
child->Visit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Update(Duration const& dt)
|
||||
{
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
OnUpdate(dt);
|
||||
UpdateActions(this, dt);
|
||||
UpdateTasks(dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 访问 Order 小于零的节点
|
||||
spNode child = children_.First();
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
if (child->GetOrder() < 0)
|
||||
{
|
||||
next = child->NextItem();
|
||||
child->Update(dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OnUpdate(dt);
|
||||
UpdateActions(this, dt);
|
||||
UpdateTasks(dt);
|
||||
|
||||
for (spNode next; child; child = next)
|
||||
{
|
||||
next = child->NextItem();
|
||||
child->Update(dt);
|
||||
child->Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -159,15 +155,22 @@ namespace easy2d
|
|||
devices::Graphics::Instance()->DrawGeometry(border_, border_color_, 1.5f);
|
||||
}
|
||||
|
||||
DrawChildrenBorder();
|
||||
for (auto child = children_.First(); child; child = child->NextItem())
|
||||
{
|
||||
child->DrawBorder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::DrawChildrenBorder()
|
||||
void Node::SortChildren()
|
||||
{
|
||||
for (auto child = children_.First(); child; child = child->NextItem())
|
||||
if (dirty_sort_)
|
||||
{
|
||||
child->DrawBorder();
|
||||
children_.Sort(
|
||||
[](spNode const& n1, spNode const& n2) { return n1->GetZOrder() < n2->GetZOrder(); }
|
||||
);
|
||||
|
||||
dirty_sort_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,12 +203,17 @@ namespace easy2d
|
|||
final_matrix_ = final_matrix_ * parent_->initial_matrix_;
|
||||
}
|
||||
|
||||
UpdateBorder();
|
||||
|
||||
// update children's transform
|
||||
for (auto child = children_.First(); child; child = child->NextItem())
|
||||
{
|
||||
child->dirty_transform_ = true;
|
||||
}
|
||||
|
||||
// update border
|
||||
if (border_enabled)
|
||||
{
|
||||
UpdateBorder();
|
||||
}
|
||||
}
|
||||
|
||||
void Node::UpdateBorder()
|
||||
|
|
@ -213,22 +221,24 @@ namespace easy2d
|
|||
cpRectangleGeometry rect;
|
||||
cpTransformedGeometry transformed;
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance()->CreateRectangleGeometry(
|
||||
rect,
|
||||
Rect(Point{}, size_)
|
||||
)
|
||||
HRESULT hr = Factory::Instance()->CreateRectangleGeometry(
|
||||
rect,
|
||||
Rect(Point{}, size_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance()->CreateTransformedGeometry(
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = Factory::Instance()->CreateTransformedGeometry(
|
||||
transformed,
|
||||
final_matrix_,
|
||||
rect
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
border_ = transformed;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
border_ = transformed;
|
||||
}
|
||||
}
|
||||
|
||||
bool Node::Dispatch(const MouseEvent & e, bool handled)
|
||||
|
|
@ -281,12 +291,12 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
void Node::SetOrder(int order)
|
||||
void Node::SetZOrder(int order)
|
||||
{
|
||||
if (order_ == order)
|
||||
if (z_order_ == order)
|
||||
return;
|
||||
|
||||
order_ = order;
|
||||
z_order_ = order;
|
||||
if (parent_)
|
||||
{
|
||||
parent_->dirty_sort_ = true;
|
||||
|
|
@ -358,7 +368,21 @@ namespace easy2d
|
|||
border_color_ = color;
|
||||
}
|
||||
|
||||
void Node::AddChild(spNode const& child, int order)
|
||||
void Node::SetVisible(bool val)
|
||||
{
|
||||
visible_ = val;
|
||||
}
|
||||
|
||||
void Node::SetName(String const& name)
|
||||
{
|
||||
if (name_ != name)
|
||||
{
|
||||
name_ = name;
|
||||
hash_name_ = std::hash<String>{}(name);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::AddChild(spNode const& child, int z_order)
|
||||
{
|
||||
if (!child)
|
||||
logs::Warningln("Node::AddChild failed, child is nullptr");
|
||||
|
|
@ -366,28 +390,31 @@ namespace easy2d
|
|||
if (child)
|
||||
{
|
||||
#ifdef E2D_DEBUG
|
||||
|
||||
if (child->parent_)
|
||||
logs::Errorln("The node to be added already has a parent");
|
||||
|
||||
for (Node* parent = parent_; parent; parent = parent->parent_)
|
||||
if (parent == child)
|
||||
logs::Errorln("A node cannot be its own parent");
|
||||
|
||||
#endif // E2D_DEBUG
|
||||
|
||||
children_.PushBack(Node::ItemType(child));
|
||||
child->parent_ = this;
|
||||
child->dirty_transform_ = true;
|
||||
child->SetOrder(order);
|
||||
child->SetZOrder(z_order);
|
||||
child->UpdateOpacity();
|
||||
|
||||
dirty_sort_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::AddChild(const Nodes& nodes, int order)
|
||||
void Node::AddChild(const Nodes& nodes, int z_order)
|
||||
{
|
||||
for (const auto& node : nodes)
|
||||
{
|
||||
this->AddChild(node, order);
|
||||
this->AddChild(node, z_order);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -486,30 +513,22 @@ namespace easy2d
|
|||
|
||||
UpdateTransform();
|
||||
|
||||
BOOL ret = 0;
|
||||
cpRectangleGeometry border;
|
||||
|
||||
ThrowIfFailed(
|
||||
border_->FillContainsPoint(
|
||||
point,
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
&ret
|
||||
Factory::Instance()->CreateRectangleGeometry(
|
||||
border,
|
||||
Rect(Point{}, size_)
|
||||
)
|
||||
);
|
||||
|
||||
BOOL ret = 0;
|
||||
// no matter it failed or not
|
||||
border->FillContainsPoint(
|
||||
point,
|
||||
ConvertToD2DMatrix(final_matrix_),
|
||||
&ret
|
||||
);
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
void Node::SetVisible(bool val)
|
||||
{
|
||||
visible_ = val;
|
||||
}
|
||||
|
||||
void Node::SetName(String const& name)
|
||||
{
|
||||
if (name_ != name)
|
||||
{
|
||||
// 保存节点名
|
||||
name_ = name;
|
||||
// 保存节点 Hash 名
|
||||
hash_name_ = std::hash<String>{}(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,13 +50,14 @@ namespace easy2d
|
|||
public:
|
||||
Node();
|
||||
|
||||
virtual ~Node();
|
||||
|
||||
// 渲染节点
|
||||
virtual void OnDraw() {}
|
||||
// 初始化节点
|
||||
virtual void Init();
|
||||
|
||||
// 更新节点
|
||||
virtual void OnUpdate(Duration const& dt) {}
|
||||
virtual void Update(Duration const& dt);
|
||||
|
||||
// 渲染节点
|
||||
virtual void OnRender();
|
||||
|
||||
// 获取显示状态
|
||||
bool IsVisible() const { return visible_; }
|
||||
|
|
@ -67,8 +68,8 @@ namespace easy2d
|
|||
// 获取名称的 Hash 值
|
||||
size_t GetHashName() const { return hash_name_; }
|
||||
|
||||
// 获取绘图顺序
|
||||
int GetOrder() const { return order_; }
|
||||
// 获取 Z 轴顺序
|
||||
int GetZOrder() const { return z_order_; }
|
||||
|
||||
// 获取宽度
|
||||
virtual float GetWidth() const { return size_.width * transform_.scale.x; }
|
||||
|
|
@ -157,9 +158,9 @@ namespace easy2d
|
|||
float opacity
|
||||
);
|
||||
|
||||
// 设置绘图顺序
|
||||
// 设置 Z 轴顺序
|
||||
// 默认为 0
|
||||
void SetOrder(
|
||||
void SetZOrder(
|
||||
int order
|
||||
);
|
||||
|
||||
|
|
@ -176,13 +177,13 @@ namespace easy2d
|
|||
// 添加子节点
|
||||
void AddChild(
|
||||
spNode const& child,
|
||||
int order = 0 /* 渲染顺序 */
|
||||
int z_order = 0 /* Z 轴顺序 */
|
||||
);
|
||||
|
||||
// 添加多个子节点
|
||||
void AddChild(
|
||||
const Nodes& nodes, /* 节点数组 */
|
||||
int order = 0 /* 渲染顺序 */
|
||||
int z_order = 0 /* Z 轴顺序 */
|
||||
);
|
||||
|
||||
// 获取所有名称相同的子节点
|
||||
|
|
@ -220,8 +221,24 @@ namespace easy2d
|
|||
float pivot_y
|
||||
);
|
||||
|
||||
// 启用边框自动生成
|
||||
static void EnableBorder();
|
||||
|
||||
// 禁用边框自动生成
|
||||
static void DisableBorder();
|
||||
|
||||
protected:
|
||||
virtual void Visit();
|
||||
void Render();
|
||||
|
||||
void DrawBorder();
|
||||
|
||||
void SortChildren();
|
||||
|
||||
void UpdateBorder();
|
||||
|
||||
void UpdateTransform();
|
||||
|
||||
void UpdateOpacity();
|
||||
|
||||
virtual bool Dispatch(
|
||||
const MouseEvent& e,
|
||||
|
|
@ -234,26 +251,14 @@ namespace easy2d
|
|||
);
|
||||
|
||||
protected:
|
||||
virtual void Update(Duration const& dt);
|
||||
|
||||
virtual void DrawBorder();
|
||||
|
||||
void DrawChildrenBorder();
|
||||
|
||||
void UpdateBorder();
|
||||
|
||||
void UpdateTransform();
|
||||
|
||||
void UpdateOpacity();
|
||||
|
||||
protected:
|
||||
String name_;
|
||||
size_t hash_name_;
|
||||
float display_opacity_;
|
||||
float opacity_;
|
||||
int order_;
|
||||
bool inited_;
|
||||
bool visible_;
|
||||
bool dirty_sort_;
|
||||
int z_order_;
|
||||
float opacity_;
|
||||
float display_opacity_;
|
||||
String name_;
|
||||
size_t hash_name_;
|
||||
Node* parent_;
|
||||
Color border_color_;
|
||||
Children children_;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ namespace easy2d
|
|||
return image_;
|
||||
}
|
||||
|
||||
void Sprite::OnDraw()
|
||||
void Sprite::OnRender()
|
||||
{
|
||||
if (image_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace easy2d
|
|||
spImage const& GetImage() const;
|
||||
|
||||
// äÖȾ¾«Áé
|
||||
virtual void OnDraw() override;
|
||||
virtual void OnRender() override;
|
||||
|
||||
protected:
|
||||
spImage image_;
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ namespace easy2d
|
|||
style_.outline_stroke = outline_stroke;
|
||||
}
|
||||
|
||||
void Text::OnDraw()
|
||||
void Text::OnRender()
|
||||
{
|
||||
if (text_layout_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ namespace easy2d
|
|||
TextStyle const& style
|
||||
);
|
||||
|
||||
virtual void OnDraw() override;
|
||||
virtual void OnRender() override;
|
||||
|
||||
protected:
|
||||
void UpdateLayout();
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace easy2d
|
|||
);
|
||||
graphics->PushLayer(out_layer_, out_layer_prop_);
|
||||
|
||||
out_scene_->Visit();
|
||||
out_scene_->Render();
|
||||
|
||||
graphics->PopLayer();
|
||||
graphics->PopClip();
|
||||
|
|
@ -125,7 +125,7 @@ namespace easy2d
|
|||
);
|
||||
graphics->PushLayer(in_layer_, in_layer_prop_);
|
||||
|
||||
in_scene_->Visit();
|
||||
in_scene_->Render();
|
||||
|
||||
graphics->PopLayer();
|
||||
graphics->PopClip();
|
||||
|
|
|
|||
|
|
@ -164,7 +164,6 @@ namespace easy2d
|
|||
AudioDevice::AudioDevice()
|
||||
: x_audio2_(nullptr)
|
||||
, mastering_voice_(nullptr)
|
||||
, initialized_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -185,26 +184,23 @@ namespace easy2d
|
|||
modules::MediaFoundation().MFShutdown();
|
||||
}
|
||||
|
||||
void AudioDevice::Init(bool debug)
|
||||
HRESULT AudioDevice::Init(bool debug)
|
||||
{
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
E2D_LOG("Initing audio device");
|
||||
|
||||
ThrowIfFailed(
|
||||
modules::MediaFoundation().MFStartup(MF_VERSION, MFSTARTUP_FULL)
|
||||
);
|
||||
HRESULT hr = modules::MediaFoundation().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||
|
||||
ThrowIfFailed(
|
||||
modules::XAudio2().XAudio2Create(&x_audio2_, 0, XAUDIO2_DEFAULT_PROCESSOR)
|
||||
);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = modules::XAudio2().XAudio2Create(&x_audio2_, 0, XAUDIO2_DEFAULT_PROCESSOR);
|
||||
}
|
||||
|
||||
ThrowIfFailed(
|
||||
x_audio2_->CreateMasteringVoice(&mastering_voice_)
|
||||
);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = x_audio2_->CreateMasteringVoice(&mastering_voice_);
|
||||
}
|
||||
|
||||
initialized_ = true;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT AudioDevice::CreateVoice(Voice& voice, const WAVEFORMATEX* wfx)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace easy2d
|
|||
E2D_DECLARE_SINGLETON(AudioDevice);
|
||||
|
||||
public:
|
||||
void Init(bool debug);
|
||||
HRESULT Init(bool debug);
|
||||
|
||||
// 开启设备
|
||||
void Open();
|
||||
|
|
@ -105,7 +105,6 @@ namespace easy2d
|
|||
~AudioDevice();
|
||||
|
||||
protected:
|
||||
bool initialized_;
|
||||
IXAudio2* x_audio2_;
|
||||
IXAudio2MasteringVoice* mastering_voice_;
|
||||
std::set<Voice*> voice_cache_;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ namespace easy2d
|
|||
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
|
||||
, opacity_(1.f)
|
||||
, window_occluded_(false)
|
||||
, initialized_(false)
|
||||
, options_()
|
||||
, vsync_enabled_(true)
|
||||
, antialias_(true)
|
||||
, text_antialias_(TextAntialias::ClearType)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -48,54 +49,53 @@ namespace easy2d
|
|||
ClearImageCache();
|
||||
}
|
||||
|
||||
void GraphicsDevice::Init(HWND hwnd, GraphicsOptions options, bool debug)
|
||||
HRESULT GraphicsDevice::Init(HWND hwnd, bool vsync, bool debug)
|
||||
{
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
E2D_LOG("Initing graphics device");
|
||||
|
||||
options_ = options;
|
||||
HRESULT hr = CreateResources(hwnd);
|
||||
|
||||
CreateDeviceResources(hwnd);
|
||||
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
void GraphicsDevice::BeginDraw(HWND hwnd)
|
||||
{
|
||||
CreateDeviceResources(hwnd);
|
||||
|
||||
window_occluded_ = !!(render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
|
||||
|
||||
if (!window_occluded_)
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
render_target->BeginDraw();
|
||||
render_target->Clear(clear_color_);
|
||||
vsync_enabled_ = vsync;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void GraphicsDevice::EndDraw()
|
||||
HRESULT GraphicsDevice::BeginDraw(HWND hwnd)
|
||||
{
|
||||
HRESULT hr = CreateResources(hwnd);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
window_occluded_ = !!(render_target_->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
|
||||
|
||||
if (!window_occluded_)
|
||||
{
|
||||
render_target_->BeginDraw();
|
||||
render_target_->Clear(clear_color_);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::EndDraw()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!window_occluded_)
|
||||
{
|
||||
HRESULT hr = render_target->EndDraw();
|
||||
hr = render_target_->EndDraw();
|
||||
|
||||
if (hr == D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
||||
// 并在下一次调用时重建资源
|
||||
DiscardResources();
|
||||
hr = S_OK;
|
||||
|
||||
fps_text_format_ = nullptr;
|
||||
fps_text_layout_ = nullptr;
|
||||
text_renderer = nullptr;
|
||||
solid_brush = nullptr;
|
||||
render_target = nullptr;
|
||||
}
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void GraphicsDevice::ClearImageCache()
|
||||
|
|
@ -105,20 +105,20 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateLayer(cpLayer& layer)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
layer = nullptr;
|
||||
return render_target->CreateLayer(&layer);
|
||||
return render_target_->CreateLayer(&layer);
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::CreateSolidColorBrush(cpSolidColorBrush & brush) const
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
brush = nullptr;
|
||||
return render_target->CreateSolidColorBrush(
|
||||
return render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&brush
|
||||
);
|
||||
|
|
@ -131,18 +131,18 @@ namespace easy2d
|
|||
StrokeStyle stroke
|
||||
)
|
||||
{
|
||||
if (!solid_brush ||
|
||||
!render_target)
|
||||
if (!solid_brush_ ||
|
||||
!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
solid_brush->SetColor(stroke_color);
|
||||
solid_brush_->SetColor(stroke_color);
|
||||
auto stroke_style = Factory::Instance()->GetStrokeStyle(stroke);
|
||||
render_target->DrawGeometry(
|
||||
render_target_->DrawGeometry(
|
||||
geometry.Get(),
|
||||
solid_brush.Get(),
|
||||
solid_brush_.Get(),
|
||||
stroke_width,
|
||||
stroke_style.Get()
|
||||
);
|
||||
|
|
@ -151,24 +151,24 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::FillGeometry(cpGeometry const & geometry, const Color & fill_color)
|
||||
{
|
||||
if (!solid_brush ||
|
||||
!render_target)
|
||||
if (!solid_brush_ ||
|
||||
!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
solid_brush->SetColor(fill_color);
|
||||
render_target->FillGeometry(
|
||||
solid_brush_->SetColor(fill_color);
|
||||
render_target_->FillGeometry(
|
||||
geometry.Get(),
|
||||
solid_brush.Get()
|
||||
solid_brush_.Get()
|
||||
);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::DrawImage(spImage const & image)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (!image->GetBitmap())
|
||||
|
|
@ -177,7 +177,7 @@ namespace easy2d
|
|||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target->DrawBitmap(
|
||||
render_target_->DrawBitmap(
|
||||
image->GetBitmap().Get(),
|
||||
D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()),
|
||||
opacity_,
|
||||
|
|
@ -191,7 +191,7 @@ namespace easy2d
|
|||
cpBitmap const& bitmap
|
||||
)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
|
|
@ -199,7 +199,7 @@ namespace easy2d
|
|||
|
||||
// Do not crop bitmap
|
||||
auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
|
||||
render_target->DrawBitmap(
|
||||
render_target_->DrawBitmap(
|
||||
bitmap.Get(),
|
||||
rect,
|
||||
opacity_,
|
||||
|
|
@ -211,25 +211,25 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::DrawTextLayout(cpTextLayout const& text_layout)
|
||||
{
|
||||
if (!text_renderer)
|
||||
if (!text_renderer_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
return text_layout->Draw(nullptr, text_renderer.Get(), 0, 0);
|
||||
return text_layout->Draw(nullptr, text_renderer_.Get(), 0, 0);
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::PushClip(const math::Matrix & clip_matrix, const Size & clip_size)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target->SetTransform(ConvertToD2DMatrix(clip_matrix));
|
||||
render_target->PushAxisAlignedClip(
|
||||
render_target_->SetTransform(ConvertToD2DMatrix(clip_matrix));
|
||||
render_target_->PushAxisAlignedClip(
|
||||
D2D1::RectF(0, 0, clip_size.width, clip_size.height),
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
|
||||
);
|
||||
|
|
@ -238,33 +238,33 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::PopClip()
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target->PopAxisAlignedClip();
|
||||
render_target_->PopAxisAlignedClip();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::PushLayer(cpLayer const& layer, LayerProperties const& properties)
|
||||
{
|
||||
if (!render_target ||
|
||||
!solid_brush)
|
||||
if (!render_target_ ||
|
||||
!solid_brush_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target->PushLayer(
|
||||
render_target_->PushLayer(
|
||||
D2D1::LayerParameters(
|
||||
properties.area,
|
||||
nullptr,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
properties.opacity,
|
||||
solid_brush.Get(),
|
||||
solid_brush_.Get(),
|
||||
D2D1_LAYER_OPTIONS_NONE
|
||||
),
|
||||
layer.Get()
|
||||
|
|
@ -274,22 +274,22 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::PopLayer()
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target->PopLayer();
|
||||
render_target_->PopLayer();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::GetSize(Size & size)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
auto rtsize = render_target->GetSize();
|
||||
auto rtsize = render_target_->GetSize();
|
||||
size.width = rtsize.width;
|
||||
size.height = rtsize.height;
|
||||
return S_OK;
|
||||
|
|
@ -297,7 +297,7 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, String const& file_path)
|
||||
{
|
||||
if (render_target == nullptr)
|
||||
if (render_target_ == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -312,7 +312,7 @@ namespace easy2d
|
|||
cpBitmap bitmap_tmp;
|
||||
HRESULT hr = Factory::Instance()->CreateBitmapFromFile(
|
||||
bitmap,
|
||||
render_target,
|
||||
render_target_,
|
||||
file_path
|
||||
);
|
||||
|
||||
|
|
@ -326,7 +326,7 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateBitmapFromResource(cpBitmap& bitmap, Resource const& res)
|
||||
{
|
||||
if (render_target == nullptr)
|
||||
if (render_target_ == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -340,7 +340,7 @@ namespace easy2d
|
|||
|
||||
HRESULT hr = Factory::Instance()->CreateBitmapFromResource(
|
||||
bitmap,
|
||||
render_target,
|
||||
render_target_,
|
||||
res
|
||||
);
|
||||
|
||||
|
|
@ -354,38 +354,38 @@ namespace easy2d
|
|||
|
||||
HRESULT GraphicsDevice::CreateBitmapRenderTarget(cpBitmapRenderTarget & brt)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
brt = nullptr;
|
||||
return render_target->CreateCompatibleRenderTarget(&brt);
|
||||
return render_target_->CreateCompatibleRenderTarget(&brt);
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
render_target->Resize(D2D1::SizeU(width, height));
|
||||
render_target_->Resize(D2D1::SizeU(width, height));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::SetTransform(const math::Matrix & matrix)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
render_target->SetTransform(ConvertToD2DMatrix(matrix));
|
||||
render_target_->SetTransform(ConvertToD2DMatrix(matrix));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::SetOpacity(float opacity)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
opacity_ = opacity;
|
||||
solid_brush->SetOpacity(opacity);
|
||||
solid_brush_->SetOpacity(opacity);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -397,11 +397,11 @@ namespace easy2d
|
|||
StrokeStyle outline_stroke
|
||||
)
|
||||
{
|
||||
if (!text_renderer)
|
||||
if (!text_renderer_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
auto stroke_style = Factory::Instance()->GetStrokeStyle(outline_stroke);
|
||||
text_renderer->SetTextStyle(
|
||||
text_renderer_->SetTextStyle(
|
||||
color,
|
||||
has_outline,
|
||||
outline_color,
|
||||
|
|
@ -411,14 +411,56 @@ namespace easy2d
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void GraphicsDevice::SetBackgroundColor(const Color& color)
|
||||
void GraphicsDevice::SetClearColor(const Color& color)
|
||||
{
|
||||
clear_color_ = color;
|
||||
}
|
||||
|
||||
void GraphicsDevice::CreateDeviceResources(HWND hwnd)
|
||||
HRESULT GraphicsDevice::SetAntialiasMode(bool enabled)
|
||||
{
|
||||
if (!render_target)
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
render_target_->SetAntialiasMode(
|
||||
enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
|
||||
);
|
||||
antialias_ = enabled;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::SetTextAntialiasMode(TextAntialias mode)
|
||||
{
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
text_antialias_ = mode;
|
||||
D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
switch (text_antialias_)
|
||||
{
|
||||
case TextAntialias::Default:
|
||||
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
|
||||
break;
|
||||
case TextAntialias::ClearType:
|
||||
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
break;
|
||||
case TextAntialias::GrayScale:
|
||||
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
|
||||
break;
|
||||
case TextAntialias::None:
|
||||
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
render_target_->SetTextAntialiasMode(antialias_mode);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsDevice::CreateResources(HWND hwnd)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (!render_target_)
|
||||
{
|
||||
RECT rc;
|
||||
::GetClientRect(hwnd, &rc);
|
||||
|
|
@ -428,65 +470,50 @@ namespace easy2d
|
|||
rc.bottom - rc.top
|
||||
);
|
||||
|
||||
// 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建
|
||||
// 创建一个 Direct2D 渲染目标
|
||||
ThrowIfFailed(
|
||||
Factory::Instance()->CreateHwndRenderTarget(
|
||||
render_target,
|
||||
D2D1::RenderTargetProperties(),
|
||||
D2D1::HwndRenderTargetProperties(
|
||||
hwnd,
|
||||
size,
|
||||
options_.vsync ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY
|
||||
)
|
||||
hr = Factory::Instance()->CreateHwndRenderTarget(
|
||||
render_target_,
|
||||
D2D1::RenderTargetProperties(),
|
||||
D2D1::HwndRenderTargetProperties(
|
||||
hwnd,
|
||||
size,
|
||||
vsync_enabled_ ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY
|
||||
)
|
||||
);
|
||||
|
||||
render_target->SetAntialiasMode(
|
||||
options_.antialias ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
|
||||
);
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
switch (options_.text_antialias)
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
case TextAntialias::Default:
|
||||
mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
|
||||
break;
|
||||
case TextAntialias::ClearType:
|
||||
mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
break;
|
||||
case TextAntialias::GrayScale:
|
||||
mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
|
||||
break;
|
||||
case TextAntialias::None:
|
||||
mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
SetAntialiasMode(antialias_);
|
||||
SetTextAntialiasMode(text_antialias_);
|
||||
}
|
||||
render_target->SetTextAntialiasMode(mode);
|
||||
}
|
||||
|
||||
if (!solid_brush)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
render_target->CreateSolidColorBrush(
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&solid_brush
|
||||
)
|
||||
);
|
||||
}
|
||||
&solid_brush_
|
||||
);
|
||||
}
|
||||
|
||||
if (!text_renderer)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
Factory::Instance()->CreateTextRenderer(
|
||||
text_renderer,
|
||||
render_target,
|
||||
solid_brush
|
||||
)
|
||||
);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = Factory::Instance()->CreateTextRenderer(
|
||||
text_renderer_,
|
||||
render_target_,
|
||||
solid_brush_
|
||||
);
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void GraphicsDevice::DiscardResources()
|
||||
{
|
||||
// FIXME! 应通知 Game 类销毁所有节点的 device resources
|
||||
fps_text_format_ = nullptr;
|
||||
fps_text_layout_ = nullptr;
|
||||
text_renderer_ = nullptr;
|
||||
solid_brush_ = nullptr;
|
||||
render_target_ = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,20 +37,6 @@ namespace easy2d
|
|||
None // 不启用抗锯齿
|
||||
};
|
||||
|
||||
// 图形渲染选项
|
||||
struct GraphicsOptions
|
||||
{
|
||||
bool vsync; // 垂直同步
|
||||
bool antialias; // 抗锯齿
|
||||
TextAntialias text_antialias; // 文字抗锯齿模式
|
||||
|
||||
GraphicsOptions()
|
||||
: vsync(true)
|
||||
, antialias(true)
|
||||
, text_antialias(TextAntialias::ClearType)
|
||||
{}
|
||||
};
|
||||
|
||||
namespace devices
|
||||
{
|
||||
class GraphicsDevice
|
||||
|
|
@ -59,20 +45,34 @@ namespace easy2d
|
|||
E2D_DECLARE_SINGLETON(GraphicsDevice);
|
||||
|
||||
public:
|
||||
void Init(HWND hwnd, GraphicsOptions options, bool debug);
|
||||
HRESULT Init(HWND hwnd, bool vsync, bool debug);
|
||||
|
||||
// 开始渲染
|
||||
void BeginDraw(HWND hwnd);
|
||||
HRESULT BeginDraw(HWND hwnd);
|
||||
|
||||
// 结束渲染
|
||||
void EndDraw();
|
||||
HRESULT EndDraw();
|
||||
|
||||
// 设置背景色
|
||||
void SetBackgroundColor(
|
||||
// 设置清空屏幕的颜色
|
||||
void SetClearColor(
|
||||
const Color& color
|
||||
);
|
||||
|
||||
void CreateDeviceResources(HWND hwnd);
|
||||
// 设置抗锯齿模式
|
||||
HRESULT SetAntialiasMode(
|
||||
bool enabled
|
||||
);
|
||||
|
||||
// 设置文字抗锯齿模式
|
||||
HRESULT SetTextAntialiasMode(
|
||||
TextAntialias mode
|
||||
);
|
||||
|
||||
HRESULT CreateResources(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void DiscardResources();
|
||||
|
||||
HRESULT CreateLayer(
|
||||
cpLayer& layer
|
||||
|
|
@ -167,13 +167,14 @@ namespace easy2d
|
|||
~GraphicsDevice();
|
||||
|
||||
protected:
|
||||
bool initialized_;
|
||||
bool window_occluded_;
|
||||
bool vsync_enabled_;
|
||||
bool antialias_;
|
||||
TextAntialias text_antialias_;
|
||||
float opacity_;
|
||||
GraphicsOptions options_;
|
||||
cpTextRenderer text_renderer;
|
||||
cpSolidColorBrush solid_brush;
|
||||
cpHwndRenderTarget render_target;
|
||||
cpTextRenderer text_renderer_;
|
||||
cpSolidColorBrush solid_brush_;
|
||||
cpHwndRenderTarget render_target_;
|
||||
D2D1_COLOR_F clear_color_;
|
||||
cpTextFormat fps_text_format_;
|
||||
cpTextLayout fps_text_layout_;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ namespace easy2d
|
|||
: handle(nullptr)
|
||||
, scale_x(1.f)
|
||||
, scale_y(1.f)
|
||||
, initialized_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -48,11 +47,8 @@ namespace easy2d
|
|||
E2D_LOG("Destroying window");
|
||||
}
|
||||
|
||||
void WindowImpl::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug)
|
||||
HRESULT WindowImpl::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug)
|
||||
{
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
E2D_LOG("Creating window");
|
||||
|
||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||
|
|
@ -85,10 +81,8 @@ namespace easy2d
|
|||
|
||||
GetContentScale(&scale_x, &scale_y);
|
||||
|
||||
// 计算窗口大小
|
||||
Rect client_rect = LocateWindow(width, height, scale_x, scale_y);
|
||||
|
||||
// 创建窗口
|
||||
Rect client_rect = LocateWindow(width, height, scale_x, scale_y);
|
||||
handle = ::CreateWindowEx(
|
||||
NULL,
|
||||
REGISTER_CLASS,
|
||||
|
|
@ -107,13 +101,9 @@ namespace easy2d
|
|||
if (handle == nullptr)
|
||||
{
|
||||
::UnregisterClass(REGISTER_CLASS, hinstance);
|
||||
|
||||
const char* err = "Create window failed!";
|
||||
logs::Errorln(HRESULT_FROM_WIN32(GetLastError()), err);
|
||||
throw std::runtime_error(err);
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
initialized_ = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
String WindowImpl::GetTitle() const
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace easy2d
|
|||
E2D_DECLARE_SINGLETON(WindowImpl);
|
||||
|
||||
public:
|
||||
void Init(
|
||||
HRESULT Init(
|
||||
String title,
|
||||
int width,
|
||||
int height,
|
||||
|
|
@ -72,7 +72,6 @@ namespace easy2d
|
|||
~WindowImpl();
|
||||
|
||||
private:
|
||||
bool initialized_;
|
||||
HWND handle;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
|
|
|
|||
|
|
@ -220,31 +220,6 @@ namespace easy2d
|
|||
return Node::Dispatch(e, handled);
|
||||
}
|
||||
|
||||
void Button::Visit()
|
||||
{
|
||||
Node::Visit();
|
||||
|
||||
if (IsVisible() &&
|
||||
!enabled_ &&
|
||||
normal_ &&
|
||||
normal_->ContainsPoint(devices::Input::Instance()->GetMousePos()))
|
||||
{
|
||||
HCURSOR hcursor = ::LoadCursor(nullptr, IDC_NO);
|
||||
if (hcursor)
|
||||
{
|
||||
::SetCursor(hcursor);
|
||||
}
|
||||
}
|
||||
else if (status_ == Status::Mouseover || status_ == Status::Selected)
|
||||
{
|
||||
HCURSOR hcursor = ::LoadCursor(nullptr, IDC_HAND);
|
||||
if (hcursor)
|
||||
{
|
||||
::SetCursor(hcursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Button::SetStatus(Status status)
|
||||
{
|
||||
if (status_ != status)
|
||||
|
|
|
|||
|
|
@ -120,9 +120,6 @@ namespace easy2d
|
|||
bool handled
|
||||
) override;
|
||||
|
||||
// 遍历节点
|
||||
virtual void Visit() override;
|
||||
|
||||
private:
|
||||
spNode normal_;
|
||||
spNode mouseover_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue