新增ETexture、EFont、EText,删除了ERactangle

This commit is contained in:
Nomango 2017-10-18 22:13:20 +08:00
parent ecc1cbffce
commit 59e4004294
18 changed files with 1162 additions and 716 deletions

View File

@ -10,7 +10,7 @@ int main()
auto node = new ENode(); auto node = new ENode();
node->setPos(50, 80); node->setPos(50, 80);
node->setSize(30, 180); node->_setSize(30, 180);
scene->add(node); scene->add(node);
/*auto listener = new EMouseListener([=] { /*auto listener = new EMouseListener([=] {

View File

@ -14,25 +14,16 @@ int WINAPI WinMain(
{ {
auto scene = new EScene(); auto scene = new EScene();
auto sprite = new ESprite(L"test.png"); auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", EColor::WHITE, L"Microsoft Yahei");
sprite->setAnchor(0.5f, 0.5f); text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
sprite->setPos(EApp::getWidth() / 2, sprite->getHeight() / 2); //text->setWordWrapping(true);
//text->setWordWrappingWidth(130);
text->setRotation(40);
text->getFont()->setItalic(true);
text->setAnchor(0.5f, 0.5f);
text->setColor(EColor::WHITE);
scene->add(text);
auto sprite2 = new ESprite(L"test.png");
sprite2->setPos(30, 0);
sprite2->setScale(0.5);
sprite2->setRotation(45);
sprite->addChild(sprite2);
auto mlistener = new EMouseDoubleClickListener([=](EPoint p) {
//sprite->setRotation(sprite->getRotation() + 10);
EApp::setWindowSize(640, 480);
});
mlistener->bindWith(sprite);
scene->add(sprite);
app.enterScene(scene); app.enterScene(scene);
app.run(); app.run();
} }

View File

@ -13,16 +13,16 @@ using namespace std::chrono;
// 唯一实例指针 // 唯一实例指针
e2d::EApp * s_pInstance = nullptr; static e2d::EApp * s_pInstance = nullptr;
// 场景栈 // 场景栈
std::stack<e2d::EScene*> s_SceneStack; static std::stack<e2d::EScene*> s_SceneStack;
// 游戏开始时间 // 游戏开始时间
static steady_clock::time_point s_tStart; static steady_clock::time_point s_tStart;
e2d::EApp::EApp() e2d::EApp::EApp()
: m_bRunning(false) : m_bRunning(false)
, nAnimationInterval(17LL) , nAnimationInterval(17LL)
, m_ClearColor(EColor::Black) , m_ClearColor(EColor::BLACK)
, m_pCurrentScene(nullptr) , m_pCurrentScene(nullptr)
, m_pNextScene(nullptr) , m_pNextScene(nullptr)
{ {
@ -91,8 +91,12 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind
height = static_cast<UINT>(ceil(height * dpiY / 96.f)); height = static_cast<UINT>(ceil(height * dpiY / 96.f));
// 获取屏幕分辨率 // 获取屏幕分辨率
int screenWidth = GetSystemMetrics(SM_CXSCREEN); UINT screenWidth = static_cast<UINT>(GetSystemMetrics(SM_CXSCREEN));
int screenHeight = GetSystemMetrics(SM_CYSCREEN); UINT screenHeight = static_cast<UINT>(GetSystemMetrics(SM_CYSCREEN));
// 当输入的窗口大小比分辨率大时,给出警告
WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!");
width = min(width, screenWidth);
height = min(height, screenHeight);
// 创建屏幕居中的矩形 // 创建屏幕居中的矩形
RECT rtWindow; RECT rtWindow;
rtWindow.left = (screenWidth - width) / 2; rtWindow.left = (screenWidth - width) / 2;
@ -230,8 +234,9 @@ void e2d::EApp::onActivate()
{ {
} }
void e2d::EApp::onInactive() bool e2d::EApp::onInactive()
{ {
return true;
} }
bool e2d::EApp::onCloseWindow() bool e2d::EApp::onCloseWindow()
@ -310,7 +315,7 @@ bool e2d::EApp::_onRender()
{ {
GetRenderTarget()->BeginDraw(); GetRenderTarget()->BeginDraw();
// 使用背景色清空屏幕 // 使用背景色清空屏幕
GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor)); GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor.value));
// 绘制当前场景 // 绘制当前场景
m_pCurrentScene->_onRender(); m_pCurrentScene->_onRender();
@ -480,7 +485,7 @@ void e2d::EApp::free()
s_SceneStack.pop(); s_SceneStack.pop();
} }
// 删除图片缓存 // 删除图片缓存
ESprite::clearCache(); ETexture::clearCache();
// 删除所有对象 // 删除所有对象
EObjectManager::clearAllObjects(); EObjectManager::clearAllObjects();
} }
@ -671,9 +676,11 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
{ {
if (LOWORD(wParam) == WA_INACTIVE) if (LOWORD(wParam) == WA_INACTIVE)
{ {
pEApp->getCurrentScene()->onInactive(); if (pEApp->getCurrentScene()->onInactive() &&
pEApp->onInactive(); pEApp->onInactive())
pEApp->m_bPaused = true; {
pEApp->m_bPaused = true;
}
} }
else else
{ {

View File

@ -30,8 +30,9 @@ void e2d::EScene::onActivate()
{ {
} }
void e2d::EScene::onInactive() bool e2d::EScene::onInactive()
{ {
return true;
} }
bool e2d::EScene::onCloseWindow() bool e2d::EScene::onCloseWindow()

View File

@ -206,9 +206,10 @@
<ClCompile Include="Msg\Listener\EMouseListener.cpp" /> <ClCompile Include="Msg\Listener\EMouseListener.cpp" />
<ClCompile Include="Msg\Listener\EMousePressListener.cpp" /> <ClCompile Include="Msg\Listener\EMousePressListener.cpp" />
<ClCompile Include="Node\ENode.cpp" /> <ClCompile Include="Node\ENode.cpp" />
<ClCompile Include="Node\ERectangle.cpp" />
<ClCompile Include="Node\ESprite.cpp" /> <ClCompile Include="Node\ESprite.cpp" />
<ClCompile Include="Node\EText.cpp" /> <ClCompile Include="Node\EText.cpp" />
<ClCompile Include="Node\EFont.cpp" />
<ClCompile Include="Node\ETexture.cpp" />
<ClCompile Include="Tool\EObjectManager.cpp" /> <ClCompile Include="Tool\EObjectManager.cpp" />
<ClCompile Include="Tool\ETimerManager.cpp" /> <ClCompile Include="Tool\ETimerManager.cpp" />
<ClCompile Include="Win\winbase.cpp" /> <ClCompile Include="Win\winbase.cpp" />

View File

@ -54,9 +54,6 @@
<ClCompile Include="Tool\ETimerManager.cpp"> <ClCompile Include="Tool\ETimerManager.cpp">
<Filter>Tool</Filter> <Filter>Tool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Node\ERectangle.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Node\ESprite.cpp"> <ClCompile Include="Node\ESprite.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>
@ -81,6 +78,12 @@
<ClCompile Include="Node\EText.cpp"> <ClCompile Include="Node\EText.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Node\EFont.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Node\ETexture.cpp">
<Filter>Node</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Win\winbase.h"> <ClInclude Include="Win\winbase.h">

91
Easy2D/Node/EFont.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::EFont::EFont()
: m_pTextFormat(nullptr)
, m_fFontSize(22)
, m_FontWeight(EFontWeight::REGULAR)
, m_bItalic(false)
, m_bRecreateNeeded(true)
{
}
e2d::EFont::EFont(EString fontFamily, float fontSize, EFontWeight fontWeight, bool italic)
{
this->setFamily(fontFamily);
this->setSize(fontSize);
this->setWeight(fontWeight);
this->setItalic(italic);
}
e2d::EFont::~EFont()
{
SafeReleaseInterface(&m_pTextFormat);
}
float e2d::EFont::getFontSize() const
{
return m_fFontSize;
}
e2d::EFontWeight e2d::EFont::getFontWeight() const
{
return m_FontWeight;
}
bool e2d::EFont::isItalic() const
{
return m_bItalic;
}
void e2d::EFont::setFamily(EString fontFamily)
{
m_sFontFamily = fontFamily;
m_bRecreateNeeded = true;
}
void e2d::EFont::setSize(float fontSize)
{
m_fFontSize = fontSize;
m_bRecreateNeeded = true;
}
void e2d::EFont::setWeight(EFontWeight fontWeight)
{
m_FontWeight = fontWeight;
m_bRecreateNeeded = true;
}
void e2d::EFont::setItalic(bool value)
{
m_bItalic = value;
m_bRecreateNeeded = true;
}
void e2d::EFont::_initTextFormat()
{
SafeReleaseInterface(&m_pTextFormat);
HRESULT hr = GetDirectWriteFactory()->CreateTextFormat(
m_sFontFamily.c_str(),
NULL, // Font collection(NULL sets it to the system font collection)
DWRITE_FONT_WEIGHT(m_FontWeight.value),
m_bItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
m_fFontSize,
L"en-us", // Local
&m_pTextFormat
);
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!");
}
IDWriteTextFormat * e2d::EFont::_getTextFormat()
{
if (m_bRecreateNeeded)
{
_initTextFormat();
m_bRecreateNeeded = false;
}
return m_pTextFormat;
}

View File

@ -357,22 +357,22 @@ void e2d::ENode::move(const EVec & v)
this->move(v.x, v.y); this->move(v.x, v.y);
} }
void e2d::ENode::setWidth(float width) void e2d::ENode::_setWidth(float width)
{ {
this->setSize(width, m_Size.height); this->_setSize(width, m_Size.height);
} }
void e2d::ENode::setHeight(float height) void e2d::ENode::_setHeight(float height)
{ {
this->setSize(m_Size.width, height); this->_setSize(m_Size.width, height);
} }
void e2d::ENode::setSize(const ESize & size) void e2d::ENode::_setSize(const ESize & size)
{ {
this->setSize(size.width, size.height); this->_setSize(size.width, size.height);
} }
void e2d::ENode::setSize(float width, float height) void e2d::ENode::_setSize(float width, float height)
{ {
if (m_Size.width == width && m_Size.height == height) if (m_Size.width == width && m_Size.height == height)
return; return;

View File

@ -1,24 +0,0 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::ERectangle::ERectangle()
{
}
e2d::EColor e2d::ERectangle::getColor() const
{
return m_Color;
}
void e2d::ERectangle::setColor(EColor color)
{
m_Color = color;
}
void e2d::ERectangle::_onRender()
{
D2D1_RECT_F rectangle = D2D1::RectF(0, 0, getWidth(), getHeight());
GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color, m_fDisplayOpacity));
GetRenderTarget()->FillRectangle(&rectangle, GetSolidColorBrush());
}

View File

@ -1,452 +1,79 @@
#include "..\enodes.h" #include "..\enodes.h"
#include <map> #include "..\Win\winbase.h"
struct ResKey
{
ResKey() { resNameHash = 0; resTypeHash = 0; }
bool operator < (ResKey const& key) const
{
if (resNameHash > key.resNameHash)
return true;
else if (resNameHash == key.resNameHash)
return resTypeHash > key.resTypeHash;
else
return false;
}
size_t resNameHash;
size_t resTypeHash;
};
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
static std::map<ResKey, ID2D1Bitmap*> s_mBitmapsFromResource;
static ID2D1Bitmap * GetBitmapFromFile(const e2d::EString & fileName);
static ID2D1Bitmap * GetBitmapFromResource(const e2d::EString & resourceName, const e2d::EString & resourceType);
e2d::ESprite::ESprite() e2d::ESprite::ESprite()
: m_pBitmap(nullptr) : m_fSourcePosX(0)
, m_fSourcePosX(0)
, m_fSourcePosY(0) , m_fSourcePosY(0)
, m_fSourceWidth(0) , m_pTexture(nullptr)
, m_fSourceHeight(0)
{ {
} }
e2d::ESprite::ESprite(const EString & imageFileName) e2d::ESprite::ESprite(const EString & imageFileName)
: ESprite() : ESprite()
{ {
setImage(imageFileName); setTexture(new ETexture(imageFileName));
} }
e2d::ESprite::ESprite(const EString & imageFileName, float x, float y, float width, float height) e2d::ESprite::ESprite(const EString & imageFileName, float x, float y, float width, float height)
{ {
setImage(imageFileName); setTexture(new ETexture(imageFileName));
clipImage(x, y, width, height); clipTexture(x, y, width, height);
} }
e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType) e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType)
: ESprite() : ESprite()
{ {
setImage(resourceName, resourceType); setTexture(new ETexture(resourceName, resourceType));
} }
e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height) e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height)
{ {
setImage(resourceName, resourceType); setTexture(new ETexture(resourceName, resourceType));
clipImage(x, y, width, height); clipTexture(x, y, width, height);
} }
float e2d::ESprite::getWidth() const e2d::ESprite::~ESprite()
{ {
return m_fSourceWidth * m_fScaleX; SafeRelease(&m_pTexture);
} }
float e2d::ESprite::getHeight() const void e2d::ESprite::setTexture(ETexture * texture)
{ {
return m_fSourceHeight * m_fScaleY; SafeRelease(&m_pTexture);
} m_pTexture = texture;
m_pTexture->retain();
e2d::ESize e2d::ESprite::getSize() const
{
return ESize(getWidth(), getHeight());
}
float e2d::ESprite::getRealWidth() const
{
return m_fSourceWidth;
}
float e2d::ESprite::getRealHeight() const
{
return m_fSourceHeight;
}
e2d::ESize e2d::ESprite::getRealSize() const
{
return ESize(m_fSourceWidth, m_fSourceHeight);
}
void e2d::ESprite::setWidth(float)
{
}
void e2d::ESprite::setHeight(float)
{
}
void e2d::ESprite::setSize(float, float)
{
}
void e2d::ESprite::setImage(const 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(&m_pBitmap);
m_pBitmap = GetBitmapFromFile(m_sFileName);
ASSERT(m_pBitmap, "ESprite create device resources failed!");
m_fSourcePosX = m_fSourcePosY = 0; m_fSourcePosX = m_fSourcePosY = 0;
m_fSourceWidth = m_pBitmap->GetSize().width; ENode::_setWidth(m_pTexture->getSourceWidth());
m_fSourceHeight = m_pBitmap->GetSize().height; ENode::_setHeight(m_pTexture->getSourceHeight());
} }
void e2d::ESprite::setImage(const EString & fileName, float x, float y, float width, float height) void e2d::ESprite::setTexture(ETexture * texture, float x, float y, float width, float height)
{ {
setImage(fileName); setTexture(texture);
clipImage(x, y, width, height); clipTexture(x, y, width, height);
} }
void e2d::ESprite::setImage(const EString & resourceName, const EString & resourceType) void e2d::ESprite::clipTexture(float x, float y, float width, float height)
{
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(&m_pBitmap);
m_pBitmap = GetBitmapFromResource(resourceName, resourceType);
ASSERT(m_pBitmap, "ESprite create device resources failed!");
m_fSourcePosX = m_fSourcePosY = 0;
m_fSourceWidth = m_pBitmap->GetSize().width;
m_fSourceHeight = m_pBitmap->GetSize().height;
}
void e2d::ESprite::setImage(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height)
{
setImage(resourceName, resourceType);
clipImage(x, y, width, height);
}
void e2d::ESprite::clipImage(float x, float y, float width, float height)
{ {
m_fSourcePosX = max(x, 0); m_fSourcePosX = max(x, 0);
m_fSourcePosY = max(y, 0); m_fSourcePosY = max(y, 0);
m_fSourceWidth = min(max(width, 0), m_pBitmap->GetSize().width - m_fSourcePosX); ENode::_setWidth(min(max(width, 0), m_pTexture->getSourceWidth() - m_fSourcePosX));
m_fSourceHeight = min(max(height, 0), m_pBitmap->GetSize().width - m_fSourcePosX); ENode::_setHeight(min(max(height, 0), m_pTexture->getSourceHeight() - m_fSourcePosX));
} }
void e2d::ESprite::_onRender() void e2d::ESprite::_onRender()
{ {
if (m_pBitmap) if (m_pTexture && m_pTexture->_getBitmap())
{ {
// Draw bitmap // Draw bitmap
GetRenderTarget()->DrawBitmap( GetRenderTarget()->DrawBitmap(
m_pBitmap, m_pTexture->_getBitmap(),
D2D1::RectF(0, 0, m_fSourceWidth, m_fSourceHeight), D2D1::RectF(0, 0, getRealWidth(), getRealHeight()),
m_fDisplayOpacity, m_fDisplayOpacity,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
D2D1::RectF(m_fSourcePosX, m_fSourcePosY, m_fSourceWidth, m_fSourceHeight) D2D1::RectF(m_fSourcePosX, m_fSourcePosY, getRealWidth(), getRealHeight())
); );
} }
} }
bool e2d::ESprite::preloadImage(const EString & fileName)
{
std::hash<e2d::EString> h;
size_t hash = h(fileName);
if (s_mBitmapsFromFile.find(hash) != s_mBitmapsFromFile.end())
{
return true;
}
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))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bbpPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
// 保存图片指针和图片的 Hash 名
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 e2d::ESprite::preloadImage(const EString & resourceName, const EString & resourceType)
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
if (s_mBitmapsFromResource.find(key) != s_mBitmapsFromResource.end())
{
return true;
}
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;
// 定位资源
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, resourceName.c_str(), resourceType.c_str());
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 加载资源
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 获取文件指针,并锁定资源
pImageFile = ::LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 计算大小
imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 创建 WIC 流
hr = GetImagingFactory()->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// 初始化流
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// 创建流的解码器
hr = GetImagingFactory()->CreateDecoderFromStream(
pStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
s_mBitmapsFromResource.insert(
std::map<ResKey, ID2D1Bitmap*>::value_type(
key,
pBitmap)
);
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
SafeReleaseInterface(&pScaler);
return SUCCEEDED(hr);
}
void e2d::ESprite::clearCache()
{
for (auto child : s_mBitmapsFromFile)
{
SafeReleaseInterface(&child.second);
}
for (auto child : s_mBitmapsFromResource)
{
SafeReleaseInterface(&child.second);
}
s_mBitmapsFromFile.clear();
s_mBitmapsFromResource.clear();
}
ID2D1Bitmap * GetBitmapFromFile(const e2d::EString & fileName)
{
if (!e2d::ESprite::preloadImage(fileName))
{
return nullptr;
}
std::hash<e2d::EString> h;
size_t hash = h(fileName);
return s_mBitmapsFromFile.at(hash);
}
ID2D1Bitmap * GetBitmapFromResource(const e2d::EString & resourceName, const e2d::EString & resourceType)
{
if (!e2d::ESprite::preloadImage(resourceName, resourceType))
{
return nullptr;
}
ResKey key;
std::hash<e2d::EString> h;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
return s_mBitmapsFromResource.at(key);
}

View File

@ -1 +1,166 @@
#include "..\enodes.h" #include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::EText::EText()
: m_Color(EColor::WHITE)
, m_bWordWrapping(false)
, m_pFont(nullptr)
, m_fWordWrappingWidth(0)
{
this->setFont(new EFont());
}
e2d::EText::EText(const EString & text)
: EText()
{
this->setText(text);
this->setFont(new EFont());
}
e2d::EText::EText(EFont * font)
: EText()
{
this->setFont(font);
}
e2d::EText::EText(const EString & text, EColor color, EFont * font)
: EText()
{
this->setText(text);
this->setColor(color);
this->setFont(font);
}
e2d::EText::EText(const EString & text, EColor color, EString fontFamily, float fontSize, EFontWeight fontWeight, bool italic)
{
this->setText(text);
this->setColor(color);
this->setFont(new EFont(fontFamily, fontSize, fontWeight, italic));
}
e2d::EText::~EText()
{
SafeRelease(&m_pFont);
}
e2d::EString e2d::EText::getText() const
{
return m_sText;
}
float e2d::EText::getWidth() const
{
return m_fWordWrappingWidth * m_fScaleX;
}
float e2d::EText::getRealWidth() const
{
return m_fWordWrappingWidth;
}
e2d::EColor e2d::EText::getColor() const
{
return m_Color;
}
e2d::EFont * e2d::EText::getFont() const
{
return m_pFont;
}
void e2d::EText::setText(const EString & text)
{
m_sText = text;
_initTextLayout();
}
void e2d::EText::setColor(EColor color)
{
m_Color = color;
}
void e2d::EText::setFont(EFont * font)
{
if (font)
{
SafeRelease(&m_pFont);
m_pFont = font;
font->retain();
_initTextLayout();
}
}
void e2d::EText::setWordWrapping(bool value)
{
m_bWordWrapping = value;
_initTextLayout();
}
void e2d::EText::setWordWrappingWidth(float wordWrapWidth)
{
m_fWordWrappingWidth = max(wordWrapWidth, 0);
_initTextLayout();
}
void e2d::EText::_onRender()
{
GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color.value, m_fDisplayOpacity));
GetRenderTarget()->DrawTextW(
m_sText.c_str(),
m_sText.length(),
m_pFont->_getTextFormat(),
D2D1::RectF(
0,
0,
m_bWordWrapping ? m_fWordWrappingWidth : m_Size.width,
getRealHeight()
),
GetSolidColorBrush()
);
}
void e2d::EText::_initTextLayout()
{
// 未设置字体或空字符串时,文本宽高为 0
if (!m_pFont || m_sText.empty())
{
this->_setHeight(0);
m_fWordWrappingWidth = 0;
return;
}
// 未打开文本自动换行时,设置 TextFormat 属性为不换行
if (!m_bWordWrapping)
{
m_pFont->_getTextFormat()->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}
else
{
m_pFont->_getTextFormat()->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP);
}
// 获取 TextLayout
IDWriteTextLayout * pDWriteTextLayout = nullptr;
HRESULT hr = GetDirectWriteFactory()->CreateTextLayout(
m_sText.c_str(),
m_sText.size(),
m_pFont->_getTextFormat(),
m_bWordWrapping ? m_fWordWrappingWidth : 0,
0,
&pDWriteTextLayout
);
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!");
// 获取文本布局的宽度和高度
DWRITE_TEXT_METRICS metrics;
pDWriteTextLayout->GetMetrics(&metrics);
this->_setSize(metrics.widthIncludingTrailingWhitespace, metrics.height);
m_fWordWrappingWidth = metrics.widthIncludingTrailingWhitespace;
// 删除相关资源
SafeReleaseInterface(&pDWriteTextLayout);
}

369
Easy2D/Node/ETexture.cpp Normal file
View File

@ -0,0 +1,369 @@
#include "..\enodes.h"
#include "..\Win\winbase.h"
#include <map>
struct ResKey
{
ResKey() { resNameHash = 0; resTypeHash = 0; }
bool operator < (ResKey const& key) const
{
if (resNameHash > key.resNameHash)
return true;
else if (resNameHash == key.resNameHash)
return resTypeHash > key.resTypeHash;
else
return false;
}
size_t resNameHash;
size_t resTypeHash;
};
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
static std::map<ResKey, ID2D1Bitmap*> s_mBitmapsFromResource;
e2d::ETexture::ETexture()
: m_pBitmap(nullptr)
{
}
e2d::ETexture::ETexture(const EString & fileName)
{
this->loadFromFile(fileName);
}
e2d::ETexture::ETexture(const EString & resourceName, const EString & resourceType)
{
this->loadFromResource(resourceName, resourceType);
}
e2d::ETexture::~ETexture()
{
SafeReleaseInterface(&m_pBitmap);
}
void e2d::ETexture::loadFromFile(const EString & fileName)
{
WARN_IF(fileName.empty(), "ETexture cannot load bitmap from NULL file name.");
if (fileName.empty())
return;
SafeReleaseInterface(&m_pBitmap);
if (!e2d::ETexture::preload(fileName))
{
WARN_IF(true, "Load ETexture from file failed!");
return;
}
std::hash<e2d::EString> h;
size_t hash = h(fileName);
m_pBitmap = s_mBitmapsFromFile.at(hash);
}
void e2d::ETexture::loadFromResource(const EString & resourceName, const EString & resourceType)
{
WARN_IF(resourceName.empty() || resourceType.empty(), "ETexture cannot load bitmap from NULL resource.");
if (resourceName.empty() || resourceType.empty())
return;
SafeReleaseInterface(&m_pBitmap);
if (!e2d::ETexture::preload(resourceName, resourceType))
{
WARN_IF(true, "Load ETexture from resource failed!");
return;
}
ResKey key;
std::hash<e2d::EString> h;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
m_pBitmap = s_mBitmapsFromResource.at(key);
}
float e2d::ETexture::getSourceWidth() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().width;
}
else
{
return 0;
}
}
float e2d::ETexture::getSourceHeight() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().height;
}
else
{
return 0;
}
}
e2d::ESize e2d::ETexture::getSourceSize() const
{
if (m_pBitmap)
{
return ESize(getSourceWidth(), getSourceHeight());
}
else
{
return ESize();
}
}
bool e2d::ETexture::preload(const EString & fileName)
{
std::hash<e2d::EString> h;
size_t hash = h(fileName);
if (s_mBitmapsFromFile.find(hash) != s_mBitmapsFromFile.end())
{
return true;
}
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))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bbpPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
// 保存图片指针和图片的 Hash 名
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 e2d::ETexture::preload(const EString & resourceName, const EString & resourceType)
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
if (s_mBitmapsFromResource.find(key) != s_mBitmapsFromResource.end())
{
return true;
}
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;
// 定位资源
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, resourceName.c_str(), resourceType.c_str());
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 加载资源
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 获取文件指针,并锁定资源
pImageFile = ::LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 计算大小
imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 创建 WIC 流
hr = GetImagingFactory()->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// 初始化流
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// 创建流的解码器
hr = GetImagingFactory()->CreateDecoderFromStream(
pStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
std::hash<e2d::EString> h;
ResKey key;
key.resNameHash = h(resourceName);
key.resTypeHash = h(resourceType);
s_mBitmapsFromResource.insert(
std::map<ResKey, ID2D1Bitmap*>::value_type(
key,
pBitmap)
);
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
SafeReleaseInterface(&pScaler);
return SUCCEEDED(hr);
}
void e2d::ETexture::clearCache()
{
for (auto child : s_mBitmapsFromFile)
{
SafeReleaseInterface(&child.second);
}
for (auto child : s_mBitmapsFromResource)
{
SafeReleaseInterface(&child.second);
}
s_mBitmapsFromFile.clear();
s_mBitmapsFromResource.clear();
}
ID2D1Bitmap * e2d::ETexture::_getBitmap()
{
return m_pBitmap;
}

View File

@ -2,12 +2,13 @@
using namespace std::chrono; using namespace std::chrono;
HWND s_HWnd = nullptr; static HWND s_HWnd = nullptr;
ID2D1Factory * s_pDirect2dFactory = nullptr; static ID2D1Factory * s_pDirect2dFactory = nullptr;
ID2D1HwndRenderTarget * s_pRenderTarget = nullptr; static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
ID2D1SolidColorBrush * s_pSolidBrush = nullptr; static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
IWICImagingFactory * s_pIWICFactory = nullptr; static IWICImagingFactory * s_pIWICFactory = nullptr;
steady_clock::time_point s_tNow; static IDWriteFactory * s_pDWriteFactory = nullptr;
static steady_clock::time_point s_tNow;
HWND &GetHWnd() HWND &GetHWnd()
@ -60,6 +61,21 @@ ID2D1HwndRenderTarget * &GetRenderTarget()
return s_pRenderTarget; return s_pRenderTarget;
} }
IDWriteFactory * &GetDirectWriteFactory()
{
if (!s_pDWriteFactory)
{
HRESULT hr;
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&s_pDWriteFactory)
);
ASSERT(SUCCEEDED(hr), "Create DirectWrite Factory Failed!");
}
return s_pDWriteFactory;
}
ID2D1SolidColorBrush * &GetSolidColorBrush() ID2D1SolidColorBrush * &GetSolidColorBrush()
{ {
if (!s_pSolidBrush) if (!s_pSolidBrush)

View File

@ -19,6 +19,8 @@ ID2D1SolidColorBrush * &GetSolidColorBrush();
IWICImagingFactory * &GetImagingFactory(); IWICImagingFactory * &GetImagingFactory();
IDWriteFactory * &GetDirectWriteFactory();
std::chrono::steady_clock::time_point &GetNow(); std::chrono::steady_clock::time_point &GetNow();
long long GetInterval(std::chrono::steady_clock::time_point tLast); long long GetInterval(std::chrono::steady_clock::time_point tLast);

View File

@ -50,7 +50,7 @@ public:
virtual void onActivate(); virtual void onActivate();
// 重写这个函数,它将在窗口非激活时执行 // 重写这个函数,它将在窗口非激活时执行
virtual void onInactive(); virtual bool onInactive();
// 重写这个函数,它将在关闭窗口时执行 // 重写这个函数,它将在关闭窗口时执行
virtual bool onCloseWindow(); virtual bool onCloseWindow();
@ -205,7 +205,7 @@ public:
virtual void onActivate(); virtual void onActivate();
// 重写这个函数,它将在窗口非激活时执行 // 重写这个函数,它将在窗口非激活时执行
virtual void onInactive(); virtual bool onInactive();
// 重写这个函数,它将在关闭窗口时执行 // 重写这个函数,它将在关闭窗口时执行
virtual bool onCloseWindow(); virtual bool onCloseWindow();

View File

@ -82,148 +82,204 @@ typedef std::function<void(int)> TIMER_CALLBACK;
enum EColor class EColor
{ {
AliceBlue = 0xF0F8FF, public:
AntiqueWhite = 0xFAEBD7,
Aqua = 0x00FFFF, EColor()
Aquamarine = 0x7FFFD4, {
Azure = 0xF0FFFF, value = VALUE::WHITE;
Beige = 0xF5F5DC, }
Bisque = 0xFFE4C4,
Black = 0x000000, EColor(int color)
BlanchedAlmond = 0xFFEBCD, {
Blue = 0x0000FF, value = VALUE(color);
BlueViolet = 0x8A2BE2, }
Brown = 0xA52A2A,
BurlyWood = 0xDEB887, enum VALUE
CadetBlue = 0x5F9EA0, {
Chartreuse = 0x7FFF00, ALICE_BLUE = 0xF0F8FF,
Chocolate = 0xD2691E, ANTIQUE_WHITE = 0xFAEBD7,
Coral = 0xFF7F50, AQUA = 0x00FFFF,
CornflowerBlue = 0x6495ED, AQUAMARINE = 0x7FFFD4,
Cornsilk = 0xFFF8DC, AZURE = 0xF0FFFF,
Crimson = 0xDC143C, BEIGE = 0xF5F5DC,
Cyan = 0x00FFFF, BISQUE = 0xFFE4C4,
DarkBlue = 0x00008B, BLACK = 0x000000,
DarkCyan = 0x008B8B, BLANCHED_ALMOND = 0xFFEBCD,
DarkGoldenrod = 0xB8860B, BLUE = 0x0000FF,
DarkGray = 0xA9A9A9, BLUE_VIOLET = 0x8A2BE2,
DarkGreen = 0x006400, BROWN = 0xA52A2A,
DarkKhaki = 0xBDB76B, BURLY_WOOD = 0xDEB887,
DarkMagenta = 0x8B008B, CADET_BLUE = 0x5F9EA0,
DarkOliveGreen = 0x556B2F, CHARTREUSE = 0x7FFF00,
DarkOrange = 0xFF8C00, CHOCOLATE = 0xD2691E,
DarkOrchid = 0x9932CC, CORAL = 0xFF7F50,
DarkRed = 0x8B0000, CORNFLOWER_BLUE = 0x6495ED,
DarkSalmon = 0xE9967A, CORNSILK = 0xFFF8DC,
DarkSeaGreen = 0x8FBC8F, CRIMSON = 0xDC143C,
DarkSlateBlue = 0x483D8B, CYAN = 0x00FFFF,
DarkSlateGray = 0x2F4F4F, DARK_BLUE = 0x00008B,
DarkTurquoise = 0x00CED1, DARK_CYAN = 0x008B8B,
DarkViolet = 0x9400D3, DARK_GOLDENROD = 0xB8860B,
DeepPink = 0xFF1493, DARK_GRAY = 0xA9A9A9,
DeepSkyBlue = 0x00BFFF, DARK_GREEN = 0x006400,
DimGray = 0x696969, DARK_KHAKI = 0xBDB76B,
DodgerBlue = 0x1E90FF, DARK_MAGENTA = 0x8B008B,
Firebrick = 0xB22222, DARK_OLIVE_GREEN = 0x556B2F,
FloralWhite = 0xFFFAF0, DARK_ORANGE = 0xFF8C00,
ForestGreen = 0x228B22, DARK_ORCHID = 0x9932CC,
Fuchsia = 0xFF00FF, DARK_RED = 0x8B0000,
Gainsboro = 0xDCDCDC, DARK_SALMON = 0xE9967A,
GhostWhite = 0xF8F8FF, DARK_SEA_GREEN = 0x8FBC8F,
Gold = 0xFFD700, DARK_SLATE_BLUE = 0x483D8B,
Goldenrod = 0xDAA520, DARK_SLATE_GRAY = 0x2F4F4F,
Gray = 0x808080, DARK_TURQUOISE = 0x00CED1,
Green = 0x008000, DARK_VIOLET = 0x9400D3,
GreenYellow = 0xADFF2F, DEEP_PINK = 0xFF1493,
Honeydew = 0xF0FFF0, DEEP_SKY_BLUE = 0x00BFFF,
HotPink = 0xFF69B4, DIM_GRAY = 0x696969,
IndianRed = 0xCD5C5C, DODGER_BLUE = 0x1E90FF,
Indigo = 0x4B0082, FIREBRICK = 0xB22222,
Ivory = 0xFFFFF0, FLORAL_WHITE = 0xFFFAF0,
Khaki = 0xF0E68C, FOREST_GREEN = 0x228B22,
Lavender = 0xE6E6FA, FUCHSIA = 0xFF00FF,
LavenderBlush = 0xFFF0F5, GAINSCORO = 0xDCDCDC,
LawnGreen = 0x7CFC00, GHOST_WHITE = 0xF8F8FF,
LemonChiffon = 0xFFFACD, GOLD = 0xFFD700,
LightBlue = 0xADD8E6, GOLDENROD = 0xDAA520,
LightCoral = 0xF08080, GRAY = 0x808080,
LightCyan = 0xE0FFFF, GREEN = 0x008000,
LightGoldenrodYellow = 0xFAFAD2, GREEN_YELLOW = 0xADFF2F,
LightGreen = 0x90EE90, HONEYDEW = 0xF0FFF0,
LightGray = 0xD3D3D3, HOT_PINK = 0xFF69B4,
LightPink = 0xFFB6C1, INDIAN_RED = 0xCD5C5C,
LightSalmon = 0xFFA07A, INDIGO = 0x4B0082,
LightSeaGreen = 0x20B2AA, IVORY = 0xFFFFF0,
LightSkyBlue = 0x87CEFA, KHAKI = 0xF0E68C,
LightSlateGray = 0x778899, LAVENDER = 0xE6E6FA,
LightSteelBlue = 0xB0C4DE, LAVENDER_BLUSH = 0xFFF0F5,
LightYellow = 0xFFFFE0, LAWN_GREEN = 0x7CFC00,
Lime = 0x00FF00, LEMON_CHIFFON = 0xFFFACD,
LimeGreen = 0x32CD32, LIGHT_BLUE = 0xADD8E6,
Linen = 0xFAF0E6, LIGHT_CORAL = 0xF08080,
Magenta = 0xFF00FF, LIGHT_CYAN = 0xE0FFFF,
Maroon = 0x800000, LIGHT_GOLDENROD_YELLOW = 0xFAFAD2,
MediumAquamarine = 0x66CDAA, LIGHT_GREEN = 0x90EE90,
MediumBlue = 0x0000CD, LIGHT_GRAY = 0xD3D3D3,
MediumOrchid = 0xBA55D3, LIGHT_PINK = 0xFFB6C1,
MediumPurple = 0x9370DB, LIGHT_SALMON = 0xFFA07A,
MediumSeaGreen = 0x3CB371, LIGHT_SEA_GREEN = 0x20B2AA,
MediumSlateBlue = 0x7B68EE, LIGHT_SKY_BLUE = 0x87CEFA,
MediumSpringGreen = 0x00FA9A, LIGHT_SLATE_GRAY = 0x778899,
MediumTurquoise = 0x48D1CC, LIGHT_STEEL_BLUE = 0xB0C4DE,
MediumVioletRed = 0xC71585, LIGHT_YELLOW = 0xFFFFE0,
MidnightBlue = 0x191970, LIME = 0x00FF00,
MintCream = 0xF5FFFA, LIME_GREEN = 0x32CD32,
MistyRose = 0xFFE4E1, LINEN = 0xFAF0E6,
Moccasin = 0xFFE4B5, MAGENTA = 0xFF00FF,
NavajoWhite = 0xFFDEAD, MAROON = 0x800000,
Navy = 0x000080, MEDIUM_AQUAMARINE = 0x66CDAA,
OldLace = 0xFDF5E6, MEDIUM_BLUE = 0x0000CD,
Olive = 0x808000, MEDIUM_ORCHID = 0xBA55D3,
OliveDrab = 0x6B8E23, MEDIUM_PURPLE = 0x9370DB,
Orange = 0xFFA500, MEDIUM_SEA_GREEN = 0x3CB371,
OrangeRed = 0xFF4500, MEDIUM_SLATE_BLUE = 0x7B68EE,
Orchid = 0xDA70D6, MEDIUM_SPRING_GREEN = 0x00FA9A,
PaleGoldenrod = 0xEEE8AA, MEDIUM_TURQUOISE = 0x48D1CC,
PaleGreen = 0x98FB98, MEDUIM_VIOLET_RED = 0xC71585,
PaleTurquoise = 0xAFEEEE, MIDNIGHT_BLUE = 0x191970,
PaleVioletRed = 0xDB7093, MINT_CREAM = 0xF5FFFA,
PapayaWhip = 0xFFEFD5, MISTY_ROSE = 0xFFE4E1,
PeachPuff = 0xFFDAB9, MOCCASIN = 0xFFE4B5,
Peru = 0xCD853F, NAVAJO_WHITE = 0xFFDEAD,
Pink = 0xFFC0CB, NAVY = 0x000080,
Plum = 0xDDA0DD, OLD_LACE = 0xFDF5E6,
PowderBlue = 0xB0E0E6, OLIVE = 0x808000,
Purple = 0x800080, OLIVE_DRAB = 0x6B8E23,
Red = 0xFF0000, ORANGE = 0xFFA500,
RosyBrown = 0xBC8F8F, ORANGE_RED = 0xFF4500,
RoyalBlue = 0x4169E1, ORCHID = 0xDA70D6,
SaddleBrown = 0x8B4513, PALE_GOLDENROD = 0xEEE8AA,
Salmon = 0xFA8072, PALE_GREEN = 0x98FB98,
SandyBrown = 0xF4A460, PALE_TURQUOISE = 0xAFEEEE,
SeaGreen = 0x2E8B57, PALE_VIOLET_RED = 0xDB7093,
SeaShell = 0xFFF5EE, PAPAYA_WHIP = 0xFFEFD5,
Sienna = 0xA0522D, PEACH_PUFF = 0xFFDAB9,
Silver = 0xC0C0C0, PERU = 0xCD853F,
SkyBlue = 0x87CEEB, PINK = 0xFFC0CB,
SlateBlue = 0x6A5ACD, PLUM = 0xDDA0DD,
SlateGray = 0x708090, POWDER_BLUE = 0xB0E0E6,
Snow = 0xFFFAFA, PURPLE = 0x800080,
SpringGreen = 0x00FF7F, RED = 0xFF0000,
SteelBlue = 0x4682B4, ROSY_BROWN = 0xBC8F8F,
Tan = 0xD2B48C, ROYAL_BLUE = 0x4169E1,
Teal = 0x008080, SADDLE_BROWN = 0x8B4513,
Thistle = 0xD8BFD8, SALMON = 0xFA8072,
Tomato = 0xFF6347, SANDY_BROWN = 0xF4A460,
Turquoise = 0x40E0D0, SEA_GREEN = 0x2E8B57,
Violet = 0xEE82EE, SEA_SHELL = 0xFFF5EE,
Wheat = 0xF5DEB3, SIENNA = 0xA0522D,
White = 0xFFFFFF, SILVER = 0xC0C0C0,
WhiteSmoke = 0xF5F5F5, SKY_BLUE = 0x87CEEB,
Yellow = 0xFFFF00, SLATE_BLUE = 0x6A5ACD,
YellowGreen = 0x9ACD32, SLATE_GRAY = 0x708090,
SNOW = 0xFFFAFA,
SPRING_GREEN = 0x00FF7F,
STEEL_BLUE = 0x4682B4,
TAN = 0xD2B48C,
TEAL = 0x008080,
THISTLE = 0xD8BFD8,
TOMATO = 0xFF6347,
TURQUOISE = 0x40E0D0,
VIOLET = 0xEE82EE,
WHEAT = 0xF5DEB3,
WHITE = 0xFFFFFF,
WHITE_SMOKE = 0xF5F5F5,
YELLOW = 0xFFFF00,
YELLOW_GREEN = 0x9ACD32
};
VALUE value;
};
class EFontWeight
{
public:
EFontWeight()
{
value = VALUE::REGULAR;
}
EFontWeight(int fontWeight)
{
value = VALUE(fontWeight);
}
enum VALUE
{
THIN = 100,
EXTRA_LIGHT = 200,
ULTRA_LIGHT = 200,
LIGHT = 300,
SEMI_LIGHT = 350,
NORMAL = 400,
REGULAR = 400,
MEDIUM = 500,
DEMI_BOLD = 600,
SEMI_BOLD = 600,
BOLD = 700,
EXTRA_BOLD = 800,
ULTRA_BOLD = 800,
BLACK = 900,
HEAVY = 900,
EXTRA_BLACK = 950,
ULTRA_BLACK = 950
};
VALUE value;
}; };
} }

View File

@ -57,3 +57,6 @@
template<typename T> template<typename T>
inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } } inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } }
template<typename T>
inline void SafeRelease(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } }

View File

@ -1,10 +1,12 @@
#pragma once #pragma once
#include "ebase.h" #include "ebase.h"
#include "Win\winbase.h"
namespace e2d namespace e2d
{ {
class EText;
class ESprite;
class ENode : class ENode :
public EObject public EObject
{ {
@ -138,27 +140,6 @@ public:
const EVec & v const EVec & v
); );
// 设置节点宽度
virtual void setWidth(
float width
);
// 设置节点高度
virtual void setHeight(
float height
);
// 设置节点大小
virtual void setSize(
const ESize & size
);
// 设置节点大小
virtual void setSize(
float width,
float height
);
// 设置节点绘图顺序 // 设置节点绘图顺序
// 默认为 0 // 默认为 0
virtual void setOrder( virtual void setOrder(
@ -312,6 +293,27 @@ protected:
// 更新节点透明度 // 更新节点透明度
static void _updateOpacity(ENode * node); static void _updateOpacity(ENode * node);
// 设置节点宽度
virtual void _setWidth(
float width
);
// 设置节点高度
virtual void _setHeight(
float height
);
// 设置节点大小
virtual void _setSize(
const ESize & size
);
// 设置节点大小
virtual void _setSize(
float width,
float height
);
protected: protected:
EString m_sName; EString m_sName;
size_t m_nHashName; size_t m_nHashName;
@ -338,21 +340,67 @@ protected:
}; };
class ERectangle : class ETexture :
public ENode public EObject
{ {
friend ESprite;
public: public:
ERectangle(); // 创建一个空的纹理
ETexture();
EColor getColor() const; // 从本地文件中读取资源
ETexture(
const EString & fileName
);
void setColor(EColor color); // 读取程序资源
ETexture(
const EString & resourceName,
const EString & resourceType
);
~ETexture();
// 从本地文件中读取资源
void loadFromFile(
const EString & fileName
);
// 读取程序资源
void loadFromResource(
const EString & resourceName,
const EString & resourceType
);
// 获取源图片宽度
virtual float getSourceWidth() const;
// 获取源图片高度
virtual float getSourceHeight() const;
// 获取源图片大小
virtual ESize getSourceSize() const;
// 预加载资源
static bool preload(
const EString & fileName
);
// 预加载资源
static bool preload(
const EString & resourceName,
const EString & resourceType
);
// 清空缓存
static void clearCache();
protected: protected:
virtual void _onRender() override; ID2D1Bitmap * _getBitmap();
protected: protected:
EColor m_Color; ID2D1Bitmap * m_pBitmap;
}; };
@ -393,85 +441,30 @@ public:
float height float height
); );
// 获取精灵宽度 ~ESprite();
virtual float getWidth() const override;
// 获取精灵高度 // 设置精灵纹理
virtual float getHeight() const override; void setTexture(
ETexture * texture
// 获取精灵大小
virtual ESize getSize() const override;
// 获取精灵宽度(不考虑缩放)
virtual float getRealWidth() const override;
// 获取精灵高度(不考虑缩放)
virtual float getRealHeight() const override;
// 获取精灵大小(不考虑缩放)
virtual ESize getRealSize() const override;
// 设置精灵宽度是失效的
virtual void setWidth(float) override;
// 设置精灵高度是失效的
virtual void setHeight(float) override;
// 设置精灵大小是失效的
virtual void setSize(float, float) override;
// 从文件加载图片
void setImage(
const EString & fileName
); );
// 从文件加载图片并裁剪 // 设置精灵纹理并裁剪
void setImage( void setTexture(
const EString & fileName, ETexture * texture,
float x, float x,
float y, float y,
float width, float width,
float height float height
); );
// 从资源加载图片 // 裁剪纹理
void setImage( void clipTexture(
const EString & resourceName,
const EString & resourceType
);
// 从资源加载图片并裁剪
void setImage(
const EString & resourceName,
const EString & resourceType,
float x, float x,
float y, float y,
float width, float width,
float height float height
); );
// 裁剪原图片
void clipImage(
float x,
float y,
float width,
float height
);
// 预加载资源
static bool preloadImage(
const EString & fileName
);
// 预加载资源
static bool preloadImage(
const EString & resourceName,
const EString & resourceType
);
// 清空图片缓存
static void clearCache();
protected: protected:
// 渲染精灵 // 渲染精灵
virtual void _onRender() override; virtual void _onRender() override;
@ -479,12 +472,157 @@ protected:
protected: protected:
float m_fSourcePosX; float m_fSourcePosX;
float m_fSourcePosY; float m_fSourcePosY;
float m_fSourceWidth; ETexture * m_pTexture;
float m_fSourceHeight; };
EString m_sFileName;
EString m_sResourceName;
EString m_sResourceType; class EFont :
ID2D1Bitmap * m_pBitmap; public EObject
{
friend EText;
public:
EFont();
EFont(
EString fontFamily,
float fontSize = 22,
EFontWeight fontWeight = EFontWeight::REGULAR,
bool italic = false
);
~EFont();
// 获取当前字号
float getFontSize() const;
// 获取当前字体粗细值
EFontWeight getFontWeight() const;
// 是否是斜体
bool isItalic() const;
// 设置字体
void setFamily(
EString fontFamily
);
// 设置字号
void setSize(
float fontSize
);
// 设置字体粗细值
void setWeight(
EFontWeight fontWeight
);
// 设置文字斜体
void setItalic(
bool value
);
protected:
// 创建文字格式
void _initTextFormat();
// 获取文字格式
IDWriteTextFormat * _getTextFormat();
protected:
EString m_sFontFamily;
float m_fFontSize;
EFontWeight m_FontWeight;
bool m_bItalic;
bool m_bRecreateNeeded;
IDWriteTextFormat * m_pTextFormat;
};
class EText :
public ENode
{
public:
EText();
EText(
const EString & text
);
EText(
EFont * font
);
EText(
const EString & text,
EColor color,
EFont * font
);
EText(
const EString & text,
EColor color,
EString fontFamily,
float fontSize = 22,
EFontWeight fontWeight = EFontWeight::REGULAR,
bool italic = false
);
~EText();
// 获取文本
EString getText() const;
// 获取文本宽度
virtual float getWidth() const override;
// 获取文本宽度(不考虑缩放)
virtual float getRealWidth() const override;
// 获取文字颜色
EColor getColor() const;
// 获取字体
EFont * getFont() const;
// 设置文本
void setText(
const EString & text
);
// 设置文字颜色
void setColor(
EColor color
);
// 设置字体
void setFont(
EFont * font
);
// 设置文字自动换行
void setWordWrapping(
bool value
);
// 设置文字换行宽度WordWrapping 打开时生效)
void setWordWrappingWidth(
float wordWrapWidth
);
protected:
// 渲染文字
virtual void _onRender() override;
// 创建文字布局
void _initTextLayout();
protected:
EString m_sText;
EColor m_Color;
bool m_bWordWrapping;
float m_fWordWrappingWidth;
EFont * m_pFont;
}; };
} }