在绘制渲染树中,最关键的步骤之一就是进行坐标系的变换。没有坐标系的变换,则无法在正确的位置绘制出纹理。同时,坐标系的变换在其他的场合(例如碰撞检测中)也起着十分重要的作用。因此在这一节中,我们将介绍Cocos2d-x中的坐标变换功能。
首先,我们来看一下transform方法,其代码如下所示:
void CCNode::transform()
{
kmMat4 transfrom4x4;
// Convert 3x3 into 4x4 matrix
CCAffineTransform tmpAffine = this->nodeToParentTransform();
CGAffineToGL(&tmpAffine, transfrom4x4.mat);
// Update Z vertex manually
transfrom4x4.mat[14] = m_fVertexZ;
kmGLMultMatrix( &transfrom4x4 );
// XXX: Expensive calls. Camera should be integrated into the cached affine matrix
if ( m_pCamera != NULL && !(m_pGrid != NULL && m_pGrid->isActive()) )
{
bool translate = (m_tAnchorPointInPoints.x != 0.0f || m_tAnchorPointInPoints.y != 0.0f);
if( translate )
kmGLTranslatef(RENDER_IN_SUBPIXEL(m_tAnchorPointInPoints.x), RENDER_IN_SUBPIXEL(m_tAnchorPointInPoints.y), 0 );
m_pCamera->locate();
if( translate )
kmGLTranslatef(RENDER_IN_SUBPIXEL(-m_tAnchorPointInPoints.x), RENDER_IN_SUBPIXEL(-m_tAnchorPointInPoints.y), 0 );
}
}
可以看到,上述代码用到了许多以"km"为前缀的函数,这是Cocos2d-x使用的一个开源几何计算库Kazmath。它是OpenGL ES 1.0变换函数的代替,可以为程序编写提供便利。在这个方法中,首先通过nodeToParentTransform方法获取此节点相对于父节点的变换矩阵,然后把它转换为OpenGL格式的矩阵并右乘在当前绘图矩阵之上,最后进行了一些摄像机与Gird特效相关的操作。把此节点相对于父节点的变换矩阵与当前节点相连,也就意味着在当前坐标系的基础上进行坐标系变换,得到新的合适的坐标系。这个过程中,变换矩阵等价于坐标系变换的方式,如果我们查看nodeToParentTransform的代码,就可以看到在此方法中,变换矩阵是如何根据当前节点的位置、旋转角度和缩放比例等属性计算出来的了。形象地讲,transform方法的任务就是根据当前节点的属性计算出如何把绘图坐标系变换为新坐标系的矩阵。