diff --git a/Demo/main.cpp b/Demo/main.cpp index 9d44fbba..4dee944b 100644 --- a/Demo/main.cpp +++ b/Demo/main.cpp @@ -24,8 +24,8 @@ int WINAPI WinMain( node2->setSize(40, 40); node->addChild(node2); - auto mlistener = new EMouseClickListener([](EPoint) { - EApp::getCurrentScene()->getChild(L"node1")->setPos(EMouseMsg::getPos()); + auto mlistener = new EMouseClickListener([](EPoint p) { + EApp::getCurrentScene()->getChild(L"node1")->setPos(p.x, p.y); }); mlistener->bindWith(node); diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index 9e746923..c3aa9232 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -43,43 +43,40 @@ bool e2d::EApp::init(e2d::EString title, e2d::ESize size, bool bShowConsole /* = { return init(title, size.cx, size.cy, bShowConsole); } -#include + bool e2d::EApp::init(e2d::EString title, UINT32 width, UINT32 height, bool bShowConsole /* = false */) { HRESULT hr; - hr = CoInitialize(NULL); + CoInitialize(NULL); - if (SUCCEEDED(hr)) + // 关闭控制台 + if (bShowConsole) { - // 关闭控制台 - if (bShowConsole) + // 查找是否已经存在控制台 + if (!GetConsoleWindow()) { - // 查找是否已经存在控制台 - if (!GetConsoleWindow()) + // 显示一个新控制台 + if (AllocConsole()) { - // 显示一个新控制台 - if (AllocConsole()) - { - FILE *stream; - freopen_s(&stream, "CONOUT$", "w+t", stdout); - freopen_s(&stream, "CONOUT$", "w+t", stderr); - freopen_s(&stream, "CONIN$", "r+t", stdin); - } - else - { - MessageBox(nullptr, L"Alloc Console Failed!", L"Error", MB_OK); - } + FILE *stream; + freopen_s(&stream, "CONOUT$", "w+t", stdout); + freopen_s(&stream, "CONOUT$", "w+t", stderr); + freopen_s(&stream, "CONIN$", "r+t", stdin); + } + else + { + MessageBox(nullptr, L"Alloc Console Failed!", L"Error", MB_OK); } } - else - { - FreeConsole(); - } - - // 初始化 device-indpendent 资源 - // 比如 Direct2D factory. - hr = _createDeviceIndependentResources(); } + else + { + FreeConsole(); + } + + // 初始化 device-indpendent 资源 + // 比如 Direct2D factory. + hr = _createDeviceIndependentResources(); if (SUCCEEDED(hr)) { @@ -194,6 +191,8 @@ void e2d::EApp::run() _onControl(); // 释放所有内存占用 free(); + + CoUninitialize(); } void e2d::EApp::_mainLoop() @@ -262,8 +261,6 @@ void e2d::EApp::_onRender() { GetRenderTarget()->BeginDraw(); - GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); - GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor)); m_pCurrentScene->_onRender(); // 绘制当前场景 diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index 03dc47ed..c71c99a9 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -18,6 +18,8 @@ void e2d::EScene::_onRender() { this->_sortChildren(); + GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + // 访问所有节点 for (auto child : m_vChildren) { diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index ffe10e75..d16493bb 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -4,6 +4,18 @@ e2d::ENode::ENode() : m_nOrder(0) + , m_fPosX(0) + , m_fPosY(0) + , m_fWidth(0) + , m_fHeight(0) + , m_fScaleX(1) + , m_fScaleY(1) + , m_fRotation(0) + , m_fSkewAngleX(0) + , m_fSkewAngleY(0) + , m_fDisplayOpacity(1) + , m_fRealOpacity(1) + , m_Matri(D2D1::Matrix3x2F::Identity()) , m_bVisiable(true) , m_pParent(nullptr) , m_pParentScene(nullptr) @@ -52,6 +64,7 @@ void e2d::ENode::callOn() } } + GetRenderTarget()->SetTransform(m_Matri); // 渲染自身 this->_onRender(); @@ -61,6 +74,7 @@ void e2d::ENode::callOn() } else { + GetRenderTarget()->SetTransform(m_Matri); // 渲染自身 this->_onRender(); } @@ -70,10 +84,6 @@ void e2d::ENode::_onRender() { } -void e2d::ENode::_onTransfrom() -{ -} - void e2d::ENode::_sortChildren() { if (m_bSortNeeded) @@ -95,15 +105,18 @@ void e2d::ENode::_transfrom() { if (m_bTransformNeeded) { - // 更新自身属性 + // 二维矩形变换 + 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) { - this->setPos(m_pParent->getX() + m_Pos.x, m_pParent->getY() + m_Pos.y); + //m_Matri.SetProduct() } - // 根据子节点特殊性进行更新 - _onTransfrom(); - // 提示子节点更新属性 for (const auto &child : m_vChildren) { @@ -119,115 +132,54 @@ bool e2d::ENode::isVisiable() const return m_bVisiable; } -int e2d::ENode::getX() const +float e2d::ENode::getX() const { - return m_Rect.TopLeft().x; + return m_fPosX; } -int e2d::ENode::getY() const +float e2d::ENode::getY() const { - return m_Rect.TopLeft().y; + return m_fPosY; } -CPoint e2d::ENode::getPos() const +float e2d::ENode::getWidth() const { - return m_Rect.TopLeft(); + return m_fWidth; } -UINT32 e2d::ENode::getWidth() const +float e2d::ENode::getHeight() const { - return UINT32(m_Rect.Size().cx); + return m_fHeight; } -UINT32 e2d::ENode::getHeight() const +float e2d::ENode::getScaleX() const { - return UINT32(m_Rect.Size().cy); + return m_fScaleX; } -e2d::ESize e2d::ENode::getSize() const +float e2d::ENode::getScaleY() const { - return e2d::ESize(m_Rect.Size()); + return m_fScaleY; } -e2d::ERect e2d::ENode::getRect() const +float e2d::ENode::getSkewX() const { - return e2d::ERect(m_Rect); + return m_fSkewAngleX; } -void e2d::ENode::setX(int x) +float e2d::ENode::getSkewY() const { - this->setPos(x, m_Rect.TopLeft().y); + return m_fSkewAngleY; } -void e2d::ENode::setY(int y) +float e2d::ENode::getRotation() const { - this->setPos(m_Rect.TopLeft().x, y); + return m_fRotation; } -void e2d::ENode::setPos(EPoint p) +float e2d::ENode::getOpacity() const { - this->setPos(p.x, p.y); -} - -void e2d::ENode::setPos(int x, int y) -{ - if (getX() == x && getY() == y) - return; - - if (!m_bTransformNeeded) - { - m_Pos.x = x; - m_Pos.y = y; - m_bTransformNeeded = true; - } - m_Rect.MoveToXY(x, y); -} - -void e2d::ENode::move(int x, int y) -{ - m_Rect.OffsetRect(x, y); -} - -void e2d::ENode::move(EVector v) -{ - m_Rect.OffsetRect(v); -} - -void e2d::ENode::setWidth(UINT32 width) -{ - m_Rect.BottomRight().x = m_Rect.TopLeft().x + width; -} - -void e2d::ENode::setHeight(UINT32 height) -{ - m_Rect.BottomRight().y = m_Rect.TopLeft().y + height; -} - -void e2d::ENode::setSize(UINT32 width, UINT32 height) -{ - m_Rect.BottomRight().x = m_Rect.TopLeft().x + width; - m_Rect.BottomRight().y = m_Rect.TopLeft().y + height; -} - -void e2d::ENode::setSize(ESize size) -{ - this->setSize(size.cx, size.cy); -} - -void e2d::ENode::setRect(int x1, int y1, int x2, int y2) -{ - m_Rect.SetRect(x1, y1, x2, y2); -} - -void e2d::ENode::setRect(EPoint leftTop, EPoint rightBottom) -{ - m_Rect.TopLeft() = leftTop; - m_Rect.BottomRight() = rightBottom; -} - -void e2d::ENode::setRect(ERect rect) -{ - m_Rect = rect; + return m_fDisplayOpacity; } int e2d::ENode::getOrder() const @@ -240,6 +192,113 @@ void e2d::ENode::setOrder(int order) m_nOrder = order; } +void e2d::ENode::setX(float x) +{ + this->setPos(x, m_fPosY); +} + +void e2d::ENode::setY(float y) +{ + this->setPos(m_fPosX, y); +} + +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; +} + +void e2d::ENode::move(float x, float y) +{ + this->setPos(m_fPosX + x, m_fPosY + y); +} + +void e2d::ENode::setWidth(float width) +{ + this->setSize(width, m_fHeight); +} + +void e2d::ENode::setHeight(float height) +{ + this->setSize(m_fWidth, height); +} + +void e2d::ENode::setSize(float width, float height) +{ + if (m_fWidth == width && m_fHeight == height) + return; + + m_fWidth = width; + m_fHeight = height; +} + +void e2d::ENode::setScaleX(float scaleX) +{ + this->setScale(scaleX, m_fScaleY); +} + +void e2d::ENode::setScaleY(float scaleY) +{ + this->setScale(m_fScaleX, scaleY); +} + +void e2d::ENode::setScale(float scale) +{ + this->setScale(scale, scale); +} + +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; +} + +void e2d::ENode::setSkewX(float angleX) +{ + this->setSkew(angleX, m_fSkewAngleY); +} + +void e2d::ENode::setSkewY(float angleY) +{ + this->setSkew(m_fSkewAngleX, angleY); +} + +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; +} + +void e2d::ENode::setRotation(float angle) +{ + if (m_fRotation == angle) + return; + + //m_Matri.Rotation(angle); + m_fRotation = angle; + m_bTransformNeeded = true; +} + +void e2d::ENode::setOpacity(float opacity) +{ + m_fDisplayOpacity = m_fRealOpacity = opacity; +} + void e2d::ENode::setParent(ENode * parent) { if (m_pParent) diff --git a/Easy2D/Node/ERectangle.cpp b/Easy2D/Node/ERectangle.cpp index 64239f12..4e302905 100644 --- a/Easy2D/Node/ERectangle.cpp +++ b/Easy2D/Node/ERectangle.cpp @@ -2,18 +2,23 @@ #include "..\Win\winbase.h" -void e2d::ERectangle::_onRender() +e2d::ERectangle::ERectangle() { - static D2D1_RECT_F rectangle = D2D1::RectF( - m_Rect.left, - m_Rect.top, - m_Rect.right, - m_Rect.bottom - ); - GetRenderTarget()->FillRectangle(&rectangle, GetSolidColorBrush(D2D1::ColorF(D2D1::ColorF::LightSlateGray))); } -void e2d::ERectangle::_onTransfrom() +e2d::EColor::Enum e2d::ERectangle::getColor() const { - + return m_Color; +} + +void e2d::ERectangle::setColor(EColor::Enum color) +{ + m_Color = color; +} + +void e2d::ERectangle::_onRender() +{ + D2D1_RECT_F rectangle = D2D1::RectF(0, 0, m_fWidth, m_fHeight); + GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color, m_fDisplayOpacity)); + GetRenderTarget()->FillRectangle(&rectangle, GetSolidColorBrush()); } diff --git a/Easy2D/Win/winbase.cpp b/Easy2D/Win/winbase.cpp index 705429a8..0773d764 100644 --- a/Easy2D/Win/winbase.cpp +++ b/Easy2D/Win/winbase.cpp @@ -1,5 +1,4 @@ #include "winbase.h" -#include "..\emacros.h" HWND hwnd = nullptr; ID2D1Factory * pDirect2dFactory = nullptr; @@ -22,9 +21,12 @@ ID2D1HwndRenderTarget * &GetRenderTarget() return pRenderTarget; } -ID2D1SolidColorBrush *& GetSolidColorBrush(D2D1_COLOR_F & color) +ID2D1SolidColorBrush *& GetSolidColorBrush() { - pRenderTarget->CreateSolidColorBrush(color, &m_pSolidBrush); + if (!m_pSolidBrush) + { + pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &m_pSolidBrush); + } return m_pSolidBrush; } diff --git a/Easy2D/Win/winbase.h b/Easy2D/Win/winbase.h index be5cfbe2..1500d3ae 100644 --- a/Easy2D/Win/winbase.h +++ b/Easy2D/Win/winbase.h @@ -5,6 +5,8 @@ #include #include #pragma comment(lib, "d2d1.lib") +#pragma comment(lib, "dwrite.lib") +//#pragma comment(lib, "wincodec.lib") HWND &GetHWnd(); @@ -12,7 +14,7 @@ ID2D1Factory * &GetFactory(); ID2D1HwndRenderTarget * &GetRenderTarget(); -ID2D1SolidColorBrush * &GetSolidColorBrush(D2D1_COLOR_F &color); +ID2D1SolidColorBrush * &GetSolidColorBrush(); template diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index 7376842e..eb50fb6f 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -1,5 +1,6 @@ #pragma once #include "ebase.h" +#include "Win\winbase.h" namespace e2d { @@ -23,25 +24,34 @@ public: virtual int getOrder() const; // 获取节点横坐标 - virtual int getX() const; + virtual float getX() const; // 获取节点纵坐标 - virtual int getY() const; - - // 获取节点坐标 - virtual EPoint getPos() const; + virtual float getY() const; // 获取节点宽度 - virtual UINT32 getWidth() const; + virtual float getWidth() const; // 获取节点高度 - virtual UINT32 getHeight() const; + virtual float getHeight() const; - // 获取节点大小 - virtual ESize getSize() const; + // 获取节点横向缩放倍数 + virtual float getScaleX() const; - // 获取节点所在的矩形 - virtual ERect getRect() const; + // 获取节点纵向缩放倍数 + virtual float getScaleY() const; + + // 获取节点横向倾斜角度 + virtual float getSkewX() const; + + // 获取节点纵向倾斜角度 + virtual float getSkewY() const; + + // 获取节点旋转角度 + virtual float getRotation() const; + + // 获取节点透明度 + virtual float getOpacity() const; // 获取父节点 virtual ENode * getParent() const; @@ -78,74 +88,40 @@ public: // 设置节点横坐标 virtual void setX( - int x + float x ); // 设置节点纵坐标 virtual void setY( - int y + float y ); // 设置节点坐标 virtual void setPos( - int x, - int y - ); - - // 设置节点坐标 - virtual void setPos( - EPoint p + float x, + float y ); // 移动节点 virtual void move( - int x, - int y - ); - - // 移动节点 - virtual void move( - EVector v + float x, + float y ); // 设置节点宽度 virtual void setWidth( - UINT32 width + float width ); // 设置节点高度 virtual void setHeight( - UINT32 height + float height ); // 设置节点大小 virtual void setSize( - UINT32 width, - UINT32 height - ); - - // 设置节点大小 - virtual void setSize( - ESize size - ); - - // 设置节点所在的矩形 - virtual void setRect( - int x1, - int y1, - int x2, - int y2 - ); - - // 设置节点所在的矩形 - virtual void setRect( - EPoint leftTop, - EPoint rightBottom - ); - - // 设置节点所在的矩形 - virtual void setRect( - ERect rect + float width, + float height ); // 设置节点绘图顺序 @@ -153,6 +129,53 @@ public: int order ); + // 设置横向缩放 + virtual void setScaleX( + float scaleX + ); + + // 设置纵向缩放 + virtual void setScaleY( + float scaleY + ); + + // 设置缩放 + virtual void setScale( + float scaleX, + float scaleY + ); + + // 设置缩放 + virtual void setScale( + float scale + ); + + // 设置横向倾斜角度 + virtual void setSkewX( + float angleX + ); + + // 设置纵向倾斜角度 + virtual void setSkewY( + float angleY + ); + + // 设置倾斜角度 + virtual void setSkew( + float angleX, + float angleY + ); + + // 设置旋转角度 + virtual void setRotation( + float rotation + ); + + // 设置透明度 + virtual void setOpacity( + float opacity + ); + // 设置节点所在场景 virtual void setParentScene( EScene * scene @@ -193,9 +216,6 @@ protected: // 渲染节点 virtual void _onRender(); - // 节点状态转换 - virtual void _onTransfrom(); - // 子节点排序 void _sortChildren(); @@ -205,12 +225,22 @@ protected: protected: EString m_sName; size_t m_nHashName; + float m_fPosX; + float m_fPosY; + float m_fWidth; + float m_fHeight; + float m_fScaleX; + float m_fScaleY; + float m_fRotation; + float m_fSkewAngleX; + float m_fSkewAngleY; + float m_fDisplayOpacity; + float m_fRealOpacity; + D2D1::Matrix3x2F m_Matri; int m_nOrder; bool m_bVisiable; bool m_bSortNeeded; bool m_bTransformNeeded; - ERect m_Rect; - EPoint m_Pos; EScene * m_pParentScene; ENode * m_pParent; std::vector m_vChildren; @@ -220,10 +250,18 @@ protected: class ERectangle : public ENode { +public: + ERectangle(); + + EColor::Enum getColor() const; + + void setColor(EColor::Enum color); + protected: virtual void _onRender() override; - virtual void _onTransfrom() override; +protected: + EColor::Enum m_Color; }; } \ No newline at end of file