更新ENode矩形变换,增加按下和双击鼠标消息监听器

This commit is contained in:
Nomango 2017-10-15 23:58:39 +08:00
parent 1e24823452
commit 05bcd762e0
20 changed files with 811 additions and 156 deletions

View File

@ -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();
}

BIN
Demo/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -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<e2d::EScene*> 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

View File

@ -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)
{

View File

@ -200,10 +200,13 @@
<ClCompile Include="Msg\Listener\EKeyPressListener.cpp" />
<ClCompile Include="Msg\Listener\EListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseClickListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseDraggedListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseDoubleClickListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseDragListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseListener.cpp" />
<ClCompile Include="Msg\Listener\EMousePressListener.cpp" />
<ClCompile Include="Node\ENode.cpp" />
<ClCompile Include="Node\ERectangle.cpp" />
<ClCompile Include="Node\ESprite.cpp" />
<ClCompile Include="Tool\EObjectManager.cpp" />
<ClCompile Include="Tool\ETimerManager.cpp" />
<ClCompile Include="Win\winbase.cpp" />

View File

@ -48,9 +48,6 @@
<ClCompile Include="Msg\Listener\EMouseClickListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseDraggedListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
@ -66,6 +63,18 @@
<ClCompile Include="Node\ERectangle.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Node\ESprite.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMousePressListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseDoubleClickListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseDragListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Win\winbase.h">

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

289
Easy2D/Node/ESprite.cpp Normal file
View File

@ -0,0 +1,289 @@
#include "..\enodes.h"
#include <map>
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
//static std::map<size_t, size_t, ID2D1Bitmap*> 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<e2d::EString> h;
size_t hash = h(fileName);
s_mBitmapsFromFile.insert(
std::map<size_t, ID2D1Bitmap*>::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<BYTE*>(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<e2d::EString> 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;
}

View File

@ -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<void **>(&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)
{

View File

@ -6,7 +6,14 @@
#include <wincodec.h>
#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<class Interface>
inline void SafeReleaseInterface(

View File

@ -212,6 +212,12 @@ protected:
// 子节点排序
void _sortChildren();
// 进入场景时需调用该函数
virtual void _onEnter();
// 退出场景时需调用该函数
virtual void _onExit();
protected:
bool m_bSortNeeded;
bool m_bWillSave;

View File

@ -26,6 +26,8 @@ typedef struct
typedef std::function<void()> KEY_LISTENER_CALLBACK;
typedef std::function<void()> MOUSE_LISTENER_CALLBACK;
typedef std::function<void(EPoint mousePos)> 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<void(EPoint begin, EPoint end)> MOUSE_DRAG_LISTENER_CALLBACK;

View File

@ -22,6 +22,11 @@
#include <windows.h>
#include <assert.h>
// C RunTime Header Files
#include <wchar.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef ASSERT_IF
#if defined( DEBUG ) || defined( _DEBUG )

View File

@ -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;
};

View File

@ -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<ENode*> 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;
};
}