增加Node::setClipEnabled方法,实现渲染区域裁剪

This commit is contained in:
Nomango 2018-07-28 18:44:37 +08:00
parent c61be531db
commit 4a80f2df88
14 changed files with 118 additions and 68 deletions

View File

@ -4,21 +4,19 @@
e2d::Collider::Collider(Node * parent) e2d::Collider::Collider(Node * parent)
: _visible(true) : _visible(true)
, _color(Color::Blue, 0.7) , _color(Color::Blue, 0.6)
, _parentNode(parent) , _parentNode(parent)
, _geometry(nullptr) , _geometry(nullptr)
, _enabled(true) , _enabled(true)
, _shape(Collider::Shape::None) , _shape(Collider::Shape::None)
, _notify(true) , _notify(true)
{ {
_shape = Game::getInstance()->getConfig().getDefaultColliderShape();
CollisionManager::getInstance()->__addCollider(this);
} }
e2d::Collider::~Collider() e2d::Collider::~Collider()
{ {
SafeRelease(_geometry); SafeRelease(_geometry);
CollisionManager::getInstance()->__removeCollider(this);
} }
e2d::Color e2d::Collider::getColor() const e2d::Color e2d::Collider::getColor() const
@ -43,8 +41,20 @@ ID2D1Geometry * e2d::Collider::getGeometry() const
void e2d::Collider::setShape(Shape shape) void e2d::Collider::setShape(Shape shape)
{ {
if (_shape == shape)
return;
_shape = shape; _shape = shape;
this->recreate(); if (shape == Shape::None)
{
SafeRelease(_geometry);
CollisionManager::getInstance()->__removeCollider(this);
}
else
{
this->recreate();
CollisionManager::getInstance()->__addCollider(this);
}
} }
void e2d::Collider::setCollisionNotify(bool notify) void e2d::Collider::setCollisionNotify(bool notify)
@ -78,7 +88,7 @@ void e2d::Collider::render()
brush->SetColor(_color.toD2DColorF()); brush->SetColor(_color.toD2DColorF());
brush->SetOpacity(1.f); brush->SetOpacity(1.f);
// »æÖƼ¸ºÎÅöײÌå // »æÖƼ¸ºÎÅöײÌå
renderer->getRenderTarget()->DrawGeometry(_geometry, brush); renderer->getRenderTarget()->DrawGeometry(_geometry, brush, 1.5f);
} }
} }
@ -118,11 +128,11 @@ bool e2d::Collider::isCollisionNotify() const
void e2d::Collider::recreate() void e2d::Collider::recreate()
{ {
SafeRelease(_geometry);
if (!_enabled || _shape == Shape::None) if (!_enabled || _shape == Shape::None)
return; return;
SafeRelease(_geometry);
switch (_shape) switch (_shape)
{ {
case Shape::Rect: case Shape::Rect:

View File

@ -7,7 +7,7 @@ e2d::Config::Config()
, _soundEnabled(true) , _soundEnabled(true)
, _frameInterval(15) , _frameInterval(15)
, _showFps(false) , _showFps(false)
, _vSyncEnabled(false) , _vSyncEnabled(true)
, _outlineVisible(false) , _outlineVisible(false)
, _collisionEnabled(false) , _collisionEnabled(false)
, _colliderVisible(false) , _colliderVisible(false)

View File

@ -57,6 +57,7 @@ void e2d::CollisionManager::__updateCollider(Collider* collider)
auto passive = _colliders[i]->getNode(); auto passive = _colliders[i]->getNode();
// 判断两物体是否是相互冲突的物体 // 判断两物体是否是相互冲突的物体
if (active == passive || if (active == passive ||
!passive->isVisible() ||
active->getParentScene() != passive->getParentScene() || active->getParentScene() != passive->getParentScene() ||
!CollisionManager::isCollidable(active, passive)) !CollisionManager::isCollidable(active, passive))
{ {

View File

@ -60,6 +60,7 @@ e2d::Node::Node()
, _parent(nullptr) , _parent(nullptr)
, _parentScene(nullptr) , _parentScene(nullptr)
, _hashName(0) , _hashName(0)
, _clipEnabled(false)
, _needSort(false) , _needSort(false)
, _needTransform(false) , _needTransform(false)
, _autoUpdate(true) , _autoUpdate(true)
@ -68,10 +69,10 @@ e2d::Node::Node()
, _collider(this) , _collider(this)
, _extrapolate(Property::Origin) , _extrapolate(Property::Origin)
{ {
// 设置默认中心点位置
Point defPivot = Game::getInstance()->getConfig().getNodeDefaultPivot(); Point defPivot = Game::getInstance()->getConfig().getNodeDefaultPivot();
this->_pivotX = float(defPivot.x); _pivotX = float(defPivot.x);
this->_pivotY = float(defPivot.y); _pivotY = float(defPivot.y);
_collider.setShape(Game::getInstance()->getConfig().getDefaultColliderShape());
} }
e2d::Node::~Node() e2d::Node::~Node()
@ -87,6 +88,9 @@ e2d::Node::~Node()
void e2d::Node::_update() void e2d::Node::_update()
{ {
if (!_visible)
return;
if (_children.empty()) if (_children.empty())
{ {
_updateSelf(); _updateSelf();
@ -139,19 +143,27 @@ void e2d::Node::_updateSelf()
void e2d::Node::_render() void e2d::Node::_render()
{ {
if (!_visible) if (!_visible)
{
return; return;
}
// 更新转换矩阵 // 更新转换矩阵
updateTransform(); updateTransform();
// 保留差别属性 // 保留差别属性
_extrapolate = this->getProperty(); _extrapolate = this->getProperty();
auto pRT = Renderer::getInstance()->getRenderTarget();
if (_clipEnabled)
{
pRT->SetTransform(_finalMatri);
pRT->PushAxisAlignedClip(
D2D1::RectF(0, 0, _width, _height),
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
);
}
if (_children.empty()) if (_children.empty())
{ {
// 转换渲染器的二维矩阵 // 转换渲染器的二维矩阵
Renderer::getInstance()->getRenderTarget()->SetTransform(_finalMatri); pRT->SetTransform(_finalMatri);
// 渲染自身 // 渲染自身
this->onRender(); this->onRender();
} }
@ -176,7 +188,7 @@ void e2d::Node::_render()
} }
// 转换渲染器的二维矩阵 // 转换渲染器的二维矩阵
Renderer::getInstance()->getRenderTarget()->SetTransform(_finalMatri); pRT->SetTransform(_finalMatri);
// 渲染自身 // 渲染自身
this->onRender(); this->onRender();
@ -184,41 +196,48 @@ void e2d::Node::_render()
for (; i < _children.size(); ++i) for (; i < _children.size(); ++i)
_children[i]->_render(); _children[i]->_render();
} }
if (_clipEnabled)
{
pRT->PopAxisAlignedClip();
}
} }
void e2d::Node::_renderOutline() void e2d::Node::_renderOutline()
{ {
if (_outline && _visible) if (_visible)
{ {
auto renderer = Renderer::getInstance(); if (_outline)
// 获取纯色画刷 {
ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush(); auto renderer = Renderer::getInstance();
// 设置画刷颜色和透明度 // 获取纯色画刷
brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.7f)); ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush();
brush->SetOpacity(1.f); // 设置画刷颜色和透明度
// 渲染轮廓 brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f));
renderer->getRenderTarget()->DrawGeometry(_outline, brush); brush->SetOpacity(1.f);
} // 渲染轮廓
renderer->getRenderTarget()->DrawGeometry(_outline, brush, 1.5f);
}
// 渲染所有子节点的轮廓 // 渲染所有子节点的轮廓
for (auto child : _children) for (auto child : _children)
{ {
child->_renderOutline(); child->_renderOutline();
}
} }
} }
void e2d::Node::_renderCollider() void e2d::Node::_renderCollider()
{ {
// 绘制自身的几何碰撞体
if (_visible) if (_visible)
{ {
_collider.render(); _collider.render();
}
// 绘制所有子节点的几何碰撞体 // 绘制所有子节点的几何碰撞体
for (auto child : _children) for (auto child : _children)
{ {
child->_renderCollider(); child->_renderCollider();
}
} }
} }
@ -525,7 +544,14 @@ int e2d::Node::getOrder() const
void e2d::Node::setOrder(int order) void e2d::Node::setOrder(int order)
{ {
if (_order == order)
return;
_order = order; _order = order;
if (_parent)
{
_parent->_needSort = true;
}
} }
void e2d::Node::setPosX(double x) void e2d::Node::setPosX(double x)
@ -701,6 +727,11 @@ void e2d::Node::setProperty(Property prop)
this->setSkew(prop.skewAngleX, prop.skewAngleY); this->setSkew(prop.skewAngleX, prop.skewAngleY);
} }
void e2d::Node::setClipEnabled(bool enabled)
{
_clipEnabled = enabled;
}
void e2d::Node::addChild(Node * child, int order /* = 0 */) void e2d::Node::addChild(Node * child, int order /* = 0 */)
{ {
WARN_IF(child == nullptr, "Node::addChild NULL pointer exception."); WARN_IF(child == nullptr, "Node::addChild NULL pointer exception.");

View File

@ -34,7 +34,7 @@ void e2d::CircleShape::setRadius(double radius)
Node::setSize(radius * 2, radius * 2); Node::setSize(radius * 2, radius * 2);
} }
void e2d::CircleShape::_renderLine() void e2d::CircleShape::_renderLine() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->DrawEllipse( renderer->getRenderTarget()->DrawEllipse(
@ -45,7 +45,7 @@ void e2d::CircleShape::_renderLine()
); );
} }
void e2d::CircleShape::_renderFill() void e2d::CircleShape::_renderFill() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->FillEllipse( renderer->getRenderTarget()->FillEllipse(

View File

@ -48,7 +48,7 @@ void e2d::EllipseShape::setRadiusY(double radiusY)
Node::setHeight(radiusY * 2); Node::setHeight(radiusY * 2);
} }
void e2d::EllipseShape::_renderLine() void e2d::EllipseShape::_renderLine() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->DrawEllipse( renderer->getRenderTarget()->DrawEllipse(
@ -59,7 +59,7 @@ void e2d::EllipseShape::_renderLine()
); );
} }
void e2d::EllipseShape::_renderFill() void e2d::EllipseShape::_renderFill() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->FillEllipse( renderer->getRenderTarget()->FillEllipse(

View File

@ -20,7 +20,7 @@ e2d::RectShape::~RectShape()
{ {
} }
void e2d::RectShape::_renderLine() void e2d::RectShape::_renderLine() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->DrawRectangle( renderer->getRenderTarget()->DrawRectangle(
@ -31,7 +31,7 @@ void e2d::RectShape::_renderLine()
); );
} }
void e2d::RectShape::_renderFill() void e2d::RectShape::_renderFill() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->FillRectangle( renderer->getRenderTarget()->FillRectangle(

View File

@ -46,7 +46,7 @@ void e2d::RoundRectShape::setRadiusY(double radiusY)
_radiusY = float(radiusY); _radiusY = float(radiusY);
} }
void e2d::RoundRectShape::_renderLine() void e2d::RoundRectShape::_renderLine() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->DrawRoundedRectangle( renderer->getRenderTarget()->DrawRoundedRectangle(
@ -57,7 +57,7 @@ void e2d::RoundRectShape::_renderLine()
); );
} }
void e2d::RoundRectShape::_renderFill() void e2d::RoundRectShape::_renderFill() const
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->FillRoundedRectangle( renderer->getRenderTarget()->FillRoundedRectangle(

View File

@ -13,7 +13,7 @@ e2d::Shape::~Shape()
{ {
} }
void e2d::Shape::onRender() void e2d::Shape::onRender() const
{ {
auto pBrush = Renderer::getInstance()->getSolidColorBrush(); auto pBrush = Renderer::getInstance()->getSolidColorBrush();
pBrush->SetOpacity(_displayOpacity); pBrush->SetOpacity(_displayOpacity);

View File

@ -92,7 +92,7 @@ e2d::Image * e2d::Sprite::getImage() const
return _image; return _image;
} }
void e2d::Sprite::onRender() void e2d::Sprite::onRender() const
{ {
if (_image && _image->getBitmap()) if (_image && _image->getBitmap())
{ {

View File

@ -287,7 +287,7 @@ void e2d::Text::setOutlineJoin(LineJoin outlineJoin)
_style.outlineJoin = outlineJoin; _style.outlineJoin = outlineJoin;
} }
void e2d::Text::onRender() void e2d::Text::onRender() const
{ {
if (_textLayout) if (_textLayout)
{ {

View File

@ -1066,12 +1066,12 @@ public:
); );
// 打开或关闭垂直同步 // 打开或关闭垂直同步
// 默认:关闭 // 默认:打开
void setVSyncEnabled( void setVSyncEnabled(
bool enabled bool enabled
); );
// 设置帧率刷新间隔 // 设置帧率刷新间隔(关闭垂直同步时生效)
// 默认15 // 默认15
void setFrameInterval( void setFrameInterval(
int interval int interval

View File

@ -5,6 +5,7 @@ namespace e2d
{ {
class Layer;
class Action; class Action;
class Transition; class Transition;
class CollisionManager; class CollisionManager;
@ -13,6 +14,7 @@ class Node :
public Ref public Ref
{ {
friend class Scene; friend class Scene;
friend class Layer;
friend class Collider; friend class Collider;
friend class Transition; friend class Transition;
friend class CollisionManager; friend class CollisionManager;
@ -48,7 +50,7 @@ public:
virtual void onUpdate() {} virtual void onUpdate() {}
// 渲染节点 // 渲染节点
virtual void onRender() {} virtual void onRender() const {}
// 按键消息 // 按键消息
// 说明:返回 false 将阻止消息继续传递 // 说明:返回 false 将阻止消息继续传递
@ -250,26 +252,26 @@ public:
); );
// 设置横向缩放比例 // 设置横向缩放比例
// 默认为 1.0f // 默认为 1.0
virtual void setScaleX( virtual void setScaleX(
double scaleX double scaleX
); );
// 设置纵向缩放比例 // 设置纵向缩放比例
// 默认为 1.0f // 默认为 1.0
virtual void setScaleY( virtual void setScaleY(
double scaleY double scaleY
); );
// 设置缩放比例 // 设置缩放比例
// 默认为 (1.0f, 1.0f) // 默认为 (1.0, 1.0)
virtual void setScale( virtual void setScale(
double scaleX, double scaleX,
double scaleY double scaleY
); );
// 设置缩放比例 // 设置缩放比例
// 默认为 1.0f // 默认为 1.0
virtual void setScale( virtual void setScale(
double scale double scale
); );
@ -300,7 +302,7 @@ public:
); );
// 设置透明度 // 设置透明度
// 默认为 1.0f, 范围 [0, 1] // 默认为 1.0, 范围 [0, 1]
virtual void setOpacity( virtual void setOpacity(
double opacity double opacity
); );
@ -350,6 +352,11 @@ public:
Property prop Property prop
); );
// 启用或关闭渲染区域裁剪
virtual void setClipEnabled(
bool enabled
);
// 添加子节点 // 添加子节点
void addChild( void addChild(
Node * child, Node * child,
@ -452,6 +459,7 @@ protected:
int _order; int _order;
bool _visible; bool _visible;
bool _autoUpdate; bool _autoUpdate;
bool _clipEnabled;
bool _needSort; bool _needSort;
bool _needTransform; bool _needTransform;
bool _positionFixed; bool _positionFixed;
@ -520,7 +528,7 @@ public:
virtual Image * getImage() const; virtual Image * getImage() const;
// 渲染精灵 // 渲染精灵
virtual void onRender() override; virtual void onRender() const override;
protected: protected:
E2D_DISABLE_COPY(Sprite); E2D_DISABLE_COPY(Sprite);
@ -724,7 +732,7 @@ public:
); );
// 渲染文字 // 渲染文字
virtual void onRender() override; virtual void onRender() const override;
protected: protected:
E2D_DISABLE_COPY(Text); E2D_DISABLE_COPY(Text);

View File

@ -59,16 +59,16 @@ public:
); );
// äÖȾÐÎ×´ // äÖȾÐÎ×´
virtual void onRender() override; virtual void onRender() const override;
protected: protected:
E2D_DISABLE_COPY(Shape); E2D_DISABLE_COPY(Shape);
// äÖȾÂÖÀª // äÖȾÂÖÀª
virtual void _renderLine() = 0; virtual void _renderLine() const = 0;
// äÖȾÌî³äÉ« // äÖȾÌî³äÉ«
virtual void _renderFill() = 0; virtual void _renderFill() const = 0;
protected: protected:
Style _style; Style _style;
@ -101,10 +101,10 @@ protected:
E2D_DISABLE_COPY(RectShape); E2D_DISABLE_COPY(RectShape);
// äÖȾÂÖÀª // äÖȾÂÖÀª
virtual void _renderLine() override; virtual void _renderLine() const override;
// äÖȾÌî³äÉ« // äÖȾÌî³äÉ«
virtual void _renderFill() override; virtual void _renderFill() const override;
}; };
@ -150,10 +150,10 @@ protected:
E2D_DISABLE_COPY(RoundRectShape); E2D_DISABLE_COPY(RoundRectShape);
// äÖȾÂÖÀª // äÖȾÂÖÀª
virtual void _renderLine() override; virtual void _renderLine() const override;
// äÖȾÌî³äÉ« // äÖȾÌî³äÉ«
virtual void _renderFill() override; virtual void _renderFill() const override;
protected: protected:
float _radiusX; float _radiusX;
@ -191,10 +191,10 @@ protected:
E2D_DISABLE_COPY(CircleShape); E2D_DISABLE_COPY(CircleShape);
// äÖȾÂÖÀª // äÖȾÂÖÀª
virtual void _renderLine() override; virtual void _renderLine() const override;
// äÖȾÌî³äÉ« // äÖȾÌî³äÉ«
virtual void _renderFill() override; virtual void _renderFill() const override;
protected: protected:
float _radius; float _radius;
@ -241,10 +241,10 @@ protected:
E2D_DISABLE_COPY(EllipseShape); E2D_DISABLE_COPY(EllipseShape);
// äÖȾÂÖÀª // äÖȾÂÖÀª
virtual void _renderLine() override; virtual void _renderLine() const override;
// äÖȾÌî³äÉ« // äÖȾÌî³äÉ«
virtual void _renderFill() override; virtual void _renderFill() const override;
protected: protected:
float _radiusX; float _radiusX;