渲染节点属性
为了更好的操作渲染node,我们来给它设置一些属性,首先是anchor和pos.
class Node
{
public:
Node();
~Node();
void addChild(Node* node);
void addChild(Node* node,int zOrder);
void setZOrder(int zOrder);
int getZOrder();
void sortAllChildren();
void visit();
virtual void render();
void setAnchor(const Point& anchor);
Point getAnchor();
void setPos(const point& pos);
Point getPos();
protected:
Point _anchor;
<span style="font-family: Arial, Helvetica, sans-serif;">Point _pos;</span>
Mat4 _model;
bool _reorderChildDirty;
int _zOrder;
Node* _parent;
std::vector<Node*> _children;
};
typedef Node Layer;
我们定义一个宏来设置它。
#define NODE_PROPERTY(varType, varName, funName)\
protected: varType varName;\
public: varType get##funName(void) const { return varName; }\
public: void set##funName(const varType& var){ varName = var; }
如此这般,我们再来设置旋转,翻转,缩放,斜切。最后如下:
float getScale(void) const;
void setScale(const float& scale);
NODE_PROPERTY(int,_zOrder,ZOrder)
NODE_PROPERTY(Point,_anchor,Anchor)
NODE_PROPERTY(Point,_position,Position)
NODE_PROPERTY(Size,_contentSize,ContentSize)
NODE_PROPERTY(float,_rotate,Rotate)
NODE_PROPERTY(float,_flipX,FlipX)
NODE_PROPERTY(float,_flipY,FlipY)
NODE_PROPERTY(float,_skewX,SkewX)
NODE_PROPERTY(float,_skewY,SkewY)
NODE_PROPERTY(float,_scaleX,ScaleX)
NODE_PROPERTY(float,_scaleY,ScaleY)
void Node::updateMatrix()
{
if (_isUpdateMatrix)
{
//Model matrix : an identity matrix (model will be at the origin)
glm::mat4 model = glm::mat4(1.0f);
//计算锚点
model *= glm::translate(glm::vec3((0.5f - _anchor.x) * _contentSize.width ,( 0.5f - _anchor.y) * _contentSize.height,0));
float scaleX = _scaleX;
float scaleY = _scaleY;
float degree = _rotate;
if (_flipX)
{
scaleX = -_scaleX;
degree = 360 - degree;
}
if (_flipY)
{
scaleY = -_scaleY;
degree = 360 - degree;
}
model *= glm::scale(glm::vec3(scaleX,scaleY,1.0f));
model *= glm::rotate(degree,glm::vec3(0.0f,0.0f,1.0f));
glm::mat4 skewMatrix(1, (float)tanf(angleToRadian(_skewY)), 0, 0,
(float)tanf(angleToRadian(_skewX)), 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
model *= skewMatrix;
//移动到左下角,屏幕左下角为原点。
model *= glm::translate(glm::vec3(-Engine::getInstance()->getDesignSize().width* 0.5f,-Engine::getInstance()->getDesignSize().height * 0.5f,0));
model *= glm::translate(glm::vec3(_position.x,_position.y,0));
_model = model;
}
_isUpdateMatrix = false;
}
float Node::getScale(void) const
{
assert( _scaleX == _scaleY);
return _scaleX;
}
void Node::setScale(const float& scale)
{
_isUpdateMatrix = true;
setScaleX(scale);
setScaleY(scale);
}
void Sprite::render()
{
updateMatrix();
_quadCommand.init(&_quad,_textureID,1,_blendFunc,_model);
Renderer::getInstance()->addQuadCommand(&_quadCommand);
}
sprite渲染之前更新下节点的渲染相关属性。
修改下矩阵的运算。
void Node::updateMatrix()
{
if (_isUpdateMatrix)
{
Size winSize = Engine::getInstance()->getDesignSize();
Point anchorPoint = Point((0.5f - _anchor.x) * _contentSize.width * _scaleX,( 0.5f - _anchor.y) * _contentSize.height * _scaleY);
float rotateRadians = angleToRadian(_rotate);
float cx = 1, sx = 0;
cx = cosf(rotateRadians);
sx = sinf(rotateRadians);
float flipX = _flipX == true ? -1.0f:1.0f;
float flipY = _flipY == true ? -1.0f:1.0f;
float scaleX = _scaleX * flipX;
float scaleY = _scaleY * flipY;
float x = -winSize.width * 0.5f + _position.x + anchorPoint.x;
float y = -winSize.height * 0.5f +_position.y + anchorPoint.y;
float model[4][4] = {{cx*scaleX, sx*scaleX, 0, 0},
{-sx*scaleY, cx*scaleY, 0, 0},
{0, 0, 1, 0},
{x, y, 0, 1}
};
bool needsSkewMatrix = ( _skewX || _skewY );
for (int col = 0; col < 4;++col)
for (int row = 0; row < 4; ++row)
{
_model[col][row] = model[col][row];
}
if (needsSkewMatrix)
{
Mat4 skewMatrix(1, (float)tanf(angleToRadian(_skewY)), 0, 0,
(float)tanf(angleToRadian(_skewX)), 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
if (!anchorPoint.equals(Vec2::ZERO))
{
// XXX: Argh, Mat4 needs a "translate" method.
// XXX: Although this is faster than multiplying a vec4 * mat4
_model[3][0] = _model[3][0]+_model[0][0] * -anchorPoint.x + _model[1][0] * -anchorPoint.y;
_model[3][1] = _model[3][1]+_model[0][1] * -anchorPoint.x + _model[1][2] * -anchorPoint.y;
}
_model = _model * skewMatrix;
}
}
_isUpdateMatrix = false;
}