From d1ad592df7401d33337ca94f57e39e9910f7bd89 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sun, 29 Jul 2018 13:44:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4Config=E4=B8=AD=E5=9E=82?= =?UTF-8?q?=E7=9B=B4=E5=90=8C=E6=AD=A5=E7=9A=84=E8=AE=BE=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E7=A8=8B=E5=BA=8F=E7=9A=84=E5=BB=B6?= =?UTF-8?q?=E6=97=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Config.cpp | 22 ------- core/Base/Game.cpp | 35 +++++------ core/Base/Renderer.cpp | 12 ++-- core/Common/Color.cpp | 2 +- core/Common/Scene.cpp | 4 +- core/Node/Node.cpp | 135 +++++++++++++++++++++++------------------ core/e2dbase.h | 21 ------- core/e2dnode.h | 1 - 8 files changed, 100 insertions(+), 132 deletions(-) diff --git a/core/Base/Config.cpp b/core/Base/Config.cpp index 89f31e92..8853a31d 100644 --- a/core/Base/Config.cpp +++ b/core/Base/Config.cpp @@ -4,9 +4,7 @@ e2d::Config::Config() : _gameName() , _soundEnabled(true) - , _frameInterval(15) , _showFps(false) - , _vSyncEnabled(true) , _outlineVisible(false) , _collisionEnabled(false) , _colliderVisible(false) @@ -27,16 +25,6 @@ void e2d::Config::showFps(bool show) _showFps = show; } -void e2d::Config::setVSyncEnabled(bool enabled) -{ - _vSyncEnabled = enabled; -} - -void e2d::Config::setFrameInterval(int interval) -{ - _frameInterval = interval; -} - void e2d::Config::setOutlineVisible(bool visible) { _outlineVisible = visible; @@ -67,21 +55,11 @@ bool e2d::Config::isSoundEnabled() const return _soundEnabled; } -bool e2d::Config::isVSyncEnabled() const -{ - return _vSyncEnabled; -} - bool e2d::Config::isFpsShow() const { return _showFps; } -int e2d::Config::getFrameInterval() const -{ - return _frameInterval; -} - bool e2d::Config::isOutlineVisible() const { return _outlineVisible; diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 33262ea7..352129ec 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -10,7 +10,6 @@ e2d::Game::Game() : _quit(true) , _paused(false) , _config() - , _frameInterval(_config.getFrameInterval()) { CoInitialize(nullptr); @@ -40,27 +39,24 @@ void e2d::Game::destroyInstance() void e2d::Game::start() { - // 显示窗口 + SceneManager::getInstance()->update(); + HWND hWnd = Window::getInstance()->getHWnd(); ::ShowWindow(hWnd, SW_SHOWNORMAL); ::UpdateWindow(hWnd); - - SceneManager::getInstance()->update(); Window::getInstance()->poll(); - // 开始游戏 - int wait = 0; - Duration interval; - _quit = false; _last = _now = Time::now(); + + const Duration minInterval(15); while (!_quit) { _now = Time::now(); - interval = _now - _last; + Duration interval = _now - _last; - if (_config.isVSyncEnabled() || _frameInterval < interval) + if (minInterval < interval) { _last = _now; Input::getInstance()->update(); @@ -73,7 +69,14 @@ void e2d::Game::start() } else { - std::this_thread::yield(); + // ID2D1HwndRenderTarget 在渲染时会等待显示器刷新,即开启了垂直同步, + // 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。 + // 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。 + int wait = (minInterval - interval).milliseconds(); + if (wait > 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(wait)); + } } } } @@ -109,16 +112,6 @@ void e2d::Game::setConfig(const Config& config) Player::getInstance()->getXAudio2()->StopEngine(); } - if (_config.getFrameInterval() != config.getFrameInterval()) - { - _frameInterval = Duration(config.getFrameInterval()); - } - - if (_config.isVSyncEnabled() != config.isVSyncEnabled()) - { - Renderer::getInstance()->discardDeviceResources(); - } - _config = config; } diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 57b07813..87b9f6cc 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -69,10 +69,10 @@ void e2d::Renderer::discardDeviceResources() void e2d::Renderer::render() { - HRESULT hr = S_OK; - - // 创建设备相关资源 auto renderTarget = this->getRenderTarget(); + // 仅当窗口没有被遮挡时进行渲染 + if (renderTarget->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED) + return; // 开始渲染 renderTarget->BeginDraw(); @@ -89,7 +89,7 @@ void e2d::Renderer::render() } // 终止渲染 - hr = renderTarget->EndDraw(); + HRESULT hr = renderTarget->EndDraw(); if (hr == D2DERR_RECREATE_TARGET) { @@ -195,15 +195,13 @@ ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget() rc.bottom - rc.top ); - bool VSyncEnabled = Game::getInstance()->getConfig().isVSyncEnabled(); - // 创建一个 Direct2D 渲染目标 HRESULT hr = Renderer::getFactory()->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hWnd, size, - VSyncEnabled ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY), + D2D1_PRESENT_OPTIONS_NONE), &_renderTarget ); diff --git a/core/Common/Color.cpp b/core/Common/Color.cpp index 9daee063..d857ec7c 100644 --- a/core/Common/Color.cpp +++ b/core/Common/Color.cpp @@ -44,7 +44,7 @@ e2d::Color::Color(UINT rgb, float alpha) e2d::Color::operator D2D1_COLOR_F() const { - return D2D1::ColorF(r, g, b, a); + return std::move(D2D1::ColorF(r, g, b, a)); } void e2d::Color::_init(UINT rgb, float alpha) diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index 1341b6a7..ecfdd39b 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -22,7 +22,9 @@ void e2d::Scene::render() if (Game::getInstance()->getConfig().isOutlineVisible()) { - Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + auto brush = Renderer::getInstance()->getSolidColorBrush(); + brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f)); + brush->SetOpacity(1.f); _root->_renderOutline(); } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index ce7d4b87..caf3de17 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -65,7 +65,6 @@ e2d::Node::Node() , _needTransform(false) , _autoUpdate(true) , _positionFixed(false) - , _outline(nullptr) , _collider(this) , _extrapolate(Property::Origin) { @@ -73,8 +72,6 @@ e2d::Node::Node() e2d::Node::~Node() { - SafeRelease(_outline); - ActionManager::getInstance()->clearAllBindedWith(this); for (auto child : _children) { @@ -158,7 +155,7 @@ void e2d::Node::_render() if (_children.empty()) { - // 转换渲染器的二维矩阵 + // 转换渲染器的转换矩阵 pRT->SetTransform(_finalMatri); // 渲染自身 this->onRender(); @@ -183,7 +180,7 @@ void e2d::Node::_render() } } - // 转换渲染器的二维矩阵 + // 转换渲染器的转换矩阵 pRT->SetTransform(_finalMatri); // 渲染自身 this->onRender(); @@ -203,17 +200,13 @@ void e2d::Node::_renderOutline() { if (_visible) { - if (_outline) - { - auto renderer = Renderer::getInstance(); - // 获取纯色画刷 - ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush(); - // 设置画刷颜色和透明度 - brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f)); - brush->SetOpacity(1.f); - // 渲染轮廓 - renderer->getRenderTarget()->DrawGeometry(_outline, brush, 1.5f); - } + auto renderer = Renderer::getInstance(); + renderer->getRenderTarget()->SetTransform(_finalMatri); + renderer->getRenderTarget()->DrawRectangle( + D2D1::RectF(0, 0, _width, _height), + renderer->getSolidColorBrush(), + 1.5f + ); // 渲染所有子节点的轮廓 for (auto child : _children) @@ -274,29 +267,6 @@ void e2d::Node::updateTransform() // 更新碰撞体 _collider.recreate(); - // 为节点创建一个轮廓 - ID2D1RectangleGeometry * rectGeo = nullptr; - ID2D1TransformedGeometry * transformedGeo = nullptr; - - auto factory = Renderer::getFactory(); - HRESULT hr = factory->CreateRectangleGeometry( - D2D1::RectF(0, 0, _width, _height), - &rectGeo - ); - - if (SUCCEEDED(hr)) - { - factory->CreateTransformedGeometry( - rectGeo, - _finalMatri, - &transformedGeo - ); - } - - SafeRelease(rectGeo); - SafeRelease(_outline); - _outline = transformedGeo; - // 通知子节点进行转换 for (auto& child : _children) { @@ -896,43 +866,92 @@ void e2d::Node::stopAction(const String& name) bool e2d::Node::containsPoint(const Point& point) { + // 更新转换矩阵 updateTransform(); - if (_outline) + + // 为节点创建一个轮廓 + BOOL ret = 0; + ID2D1RectangleGeometry * rectGeo = nullptr; + auto factory = Renderer::getFactory(); + + HRESULT hr = factory->CreateRectangleGeometry( + D2D1::RectF(0, 0, _width, _height), + &rectGeo + ); + + if (SUCCEEDED(hr)) { - BOOL ret = 0; - _outline->FillContainsPoint( + rectGeo->FillContainsPoint( D2D1::Point2F(point.x, point.y), - D2D1::Matrix3x2F::Identity(), + _finalMatri, &ret ); - if (ret) - { - return true; - } } - return false; + SafeRelease(rectGeo); + + return ret != 0; } bool e2d::Node::intersects(Node * node) { + // 更新转换矩阵 updateTransform(); node->updateTransform(); - if (_outline) + + // 为节点创建轮廓 + D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN; + ID2D1RectangleGeometry *rectGeo = nullptr, *rectGeo2 = nullptr; + ID2D1TransformedGeometry *transGeo = nullptr, *transGeo2 = nullptr; + auto factory = Renderer::getFactory(); + + HRESULT hr = factory->CreateRectangleGeometry( + D2D1::RectF(0, 0, _width, _height), + &rectGeo + ); + + if (SUCCEEDED(hr)) + { + hr = factory->CreateRectangleGeometry( + D2D1::RectF(0, 0, node->_width, node->_height), + &rectGeo2 + ); + } + + if (SUCCEEDED(hr)) + { + hr = factory->CreateTransformedGeometry( + rectGeo, + _finalMatri, + &transGeo + ); + } + + if (SUCCEEDED(hr)) + { + hr = factory->CreateTransformedGeometry( + rectGeo2, + node->_finalMatri, + &transGeo2 + ); + } + + if (SUCCEEDED(hr)) { - D2D1_GEOMETRY_RELATION relation; // 获取相交状态 - _outline->CompareWithGeometry( - node->_outline, + transGeo->CompareWithGeometry( + transGeo2, D2D1::Matrix3x2F::Identity(), &relation ); - if ((relation != D2D1_GEOMETRY_RELATION_UNKNOWN) && - (relation != D2D1_GEOMETRY_RELATION_DISJOINT)) - { - return true; - } } - return false; + + SafeRelease(rectGeo); + SafeRelease(rectGeo2); + SafeRelease(transGeo); + SafeRelease(transGeo2); + + return relation != D2D1_GEOMETRY_RELATION_UNKNOWN && + relation != D2D1_GEOMETRY_RELATION_DISJOINT; } void e2d::Node::setAutoUpdate(bool bAutoUpdate) diff --git a/core/e2dbase.h b/core/e2dbase.h index 223f0710..eae663a2 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -30,18 +30,6 @@ public: bool show ); - // 打开或关闭垂直同步 - // 默认:打开 - void setVSyncEnabled( - bool enabled - ); - - // 设置帧率刷新间隔(关闭垂直同步时生效) - // 默认:15 - void setFrameInterval( - int interval - ); - // 显示或隐藏节点轮廓 // 默认:隐藏 void setOutlineVisible( @@ -72,15 +60,9 @@ public: // 获取声音打开状态 bool isSoundEnabled() const; - // 获取垂直同步打开状态 - bool isVSyncEnabled() const; - // 获取 FPS 显示状态 bool isFpsShow() const; - // 获取帧率刷新间隔 - int getFrameInterval() const; - // 获取节点轮廓显示状态 bool isOutlineVisible() const; @@ -92,12 +74,10 @@ public: protected: bool _showFps; - bool _vSyncEnabled; bool _soundEnabled; bool _outlineVisible; bool _collisionEnabled; bool _colliderVisible; - int _frameInterval; String _gameName; }; @@ -155,7 +135,6 @@ private: Time _start; Time _now; Time _last; - Duration _frameInterval; static Game * _instance; }; diff --git a/core/e2dnode.h b/core/e2dnode.h index 7e11dde3..5f386225 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -467,7 +467,6 @@ protected: Scene * _parentScene; Node * _parent; Property _extrapolate; - ID2D1Geometry* _outline; D2D1::Matrix3x2F _initialMatri; D2D1::Matrix3x2F _finalMatri; std::vector _children;