增加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)
: _visible(true)
, _color(Color::Blue, 0.7)
, _color(Color::Blue, 0.6)
, _parentNode(parent)
, _geometry(nullptr)
, _enabled(true)
, _shape(Collider::Shape::None)
, _notify(true)
{
_shape = Game::getInstance()->getConfig().getDefaultColliderShape();
CollisionManager::getInstance()->__addCollider(this);
}
e2d::Collider::~Collider()
{
SafeRelease(_geometry);
CollisionManager::getInstance()->__removeCollider(this);
}
e2d::Color e2d::Collider::getColor() const
@ -43,8 +41,20 @@ ID2D1Geometry * e2d::Collider::getGeometry() const
void e2d::Collider::setShape(Shape shape)
{
if (_shape == shape)
return;
_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)
@ -78,7 +88,7 @@ void e2d::Collider::render()
brush->SetColor(_color.toD2DColorF());
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()
{
SafeRelease(_geometry);
if (!_enabled || _shape == Shape::None)
return;
SafeRelease(_geometry);
switch (_shape)
{
case Shape::Rect:

View File

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

View File

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

View File

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

View File

@ -48,7 +48,7 @@ void e2d::EllipseShape::setRadiusY(double radiusY)
Node::setHeight(radiusY * 2);
}
void e2d::EllipseShape::_renderLine()
void e2d::EllipseShape::_renderLine() const
{
auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->DrawEllipse(
@ -59,7 +59,7 @@ void e2d::EllipseShape::_renderLine()
);
}
void e2d::EllipseShape::_renderFill()
void e2d::EllipseShape::_renderFill() const
{
auto renderer = Renderer::getInstance();
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();
renderer->getRenderTarget()->DrawRectangle(
@ -31,7 +31,7 @@ void e2d::RectShape::_renderLine()
);
}
void e2d::RectShape::_renderFill()
void e2d::RectShape::_renderFill() const
{
auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->FillRectangle(

View File

@ -46,7 +46,7 @@ void e2d::RoundRectShape::setRadiusY(double radiusY)
_radiusY = float(radiusY);
}
void e2d::RoundRectShape::_renderLine()
void e2d::RoundRectShape::_renderLine() const
{
auto renderer = Renderer::getInstance();
renderer->getRenderTarget()->DrawRoundedRectangle(
@ -57,7 +57,7 @@ void e2d::RoundRectShape::_renderLine()
);
}
void e2d::RoundRectShape::_renderFill()
void e2d::RoundRectShape::_renderFill() const
{
auto renderer = Renderer::getInstance();
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();
pBrush->SetOpacity(_displayOpacity);

View File

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

View File

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

View File

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

View File

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

View File

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