From 05bcd762e0d91998387607e364a52df03d6c2192 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sun, 15 Oct 2017 23:58:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0ENode=E7=9F=A9=E5=BD=A2?= =?UTF-8?q?=E5=8F=98=E6=8D=A2=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=8C=89=E4=B8=8B?= =?UTF-8?q?=E5=92=8C=E5=8F=8C=E5=87=BB=E9=BC=A0=E6=A0=87=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/main.cpp | 24 +- Demo/test.png | Bin 0 -> 21833 bytes Easy2D/Base/EApp.cpp | 41 +-- Easy2D/Base/EScene.cpp | 14 +- Easy2D/Easy2D.vcxproj | 5 +- Easy2D/Easy2D.vcxproj.filters | 15 +- Easy2D/Msg/Listener/EMouseClickListener.cpp | 12 +- .../Listener/EMouseDoubleClickListener.cpp | 45 +++ Easy2D/Msg/Listener/EMouseDragListener.cpp | 41 +++ Easy2D/Msg/Listener/EMouseDraggedListener.cpp | 42 --- Easy2D/Msg/Listener/EMousePressListener.cpp | 37 +++ Easy2D/Node/ENode.cpp | 162 +++++++--- Easy2D/Node/ESprite.cpp | 289 ++++++++++++++++++ Easy2D/Win/winbase.cpp | 38 ++- Easy2D/Win/winbase.h | 10 +- Easy2D/ebase.h | 6 + Easy2D/ecommon.h | 2 + Easy2D/emacros.h | 5 + Easy2D/emsg.h | 83 ++++- Easy2D/enodes.h | 96 +++++- 20 files changed, 811 insertions(+), 156 deletions(-) create mode 100644 Demo/test.png create mode 100644 Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp create mode 100644 Easy2D/Msg/Listener/EMouseDragListener.cpp delete mode 100644 Easy2D/Msg/Listener/EMouseDraggedListener.cpp create mode 100644 Easy2D/Msg/Listener/EMousePressListener.cpp create mode 100644 Easy2D/Node/ESprite.cpp diff --git a/Demo/main.cpp b/Demo/main.cpp index 4dee944b..fc1cbffb 100644 --- a/Demo/main.cpp +++ b/Demo/main.cpp @@ -14,7 +14,7 @@ int WINAPI WinMain( { auto scene = new EScene(); - auto node = new ENode(L"node1"); + /*auto node = new ENode(L"node1"); node->setPos(50, 80); node->setSize(30, 30); scene->add(node); @@ -25,13 +25,29 @@ int WINAPI WinMain( node->addChild(node2); auto mlistener = new EMouseClickListener([](EPoint p) { - EApp::getCurrentScene()->getChild(L"node1")->setPos(p.x, p.y); + EApp::getCurrentScene()->getChild(L"node1")->setPos(p.x, p.y); }); - mlistener->bindWith(node); + mlistener->bindWith(node);*/ + auto sprite = new ESprite(L"test.png"); + sprite->setAnchor(0.5f, 0.5f); + sprite->setPos(sprite->getWidth() / 2, sprite->getHeight() / 2); + + auto sprite2 = new ESprite(L"test.png"); + sprite2->setScale(0.5); + sprite2->setRotation(45); + + sprite->addChild(sprite2); + + auto mlistener = new EMouseClickListener([=](EPoint p) { + sprite->setRotation(sprite->getRotation() + 10); + }); + + mlistener->bindWith(sprite); + + scene->add(sprite); app.enterScene(scene); - app.run(); } diff --git a/Demo/test.png b/Demo/test.png new file mode 100644 index 0000000000000000000000000000000000000000..23b604623cfa24166dd9310929b57ee6de3aafba GIT binary patch literal 21833 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 literal 0 HcmV?d00001 diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index c3aa9232..90feea4b 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -9,12 +9,6 @@ using namespace std::chrono; using namespace std::this_thread; -#ifndef HINST_THISCOMPONENT -EXTERN_C IMAGE_DOS_HEADER __ImageBase; -#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) -#endif - - e2d::EApp * s_pInstance = nullptr; std::stack s_SceneStack; @@ -134,7 +128,7 @@ bool e2d::EApp::init(e2d::EString title, UINT32 width, UINT32 height, bool bShow // 获取窗口大小(包含菜单栏) tagRECT rcWindow; GetWindowRect(GetHWnd(), &rcWindow); - // 修改窗口大小,并设置窗口在屏幕居中 + // 设置窗口在屏幕居中 MoveWindow( GetHWnd(), (screenWidth - (rcWindow.right - rcWindow.left)) / 2, @@ -432,6 +426,7 @@ void e2d::EApp::_enterNextScene() if (m_pCurrentScene) { m_pCurrentScene->onExit(); + m_pCurrentScene->_onExit(); if (m_pCurrentScene->m_bWillSave) { @@ -444,7 +439,9 @@ void e2d::EApp::_enterNextScene() } } - m_pNextScene->onEnter(); // 执行下一场景的 onEnter 函数 + // 执行下一场景的 onEnter 函数 + m_pNextScene->_onEnter(); + m_pNextScene->onEnter(); m_pCurrentScene = m_pNextScene; // 切换场景 m_pNextScene = nullptr; // 下一场景置空 @@ -474,32 +471,10 @@ HRESULT e2d::EApp::_createDeviceIndependentResources() // changes, the window is remoted, etc. HRESULT e2d::EApp::_createDeviceResources() { - HRESULT hr = S_OK; + // 这个函数将自动创建设备相关资源 + GetRenderTarget(); - if (!GetRenderTarget()) - { - RECT rc; - GetClientRect(GetHWnd(), &rc); - - D2D1_SIZE_U size = D2D1::SizeU( - rc.right - rc.left, - rc.bottom - rc.top - ); - - // Create a Direct2D render target. - hr = GetFactory()->CreateHwndRenderTarget( - D2D1::RenderTargetProperties(), - D2D1::HwndRenderTargetProperties(GetHWnd(), size), - &GetRenderTarget() - ); - } - - if (FAILED(hr)) - { - MessageBox(nullptr, L"Create Device Resources Failed!", L"Error", MB_OK); - } - - return hr; + return S_OK; } // Discards device-dependent resources. These resources must be diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index c71c99a9..f5205e43 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -14,6 +14,14 @@ e2d::EScene::~EScene() clearAllChildren(); } +void e2d::EScene::onEnter() +{ +} + +void e2d::EScene::onExit() +{ +} + void e2d::EScene::_onRender() { this->_sortChildren(); @@ -23,7 +31,7 @@ void e2d::EScene::_onRender() // 访问所有节点 for (auto child : m_vChildren) { - child->callOn(); + child->_callOn(); } } @@ -44,7 +52,7 @@ void e2d::EScene::_sortChildren() } } -void e2d::EScene::onEnter() +void e2d::EScene::_onEnter() { // 启用场景上的所有定时器、监听器和动画 //Timer::notifyAllSceneTimers(m_pNextScene); @@ -52,7 +60,7 @@ void e2d::EScene::onEnter() //ActionManager::notifyAllSceneActions(m_pNextScene); } -void e2d::EScene::onExit() +void e2d::EScene::_onExit() { if (m_bWillSave) { diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index 7903b83a..135e7a09 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -200,10 +200,13 @@ - + + + + diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index caaf10a1..9405f3d5 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -48,9 +48,6 @@ Msg\Listener - - Msg\Listener - Msg\Listener @@ -66,6 +63,18 @@ Node + + Node + + + Msg\Listener + + + Msg\Listener + + + Msg\Listener + diff --git a/Easy2D/Msg/Listener/EMouseClickListener.cpp b/Easy2D/Msg/Listener/EMouseClickListener.cpp index 951030a7..367046bd 100644 --- a/Easy2D/Msg/Listener/EMouseClickListener.cpp +++ b/Easy2D/Msg/Listener/EMouseClickListener.cpp @@ -2,31 +2,41 @@ e2d::EMouseClickListener::EMouseClickListener() : EMouseListener() + , m_bPressed(false) { } e2d::EMouseClickListener::EMouseClickListener(EString name) : EMouseListener(name) + , m_bPressed(false) { } e2d::EMouseClickListener::EMouseClickListener(const MOUSE_CLICK_LISTENER_CALLBACK & callback) : EMouseListener() , m_callback(callback) + , m_bPressed(false) { } e2d::EMouseClickListener::EMouseClickListener(EString name, const MOUSE_CLICK_LISTENER_CALLBACK & callback) : EMouseListener(name) , m_callback(callback) + , m_bPressed(false) { } void e2d::EMouseClickListener::runCallback() { - if (EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_UP) + if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN || + EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK) + { + m_bPressed = true; + } + else if (m_bPressed && EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP) { m_callback(EMouseMsg::getPos()); + m_bPressed = false; } } diff --git a/Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp b/Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp new file mode 100644 index 00000000..1a8ee4f8 --- /dev/null +++ b/Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp @@ -0,0 +1,45 @@ +#include "..\..\emsg.h" + +e2d::EMouseDoubleClickListener::EMouseDoubleClickListener() + : EMouseListener() + , m_bPressed(false) +{ +} + +e2d::EMouseDoubleClickListener::EMouseDoubleClickListener(EString name) + : EMouseListener(name) + , m_bPressed(false) +{ +} + +e2d::EMouseDoubleClickListener::EMouseDoubleClickListener(const MOUSE_DBLCLK_LISTENER_CALLBACK & callback) + : EMouseListener() + , m_callback(callback) + , m_bPressed(false) +{ +} + +e2d::EMouseDoubleClickListener::EMouseDoubleClickListener(EString name, const MOUSE_DBLCLK_LISTENER_CALLBACK & callback) + : EMouseListener(name) + , m_callback(callback) + , m_bPressed(false) +{ +} + +void e2d::EMouseDoubleClickListener::runCallback() +{ + if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK) + { + m_bPressed = true; + } + else if (m_bPressed && EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP) + { + m_callback(EMouseMsg::getPos()); + m_bPressed = false; + } +} + +void e2d::EMouseDoubleClickListener::setCallback(const MOUSE_DBLCLK_LISTENER_CALLBACK & callback) +{ + m_callback = callback; +} diff --git a/Easy2D/Msg/Listener/EMouseDragListener.cpp b/Easy2D/Msg/Listener/EMouseDragListener.cpp new file mode 100644 index 00000000..1eb9c705 --- /dev/null +++ b/Easy2D/Msg/Listener/EMouseDragListener.cpp @@ -0,0 +1,41 @@ +#include "..\..\emsg.h" + +e2d::EMouseDragListener::EMouseDragListener() + : EMouseListener() +{ +} + +e2d::EMouseDragListener::EMouseDragListener(EString name) + : EMouseListener(name) +{ +} + +e2d::EMouseDragListener::EMouseDragListener(const MOUSE_DRAG_LISTENER_CALLBACK & callback) + : EMouseListener() + , m_callback(callback) +{ +} + +e2d::EMouseDragListener::EMouseDragListener(EString name, const MOUSE_DRAG_LISTENER_CALLBACK & callback) + : EMouseListener(name) + , m_callback(callback) +{ +} + +void e2d::EMouseDragListener::runCallback() +{ + if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN || + EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK) + { + m_Begin = EMouseMsg::getPos(); + } + else if (EMouseMsg::isLButtonDown() && EMouseMsg::getMsg() == EMouseMsg::MOVE) + { + m_callback(m_Begin, EMouseMsg::getPos()); + } +} + +void e2d::EMouseDragListener::setCallback(const MOUSE_DRAG_LISTENER_CALLBACK & callback) +{ + m_callback = callback; +} diff --git a/Easy2D/Msg/Listener/EMouseDraggedListener.cpp b/Easy2D/Msg/Listener/EMouseDraggedListener.cpp deleted file mode 100644 index b944baed..00000000 --- a/Easy2D/Msg/Listener/EMouseDraggedListener.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "..\..\emsg.h" - -e2d::EMouseDraggedListener::EMouseDraggedListener() - : EMouseListener() -{ -} - -e2d::EMouseDraggedListener::EMouseDraggedListener(EString name) - : EMouseListener(name) -{ -} - -e2d::EMouseDraggedListener::EMouseDraggedListener(const MOUSE_DRAG_LISTENER_CALLBACK & callback) - : EMouseListener() - , m_callback(callback) -{ -} - -e2d::EMouseDraggedListener::EMouseDraggedListener(EString name, const MOUSE_DRAG_LISTENER_CALLBACK & callback) - : EMouseListener(name) - , m_callback(callback) -{ -} - -void e2d::EMouseDraggedListener::runCallback() -{ - if (EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_DOWN || - EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_DBLCLK) - { - m_Begin = EMouseMsg::getPos(); - } - else if (EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_UP) - { - m_End = EMouseMsg::getPos(); - m_callback(m_Begin, m_End); - } -} - -void e2d::EMouseDraggedListener::setCallback(const MOUSE_DRAG_LISTENER_CALLBACK & callback) -{ - m_callback = callback; -} diff --git a/Easy2D/Msg/Listener/EMousePressListener.cpp b/Easy2D/Msg/Listener/EMousePressListener.cpp new file mode 100644 index 00000000..ef0801e4 --- /dev/null +++ b/Easy2D/Msg/Listener/EMousePressListener.cpp @@ -0,0 +1,37 @@ +#include "..\..\emsg.h" + +e2d::EMousePressListener::EMousePressListener() + : EMouseListener() +{ +} + +e2d::EMousePressListener::EMousePressListener(EString name) + : EMouseListener(name) +{ +} + +e2d::EMousePressListener::EMousePressListener(const MOUSE_PRESS_LISTENER_CALLBACK & callback) + : EMouseListener() + , m_callback(callback) +{ +} + +e2d::EMousePressListener::EMousePressListener(EString name, const MOUSE_PRESS_LISTENER_CALLBACK & callback) + : EMouseListener(name) + , m_callback(callback) +{ +} + +void e2d::EMousePressListener::runCallback() +{ + if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN || + EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK) + { + m_callback(EMouseMsg::getPos()); + } +} + +void e2d::EMousePressListener::setCallback(const MOUSE_PRESS_LISTENER_CALLBACK & callback) +{ + m_callback = callback; +} diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index d16493bb..6c190c3c 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -8,20 +8,22 @@ e2d::ENode::ENode() , m_fPosY(0) , m_fWidth(0) , m_fHeight(0) - , m_fScaleX(1) - , m_fScaleY(1) + , m_fScaleX(1.0f) + , m_fScaleY(1.0f) , m_fRotation(0) , m_fSkewAngleX(0) , m_fSkewAngleY(0) - , m_fDisplayOpacity(1) - , m_fRealOpacity(1) + , m_fDisplayOpacity(1.0f) + , m_fRealOpacity(1.0f) + , m_fAnchorX(0) + , m_fAnchorY(0) , m_Matri(D2D1::Matrix3x2F::Identity()) , m_bVisiable(true) , m_pParent(nullptr) , m_pParentScene(nullptr) , m_nHashName(0) - , m_bSortNeeded(false) - , m_bTransformNeeded(false) + , m_bSortChildrenNeeded(false) + , m_bTransformChildrenNeeded(false) { } @@ -35,14 +37,17 @@ e2d::ENode::~ENode() { } -void e2d::ENode::callOn() +void e2d::ENode::_callOn() { if (!m_bVisiable) { return; } - this->_transfrom(); + if (m_bTransformChildrenNeeded) + { + _updateTransform(this); + } if (!m_vChildren.empty()) { @@ -56,7 +61,7 @@ void e2d::ENode::callOn() // 访问 Order 小于零的节点 if (child->getOrder() < 0) { - child->callOn(); + child->_callOn(); } else { @@ -70,7 +75,7 @@ void e2d::ENode::callOn() // 访问剩余节点 for (; i < size; i++) - m_vChildren[i]->callOn(); + m_vChildren[i]->_callOn(); } else { @@ -86,7 +91,7 @@ void e2d::ENode::_onRender() void e2d::ENode::_sortChildren() { - if (m_bSortNeeded) + if (m_bSortChildrenNeeded) { // 子节点排序 std::sort( @@ -97,36 +102,77 @@ void e2d::ENode::_sortChildren() } ); - m_bSortNeeded = false; + m_bSortChildrenNeeded = false; } } -void e2d::ENode::_transfrom() +void e2d::ENode::_updateTransformToReal() { - if (m_bTransformNeeded) + // 计算锚点坐标 + D2D1_POINT_2F anchorPos = D2D1::Point2F( + m_fWidth * m_fAnchorX, + m_fHeight * m_fAnchorY + ); + // 计算左上角坐标 + D2D1_POINT_2F upperLeftCorner = D2D1::Point2F( + m_fPosX - m_fWidth * m_fAnchorX, + m_fPosY - m_fHeight * m_fAnchorY + ); + // 二维矩形变换 + m_Matri = D2D1::Matrix3x2F::Scale( + m_fScaleX, + m_fScaleY, + anchorPos + ) * D2D1::Matrix3x2F::Rotation( + m_fRotation, + anchorPos + ) * D2D1::Matrix3x2F::Skew( + m_fSkewAngleX, + m_fSkewAngleY, + anchorPos + ) * D2D1::Matrix3x2F::Translation( + upperLeftCorner.x, + upperLeftCorner.y + ); +} + +void e2d::ENode::_updateChildrenTransform() +{ + for (const auto &child : m_vChildren) { - // 二维矩形变换 - m_Matri = D2D1::Matrix3x2F::Identity(); - m_Matri = m_Matri.Translation(m_fPosX, m_fPosY); - m_Matri = m_Matri.Rotation(m_fRotation); - m_Matri = m_Matri.Scale(m_fScaleX, m_fScaleY); - m_Matri = m_Matri.Skew(m_fSkewAngleX, m_fSkewAngleY); - - if (m_pParent) - { - //m_Matri.SetProduct() - } - - // 提示子节点更新属性 - for (const auto &child : m_vChildren) - { - child->m_bTransformNeeded = true; - } - - m_bTransformNeeded = false; + _updateTransform(child); } } +void e2d::ENode::_updateTransform(ENode * node) +{ + node->_updateTransformToReal(); + if (node->m_pParent) + { + node->m_Matri = node->m_Matri * node->m_pParent->m_Matri; + } + // 遍历子节点下的所有节点 + node->_updateChildrenTransform(); + node->m_bTransformChildrenNeeded = false; +} + +void e2d::ENode::_updateChildrenOpacity() +{ + for (const auto &child : m_vChildren) + { + _updateOpacity(child); + } +} + +void e2d::ENode::_updateOpacity(ENode * node) +{ + if (node->m_pParent) + { + node->m_fDisplayOpacity = node->m_fRealOpacity * node->m_pParent->m_fDisplayOpacity; + } + node->_updateChildrenOpacity(); +} + bool e2d::ENode::isVisiable() const { return m_bVisiable; @@ -179,7 +225,7 @@ float e2d::ENode::getRotation() const float e2d::ENode::getOpacity() const { - return m_fDisplayOpacity; + return m_fRealOpacity; } int e2d::ENode::getOrder() const @@ -207,10 +253,9 @@ void e2d::ENode::setPos(float x, float y) if (m_fPosX == x && m_fPosY == y) return; - //m_Matri.Translation(x, y); m_fPosX = x; m_fPosY = y; - m_bTransformNeeded = true; + m_bTransformChildrenNeeded = true; } void e2d::ENode::move(float x, float y) @@ -235,6 +280,7 @@ void e2d::ENode::setSize(float width, float height) m_fWidth = width; m_fHeight = height; + m_bTransformChildrenNeeded = true; } void e2d::ENode::setScaleX(float scaleX) @@ -257,10 +303,9 @@ void e2d::ENode::setScale(float scaleX, float scaleY) if (m_fScaleX == scaleX && m_fScaleY == scaleY) return; - //m_Matri.Scale(scaleX, scaleY); m_fScaleX = scaleX; m_fScaleY = scaleY; - m_bTransformNeeded = true; + m_bTransformChildrenNeeded = true; } void e2d::ENode::setSkewX(float angleX) @@ -278,10 +323,9 @@ void e2d::ENode::setSkew(float angleX, float angleY) if (m_fSkewAngleX == angleX && m_fSkewAngleY == angleY) return; - //m_Matri.Skew(angleX, angleY); m_fSkewAngleX = angleX; m_fSkewAngleY = angleY; - m_bTransformNeeded = true; + m_bTransformChildrenNeeded = true; } void e2d::ENode::setRotation(float angle) @@ -289,14 +333,38 @@ void e2d::ENode::setRotation(float angle) if (m_fRotation == angle) return; - //m_Matri.Rotation(angle); m_fRotation = angle; - m_bTransformNeeded = true; + m_bTransformChildrenNeeded = true; } void e2d::ENode::setOpacity(float opacity) { - m_fDisplayOpacity = m_fRealOpacity = opacity; + if (m_fRealOpacity == opacity) + return; + + m_fDisplayOpacity = m_fRealOpacity = min(max(opacity, 0), 1); + // 更新子节点透明度 + _updateChildrenOpacity(); +} + +void e2d::ENode::setAnchorX(float anchorX) +{ + this->setAnchor(anchorX, m_fAnchorY); +} + +void e2d::ENode::setAnchorY(float anchorY) +{ + this->setAnchor(m_fAnchorX, anchorY); +} + +void e2d::ENode::setAnchor(float anchorX, float anchorY) +{ + if (m_fAnchorX == anchorX && m_fAnchorY == anchorY) + return; + + m_fAnchorX = min(max(anchorX, 0), 1); + m_fAnchorY = min(max(anchorY, 0), 1); + m_bTransformChildrenNeeded = true; } void e2d::ENode::setParent(ENode * parent) @@ -325,13 +393,15 @@ void e2d::ENode::addChild(ENode * child, int order /* = 0 */) m_vChildren.push_back(child); - child->m_pParent = this; - child->setOrder(order); child->retain(); - m_bSortNeeded = true; + child->m_pParent = this; + + _updateOpacity(child); + + m_bSortChildrenNeeded = true; } } diff --git a/Easy2D/Node/ESprite.cpp b/Easy2D/Node/ESprite.cpp new file mode 100644 index 00000000..e284503a --- /dev/null +++ b/Easy2D/Node/ESprite.cpp @@ -0,0 +1,289 @@ +#include "..\enodes.h" +#include + +static std::map s_mBitmapsFromFile; +//static std::map s_mBitmapsFromResource; + +static ID2D1Bitmap * GetBitmapFromFile(e2d::EString fileName); +static ID2D1Bitmap * GetBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType); + +static bool _loadBitmapFromFile(e2d::EString fileName); +static bool _loadBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType); + + +e2d::ESprite::ESprite() +{ +} + +e2d::ESprite::ESprite(EString imageFileName) + : ESprite() +{ + setImage(imageFileName); +} + +e2d::ESprite::ESprite(EString resourceName, EString resourceType) + : ESprite() +{ + setImage(resourceName, resourceType); +} + +void e2d::ESprite::setImage(EString fileName) +{ + WARN_IF(fileName.empty(), "ESprite cannot load bitmap from NULL file name."); + + if (fileName.empty() || m_sFileName == fileName) + return; + + m_sFileName = fileName; + + SafeReleaseInterface(&pBitmap); + pBitmap = GetBitmapFromFile(m_sFileName); + + ASSERT(pBitmap, "ESprite create device resources failed!"); + + this->setSize(pBitmap->GetSize().width, pBitmap->GetSize().height); +} + +void e2d::ESprite::setImage(EString resourceName, EString resourceType) +{ + WARN_IF(resourceName.empty() || resourceType.empty(), "ESprite cannot load bitmap from NULL resource."); + + if (resourceName.empty() || resourceType.empty()) + return; + + if (m_sResourceName == resourceName && m_sResourceType == resourceType) + return; + + if (!m_sFileName.empty()) + m_sFileName.clear(); + + m_sResourceName = resourceName; + m_sResourceType = resourceType; + + SafeReleaseInterface(&pBitmap); + pBitmap = GetBitmapFromResource(resourceName, resourceType); + + ASSERT(pBitmap, "ESprite create device resources failed!"); + + this->setSize(pBitmap->GetSize().width, pBitmap->GetSize().height); +} + +void e2d::ESprite::_onRender() +{ + if (pBitmap) + { + // Draw bitmap + GetRenderTarget()->DrawBitmap( + pBitmap, + D2D1::RectF(0, 0, m_fWidth, m_fHeight), + m_fDisplayOpacity + ); + } +} + + + + +bool _loadBitmapFromFile(e2d::EString fileName) +{ + HRESULT hr = S_OK; + + IWICBitmapDecoder *pDecoder = nullptr; + IWICBitmapFrameDecode *pSource = nullptr; + IWICStream *pStream = nullptr; + IWICFormatConverter *pConverter = nullptr; + ID2D1Bitmap *pBitmap = nullptr; + + hr = GetImagingFactory()->CreateDecoderFromFilename( + fileName.c_str(), + NULL, + GENERIC_READ, + WICDecodeMetadataCacheOnLoad, + &pDecoder + ); + + if (SUCCEEDED(hr)) + { + // Create the initial frame. + hr = pDecoder->GetFrame(0, &pSource); + } + + if (SUCCEEDED(hr)) + { + // Convert the image format to 32bppPBGRA + // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). + hr = GetImagingFactory()->CreateFormatConverter(&pConverter); + } + if (SUCCEEDED(hr)) + { + hr = pConverter->Initialize( + pSource, + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + NULL, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + if (SUCCEEDED(hr)) + { + // Create a Direct2D bitmap from the WIC bitmap. + hr = GetRenderTarget()->CreateBitmapFromWicBitmap( + pConverter, + NULL, + &pBitmap + ); + } + if (SUCCEEDED(hr)) + { + std::hash h; + size_t hash = h(fileName); + + s_mBitmapsFromFile.insert( + std::map::value_type( + hash, + pBitmap) + ); + } + + SafeReleaseInterface(&pDecoder); + SafeReleaseInterface(&pSource); + SafeReleaseInterface(&pStream); + SafeReleaseInterface(&pConverter); + + return SUCCEEDED(hr); +} + +bool _loadBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType) +{ + HRESULT hr = S_OK; + + IWICBitmapDecoder *pDecoder = nullptr; + IWICBitmapFrameDecode *pSource = nullptr; + IWICStream *pStream = nullptr; + IWICFormatConverter *pConverter = nullptr; + IWICBitmapScaler *pScaler = nullptr; + ID2D1Bitmap *pBitmap = nullptr; + + HRSRC imageResHandle = nullptr; + HGLOBAL imageResDataHandle = nullptr; + void *pImageFile = nullptr; + DWORD imageFileSize = 0; + + // Locate the resource. + imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName.c_str(), resourceType.c_str()); + + hr = imageResHandle ? S_OK : E_FAIL; + if (SUCCEEDED(hr)) + { + // Load the resource. + imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle); + + hr = imageResDataHandle ? S_OK : E_FAIL; + } + + if (SUCCEEDED(hr)) + { + // Lock it to get a system memory pointer. + pImageFile = LockResource(imageResDataHandle); + + hr = pImageFile ? S_OK : E_FAIL; + } + + if (SUCCEEDED(hr)) + { + // Calculate the size. + imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle); + + hr = imageFileSize ? S_OK : E_FAIL; + } + + if (SUCCEEDED(hr)) + { + // Create a WIC stream to map onto the memory. + hr = GetImagingFactory()->CreateStream(&pStream); + } + + if (SUCCEEDED(hr)) + { + // Initialize the stream with the memory pointer and size. + hr = pStream->InitializeFromMemory( + reinterpret_cast(pImageFile), + imageFileSize + ); + } + + if (SUCCEEDED(hr)) + { + // Create a decoder for the stream. + hr = GetImagingFactory()->CreateDecoderFromStream( + pStream, + NULL, + WICDecodeMetadataCacheOnLoad, + &pDecoder + ); + } + + if (SUCCEEDED(hr)) + { + // Create the initial frame. + hr = pDecoder->GetFrame(0, &pSource); + } + + if (SUCCEEDED(hr)) + { + // Convert the image format to 32bppPBGRA + // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED). + hr = GetImagingFactory()->CreateFormatConverter(&pConverter); + } + + if (SUCCEEDED(hr)) + { + hr = pConverter->Initialize( + pSource, + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + NULL, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + + if (SUCCEEDED(hr)) + { + //create a Direct2D bitmap from the WIC bitmap. + hr = GetRenderTarget()->CreateBitmapFromWicBitmap( + pConverter, + NULL, + &pBitmap + ); + } + + SafeReleaseInterface(&pDecoder); + SafeReleaseInterface(&pSource); + SafeReleaseInterface(&pStream); + SafeReleaseInterface(&pConverter); + SafeReleaseInterface(&pScaler); + + return SUCCEEDED(hr); +} + +ID2D1Bitmap * GetBitmapFromFile(e2d::EString fileName) +{ + std::hash h; + size_t hash = h(fileName); + + if (s_mBitmapsFromFile.find(hash) == s_mBitmapsFromFile.end()) + { + if (!_loadBitmapFromFile(fileName)) + { + return nullptr; + } + } + return s_mBitmapsFromFile.at(hash); +} + +ID2D1Bitmap * GetBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType) +{ + return nullptr; +} \ No newline at end of file diff --git a/Easy2D/Win/winbase.cpp b/Easy2D/Win/winbase.cpp index 0773d764..60ace85c 100644 --- a/Easy2D/Win/winbase.cpp +++ b/Easy2D/Win/winbase.cpp @@ -4,6 +4,7 @@ HWND hwnd = nullptr; ID2D1Factory * pDirect2dFactory = nullptr; ID2D1HwndRenderTarget * pRenderTarget = nullptr; ID2D1SolidColorBrush * m_pSolidBrush = nullptr; +IWICImagingFactory * pIWICFactory = nullptr; HWND &GetHWnd() @@ -16,12 +17,47 @@ ID2D1Factory * &GetFactory() return pDirect2dFactory; } +IWICImagingFactory * &GetImagingFactory() +{ + if (!pIWICFactory) + { + CoCreateInstance( + CLSID_WICImagingFactory, + NULL, + CLSCTX_INPROC_SERVER, + IID_IWICImagingFactory, + reinterpret_cast(&pIWICFactory) + ); + } + return pIWICFactory; +} + ID2D1HwndRenderTarget * &GetRenderTarget() { + if (!pRenderTarget) + { + RECT rc; + GetClientRect(hwnd, &rc); + + D2D1_SIZE_U size = D2D1::SizeU( + rc.right - rc.left, + rc.bottom - rc.top + ); + + // Create a Direct2D render target. + HRESULT hr; + hr = pDirect2dFactory->CreateHwndRenderTarget( + D2D1::RenderTargetProperties(), + D2D1::HwndRenderTargetProperties(hwnd, size), + &pRenderTarget + ); + + ASSERT(SUCCEEDED(hr), "Create Render Target Failed!"); + } return pRenderTarget; } -ID2D1SolidColorBrush *& GetSolidColorBrush() +ID2D1SolidColorBrush * &GetSolidColorBrush() { if (!m_pSolidBrush) { diff --git a/Easy2D/Win/winbase.h b/Easy2D/Win/winbase.h index 1500d3ae..5185704f 100644 --- a/Easy2D/Win/winbase.h +++ b/Easy2D/Win/winbase.h @@ -6,7 +6,14 @@ #include #pragma comment(lib, "d2d1.lib") #pragma comment(lib, "dwrite.lib") -//#pragma comment(lib, "wincodec.lib") +#pragma comment(lib, "windowscodecs.lib") + + +#ifndef HINST_THISCOMPONENT +EXTERN_C IMAGE_DOS_HEADER __ImageBase; +#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) +#endif + HWND &GetHWnd(); @@ -16,6 +23,7 @@ ID2D1HwndRenderTarget * &GetRenderTarget(); ID2D1SolidColorBrush * &GetSolidColorBrush(); +IWICImagingFactory * &GetImagingFactory(); template inline void SafeReleaseInterface( diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h index c6526bcc..db301a82 100644 --- a/Easy2D/ebase.h +++ b/Easy2D/ebase.h @@ -212,6 +212,12 @@ protected: // 子节点排序 void _sortChildren(); + // 进入场景时需调用该函数 + virtual void _onEnter(); + + // 退出场景时需调用该函数 + virtual void _onExit(); + protected: bool m_bSortNeeded; bool m_bWillSave; diff --git a/Easy2D/ecommon.h b/Easy2D/ecommon.h index 9c2a306d..1d226fd5 100644 --- a/Easy2D/ecommon.h +++ b/Easy2D/ecommon.h @@ -26,6 +26,8 @@ typedef struct typedef std::function KEY_LISTENER_CALLBACK; typedef std::function MOUSE_LISTENER_CALLBACK; typedef std::function MOUSE_CLICK_LISTENER_CALLBACK; +typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK; +typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK; typedef std::function MOUSE_DRAG_LISTENER_CALLBACK; diff --git a/Easy2D/emacros.h b/Easy2D/emacros.h index 26073f69..8d86d282 100644 --- a/Easy2D/emacros.h +++ b/Easy2D/emacros.h @@ -22,6 +22,11 @@ #include #include +// C RunTime Header Files +#include +#include +#include + #ifndef ASSERT_IF #if defined( DEBUG ) || defined( _DEBUG ) diff --git a/Easy2D/emsg.h b/Easy2D/emsg.h index bc5554a8..59cbee0b 100644 --- a/Easy2D/emsg.h +++ b/Easy2D/emsg.h @@ -244,6 +244,39 @@ protected: }; +// 鼠标按下消息监听器 +class EMousePressListener : + public EMouseListener +{ +public: + EMousePressListener(); + + EMousePressListener( + EString name + ); + + EMousePressListener( + const MOUSE_PRESS_LISTENER_CALLBACK &callback + ); + + EMousePressListener( + EString name, + const MOUSE_PRESS_LISTENER_CALLBACK &callback + ); + + // 执行监听器回调函数 + virtual void runCallback() override; + + // 设置监听器回调函数 + void setCallback( + const MOUSE_PRESS_LISTENER_CALLBACK &callback + ); + +protected: + MOUSE_PRESS_LISTENER_CALLBACK m_callback; +}; + + // 鼠标点击消息监听器 class EMouseClickListener : public EMouseListener @@ -273,26 +306,61 @@ public: ); protected: + bool m_bPressed; MOUSE_CLICK_LISTENER_CALLBACK m_callback; }; -// 鼠标拖动消息监听器 -class EMouseDraggedListener : +// 鼠标点击消息监听器 +class EMouseDoubleClickListener : public EMouseListener { public: - EMouseDraggedListener(); + EMouseDoubleClickListener(); - EMouseDraggedListener( + EMouseDoubleClickListener( EString name ); - EMouseDraggedListener( + EMouseDoubleClickListener( + const MOUSE_DBLCLK_LISTENER_CALLBACK &callback + ); + + EMouseDoubleClickListener( + EString name, + const MOUSE_DBLCLK_LISTENER_CALLBACK &callback + ); + + // 执行监听器回调函数 + virtual void runCallback() override; + + // 设置监听器回调函数 + void setCallback( + const MOUSE_DBLCLK_LISTENER_CALLBACK &callback + ); + +protected: + bool m_bPressed; + MOUSE_DBLCLK_LISTENER_CALLBACK m_callback; +}; + + +// 鼠标拖动消息监听器 +class EMouseDragListener : + public EMouseListener +{ +public: + EMouseDragListener(); + + EMouseDragListener( + EString name + ); + + EMouseDragListener( const MOUSE_DRAG_LISTENER_CALLBACK &callback ); - EMouseDraggedListener( + EMouseDragListener( EString name, const MOUSE_DRAG_LISTENER_CALLBACK &callback ); @@ -306,8 +374,7 @@ public: ); protected: - EPoint m_Begin; - EPoint m_End; + EPoint m_Begin; MOUSE_DRAG_LISTENER_CALLBACK m_callback; }; diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index eb50fb6f..40483a3e 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -8,6 +8,8 @@ namespace e2d class ENode : public EObject { + friend EScene; + public: ENode(); @@ -35,10 +37,10 @@ public: // 获取节点高度 virtual float getHeight() const; - // 获取节点横向缩放倍数 + // 获取节点横向缩放比例 virtual float getScaleX() const; - // 获取节点纵向缩放倍数 + // 获取节点纵向缩放比例 virtual float getScaleY() const; // 获取节点横向倾斜角度 @@ -125,57 +127,86 @@ public: ); // 设置节点绘图顺序 + // 默认为 0 virtual void setOrder( int order ); - // 设置横向缩放 + // 设置横向缩放比例 + // 默认为 1.0f virtual void setScaleX( float scaleX ); - // 设置纵向缩放 + // 设置纵向缩放比例 + // 默认为 1.0f virtual void setScaleY( float scaleY ); - // 设置缩放 + // 设置缩放比例 + // 默认为 (1.0f, 1.0f) virtual void setScale( float scaleX, float scaleY ); - // 设置缩放 + // 设置缩放比例 + // 默认为 1.0f virtual void setScale( float scale ); // 设置横向倾斜角度 + // 默认为 0 virtual void setSkewX( float angleX ); // 设置纵向倾斜角度 + // 默认为 0 virtual void setSkewY( float angleY ); // 设置倾斜角度 + // 默认为 (0, 0) virtual void setSkew( float angleX, float angleY ); // 设置旋转角度 + // 默认为 0 virtual void setRotation( float rotation ); // 设置透明度 + // 默认为 1.0f, 范围 [0, 1] virtual void setOpacity( float opacity ); + // 设置纵向锚点 + // 默认为 0, 范围 [0, 1] + virtual void setAnchorX( + float anchorX + ); + + // 设置横向锚点 + // 默认为 0, 范围 [0, 1] + virtual void setAnchorY( + float anchorY + ); + + // 设置锚点 + // 默认为 (0, 0), 范围 [0, 1] + virtual void setAnchor( + float anchorX, + float anchorY + ); + // 设置节点所在场景 virtual void setParentScene( EScene * scene @@ -209,18 +240,30 @@ public: bool release = false ); - // 访问节点 - virtual void callOn(); - protected: + // 访问节点 + virtual void _callOn(); + // 渲染节点 virtual void _onRender(); // 子节点排序 void _sortChildren(); - // 节点状态转换 - void _transfrom(); + // 只考虑自身进行二维矩阵变换 + void _updateTransformToReal(); + + // 更新所有子节点矩阵 + void _updateChildrenTransform(); + + // 更新所有子节点透明度 + void _updateChildrenOpacity(); + + // 更新节点矩阵 + static void _updateTransform(ENode * node); + + // 更新节点透明度 + static void _updateOpacity(ENode * node); protected: EString m_sName; @@ -236,11 +279,13 @@ protected: float m_fSkewAngleY; float m_fDisplayOpacity; float m_fRealOpacity; + float m_fAnchorX; + float m_fAnchorY; D2D1::Matrix3x2F m_Matri; int m_nOrder; bool m_bVisiable; - bool m_bSortNeeded; - bool m_bTransformNeeded; + bool m_bSortChildrenNeeded; + bool m_bTransformChildrenNeeded; EScene * m_pParentScene; ENode * m_pParent; std::vector m_vChildren; @@ -264,4 +309,29 @@ protected: EColor::Enum m_Color; }; + +class ESprite : + public ENode +{ +public: + ESprite(); + + ESprite(EString imageFileName); + + ESprite(EString resourceName, EString resourceType); + + void setImage(EString fileName); + + void setImage(EString resourceName, EString resourceType); + +protected: + virtual void _onRender() override; + +protected: + EString m_sFileName; + EString m_sResourceName; + EString m_sResourceType; + ID2D1Bitmap * pBitmap; +}; + } \ No newline at end of file