ocos2d-x Win32下的节点缩放原理研究心得

来源:互联网 发布:linux 脚本 while 死 编辑:程序博客网 时间:2024/05/18 21:07

[2.1.0]Cocos2d-x Win32下的节点缩放原理研究心得 

[复制链接]  
火星熊猫

19

主题

2

听众

489

积分

版主

Rank: 7Rank: 7Rank: 7

  • 收听TA
  • 发消息
跳转到指定楼层
楼主
 发表于 2013-3-7 01:10:43 |只看该作者 |倒序浏览
本帖最后由 火星熊猫 于 2013-3-7 08:07 编辑

说明:按照FireDragon的建议,我把缩放原理这部分发在新帖里(顺便再骗一个精华),但是本帖内容与上一贴讲到的部分内容有联系,所以请自行参考http://bbs.firedragonpzy.com.cn/ ... d=54&extra=page%3D1

二、节点缩放原理
引擎对节点的平移(T)、缩放(S)、旋转(R)等操作,最终都是通过修改OpenGL的模型视图矩阵(MV)和投影矩阵(P)来实现的。
在cocos2dx\kazmath\src\GL\matrix.c中维护了三个栈结构用来保存绘制流程中每个节点的矩阵
  1. km_mat4_stack modelview_matrix_stack; //模型视图矩阵栈
  2. km_mat4_stack projection_matrix_stack; //投影矩阵栈
  3. km_mat4_stack texture_matrix_stack; //引擎中目前未使用
复制代码
三个栈会在第一次访问时被初始化,初始化后栈中都有一个4*4的对角线是1的单位矩阵。
  1. void lazyInitialize()
  2. {

  3.     if (!initialized) { //若尚未初始化则进入,下面的各种接口都会频繁的进入这里
  4.         kmMat4 identity; //Temporary identity matrix

  5.         //Initialize all 3 stacks
  6.         //modelview_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
  7.         km_mat4_stack_initialize(&modelview_matrix_stack); //MV栈初始化

  8.         //projection_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
  9.         km_mat4_stack_initialize(&projection_matrix_stack); //P栈初始化

  10.         //texture_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
  11.         km_mat4_stack_initialize(&texture_matrix_stack);

  12.         current_stack = &modelview_matrix_stack; //设定MV矩阵栈为当前栈
  13.         initialized = 1; //初始化标志设为true

  14.         kmMat4Identity(&identity); //创建单位矩阵

  15.         //Make sure that each stack has the identity matrix
  16.         km_mat4_stack_push(&modelview_matrix_stack, &identity); //单位矩阵压入MV
  17.         km_mat4_stack_push(&projection_matrix_stack, &identity); //单位矩阵压入P
  18.         km_mat4_stack_push(&texture_matrix_stack, &identity);
  19.     }
  20. }
复制代码
用kmGLMatrixMode(kmGLEnum mode)函数来切换当前操作的栈
  1. void kmGLMatrixMode(kmGLEnum mode)
  2. {
  3.     lazyInitialize(); //判定是否需要初始化以及初始化

  4.     switch(mode)
  5.     {
  6.         case KM_GL_MODELVIEW: 
  7.             current_stack = &modelview_matrix_stack; //切换为模型视图矩阵栈 
  8.         break;
  9.         case KM_GL_PROJECTION: 
  10.             current_stack = &projection_matrix_stack; //切换为投影矩阵栈 
  11.         break;
  12.         case KM_GL_TEXTURE:
  13.             current_stack = &texture_matrix_stack;
  14.         break;
  15.         default:
  16.             assert(0 && "Invalid matrix mode specified"); //TODO: Proper error handling
  17.         break;
  18.     }
  19. }
复制代码
用kmGLPushMatrix()函数将当前栈的栈顶矩阵复制后压栈,kmGLPopMatrix()用于出栈,kmGLLoadIdentity()用于将栈顶矩阵初始化成单位矩阵。
  1. void kmGLPushMatrix(void)
  2. {
  3.     kmMat4 top;

  4.     lazyInitialize(); //Initialize the stacks if they haven't been already //判定是否需要初始化以及初始化 

  5.     //Duplicate the top of the stack (i.e the current matrix)
  6.     kmMat4Assign(&top, current_stack->top); //将栈顶矩阵复制到top
  7.     km_mat4_stack_push(current_stack, &top); //将top压栈
  8. }

  9. void kmGLPopMatrix(void)
  10. {
  11.     assert(initialized && "Cannot Pop empty matrix stack");
  12.     //No need to lazy initialize, you shouldn't be popping first anyway!
  13.     km_mat4_stack_pop(current_stack, NULL); //当前栈 弹出一个矩阵
  14. }

  15. void kmGLLoadIdentity()
  16. {
  17.     lazyInitialize();  //判定是否需要初始化以及初始化 

  18.     kmMat4Identity(current_stack->top); //Replace the top matrix with the identity matrix //将当前栈的栈顶元素覆盖为单位矩阵
  19. }
复制代码
kmGLMultMatrix()做矩阵乘法(主要是节点经过变形计算后得到的结果与栈顶矩阵相乘时,以及最终绘制时MV与P相乘时使用)
kmGLGetMatrix ()获得指定栈的栈顶矩阵
  1. void kmGLMultMatrix(const kmMat4* pIn)
  2. {
  3.     lazyInitialize(); //判定是否需要初始化以及初始化 
  4.     kmMat4Multiply(current_stack->top, current_stack->top, pIn); //将pIn与当前栈栈顶矩阵相乘,结果存入栈顶矩阵
  5. }

  6. void kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut)
  7. {
  8.     lazyInitialize(); //判定是否需要初始化以及初始化 

  9.     switch(mode)
  10.     {
  11.         case KM_GL_MODELVIEW:
  12.             kmMat4Assign(pOut, modelview_matrix_stack.top); //获取MV栈栈顶矩阵
  13.         break;
  14.         case KM_GL_PROJECTION:
  15.             kmMat4Assign(pOut, projection_matrix_stack.top); //获取P栈栈顶矩阵
  16.         break;
  17.         case KM_GL_TEXTURE:
  18.             kmMat4Assign(pOut, texture_matrix_stack.top);
  19.         break;
  20.         default:
  21.             assert(1 && "Invalid matrix mode specified"); //TODO: Proper error handling
  22.         break;
  23.     }
  24. }
复制代码
当每个节点被访问(visit())时,先压栈(默认操作的是MV),再变形
  1. kmGLPushMatrix(); //压栈,压的是MV

  2. this->transform(); //变形计算
复制代码
CCNode::transform()中,CCNode::nodeToParentTransform()负责实际计算,然后将计算结果乘入MV的栈顶矩阵
  1. kmMat4 transfrom4x4;

  2. // Convert 3x3 into 4x4 matrix
  3. CCAffineTransform tmpAffine = this->nodeToParentTransform(); //实际计算
  4. CGAffineToGL(&tmpAffine, transfrom4x4.mat); //将计算结果转换成4*4的矩阵

  5. // Update Z vertex manually
  6. transfrom4x4.mat[14] = m_fVertexZ;

  7. kmGLMultMatrix( &transfrom4x4 ); //做乘法,这里要注意相乘前的MV栈顶矩阵是从父节点的矩阵复制过来的(kmGLPushMatrix有复制的环节),所以如果父节点是缩放过的,那么子节点的矩阵在相乘后也就同样是缩放过的,所以节点缩放为什么具有传递性,原因就在这里
复制代码
CCNode::nodeToParentTransform()并不是每一帧都会计算,只有当需要的时候,即m_bTransformDirty为真时,才会重新计算。除了节点的创建的时候,m_bTransformDirty  为真。运行过程中的扭曲(setSkew)、旋转(setRotation)、缩放(setScale)、平移(setPosition)、设置锚点(setAnchorPoint)、设置内容尺寸(setContentSize)等操作会导致节点的 m_bTransformDirty 设置为真。经过一次变形计算后, m_bTransformDirty 再次赋值成false。
我在这里只贴出了缩放生效的代码,其他操作的计算,请参考 CCNode::nodeToParentTransform()
  1. m_sTransform = CCAffineTransformMake( cy * m_fScaleX, sy * m_fScaleX, -sx * m_fScaleY, cx * m_fScaleY, x, y ); // 这句负责缩放的计算,以及把尺寸信息和坐标信息拼成一个Struct
复制代码
当节点在绘制自身(draw())的时候,以CCLayerColor为例,先将矩阵设置给OpenGL,然后设置颜色数据和顶点数据,指定像素渲染模式,最后绘制顶点
矩阵是在 CC_NODE_DRAW_SETUP 这个宏里设置到OpenGL的
  1. #define CC_NODE_DRAW_SETUP() \
  2. do { \
  3. ccGLEnable(m_eGLServerState); \
  4. CCAssert(getShaderProgram(), "No shader program set for this node"); \
  5. { \
  6. getShaderProgram()->use(); \
  7. getShaderProgram()->setUniformsForBuiltins(); \ //这句负责将矩阵设置给OpenGL
  8. } \
  9. } while(0)
复制代码
CCGLProgram::setUniformsForBuiltins() 中先取得MV和P,然后将MV和P相乘得到名字很酷的MVP,即模型视图投影矩阵,然后调用setUniformLocationWithMatrix4fv 将各个矩阵写入OpenGL中
  1. kmMat4 matrixP;
  2. kmMat4 matrixMV;
  3. kmMat4 matrixMVP;

  4. kmGLGetMatrix(KM_GL_PROJECTION, &matrixP); //获得投影矩阵栈的栈顶矩阵
  5. kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV);//获得模型视图矩阵栈的栈顶矩阵

  6. kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);//相乘得到MVP

  7. setUniformLocationWithMatrix4fv(m_uUniforms[kCCUniformPMatrix], matrixP.mat, 1); //设置投影矩阵
  8. setUniformLocationWithMatrix4fv(m_uUniforms[kCCUniformMVMatrix], matrixMV.mat, 1); //设置MV矩阵
  9. setUniformLocationWithMatrix4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1); //设置MVP矩阵
复制代码
至于矩阵的说明,我也不懂,所以请参考OpenGL的相关资料。

超出字数限制了,后面的部分放在二楼
本主题由 firedragonpzy 于 2013-3-7 09:50 设置高亮

相关帖子

  • [2.1.0]cocos2d-x win32下的节点绘制流程研究心得
  • cocos2d-x屏幕适配原理分析
  • cocos2d-x调试利器[bluestacks] 支持 opengl 2.0 的模拟器
  • [2.1.0]实现在cocos2d-x内调用系统对话框的过程中的一些收获
  • [2.1.0]ccscrollview在上级容器缩放后响应触摸区域错误的问题
  • [2.1.0]cocos2d-x 研究心得 2013-02-11
  • [2.1.0]cocos2d-x 研究心得 2013-02-10
  • [2.1.0]win32下cclabelttf设置字体的一点心得
  • [2.0.4]cocos2d-x项目程序入口研究的一点收获
  • [2.1.0]在andriod下cclabelttf使用自定义字体失效的问题
分享到:QQ空间QQ空间腾讯微博腾讯微博腾讯朋友腾讯朋友
转播转播0分享淘帖0分享分享0收藏收藏0支持支持0反对反对0
 
回复

使用道具 举报

  
火星熊猫

19

主题

2

听众

489

积分

版主

Rank: 7Rank: 7Rank: 7

  • 收听TA
  • 发消息
沙发
 发表于 2013-3-7 08:09:20 |只看该作者
本帖最后由 火星熊猫 于 2013-3-7 08:31 编辑

最后就是调用OpenGL的接口来绘制
  1. void CCLayerColor::draw()
  2. {
  3.     CC_NODE_DRAW_SETUP();//将矩阵设置给OpenGL是在这个宏里面做的

  4.     ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color ); //通知OpenGL要修改顶点和颜色

  5.     glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, m_pSquareVertices); //设置顶点,m_pSquareVertices是一个4元素的数组,每个元素表示一个顶点,依次是左下角、右下角、左上角、右上角
  6.     glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, m_pSquareColors); //设置颜色

  7.     ccGLBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst ); //设置像素渲染模式,这里是 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),即“不论叠加多少次,亮度是不变的”,如有兴趣请参考glBlendFunc的资料

  8.     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); //绘制顶点

  9.     CC_INCREMENT_GL_DRAWS(1);
  10. }
复制代码
注意 m_pSquareVertices 中储存的顶点数据是与缩放无关的,OpenGL在绘制顶点时,会将顶点与矩阵相乘转换后再绘制。
这样当 CCLayerColor::draw() 结束时,屏幕上就应该出现一个填充了颜色的矩形。

以我实验时的程序为例,说明缩放前后矩阵的变化。实验程序以HelloWorld为基础修改而来,共有4个节点,依次是CCScene(即HelloWorldScene)、CCLayer(HelloWorld::scene()创建的)、CCLayerColor 1和 CCLayerColor 2,
  1.         CCLayerColor *layer = CCLayerColor::create(ccc4(255, 0, 0, 255), 960, 720); //设置尺寸为960*720,颜色为红色
  2.         layer->setPosition(ccp(0, 0));
  3.         this->addChild(layer); //CCLayerColor 1 Add在CCLayer上

  4.         CCLayerColor *childlayer = CCLayerColor::create(ccc4(0, 255, 0, 255), 480, 360);//设置尺寸为480*360,即CCLayerColor 1 四分之一的大小,颜色为绿色
  5.         childlayer->setPosition(ccp(0, 0));
  6.         layer->addChild(childlayer); //CCLayerColor 2 Add在CCLayerColor 1上
复制代码
增加一个action使 CCLayerColor 1在运行1秒后被缩小
  1.         CCAction* action = CCSequence::create(
  2.                 CCDelayTime::create(1.0f),
  3.                 CCCallFuncN::create(this, callfuncN_selector(HelloWorld::actiontDone)),
  4.                 NULL);

  5.         layer->runAction(action);
复制代码
在缩放操作的前后打印log
  1. void HelloWorld::actiontDone(CCNode* pSender)
  2. {
  3.         CCLog("before setscale");
  4.         pSender->setScale(0.5f);
  5.         CCLog("after setscale");
  6. }
复制代码
同时为便于跟踪,增加了如下的log
给CCScene增加一个draw函数
  1. void CCScene::draw()
  2. {
  3.         CCLog("in CCScene");
  4. }
复制代码
给CCLayer增加一个draw函数
  1. void CCLayer::draw()
  2. {
  3.         CCLog("in CCLayer");
  4. }
复制代码
CCLayerColor::draw()增加打印顶点数据以及节点名称
  1.     CCLog("m_pSquareVertices[0]: %f, %f", m_pSquareVertices[0].x, m_pSquareVertices[0].y);
  2.     CCLog("m_pSquareVertices[1]: %f, %f", m_pSquareVertices[1].x, m_pSquareVertices[1].y);
  3.     CCLog("m_pSquareVertices[2]: %f, %f", m_pSquareVertices[2].x, m_pSquareVertices[2].y);
  4.     CCLog("m_pSquareVertices[3]: %f, %f", m_pSquareVertices[3].x, m_pSquareVertices[3].y);
复制代码
CCNode::nodeToParentTransform(void) 中增加打印变形计算的结果
  1. CCLog("in nodeToParentTransform: %f, %f, %f, %f, %f, %f", m_sTransform.a, m_sTransform.b, m_sTransform.c, m_sTransform.d, m_sTransform.tx, m_sTransform.ty);
复制代码
CCGLProgram::setUniformsForBuiltins() 中增加打印矩阵数据
  1.         CCLog("KM_GL_MODELVIEW: %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f", matrixMV.mat[0],  matrixMV.mat[1], matrixMV.mat[2], matrixMV.mat[3], matrixMV.mat[4], matrixMV.mat[5], matrixMV.mat[6], matrixMV.mat[7], matrixMV.mat[8], matrixMV.mat[9], matrixMV.mat[10], matrixMV.mat[11], matrixMV.mat[12], matrixMV.mat[13], matrixMV.mat[14], matrixMV.mat[15]);

  2.         CCLog("KM_GL_PROJECTION: %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f", matrixP.mat[0],  matrixP.mat[1], matrixP.mat[2], matrixP.mat[3], matrixP.mat[4], matrixP.mat[5], matrixP.mat[6], matrixP.mat[7], matrixP.mat[8], matrixP.mat[9], matrixP.mat[10], matrixP.mat[11], matrixP.mat[12], matrixP.mat[13], matrixP.mat[14], matrixP.mat[15]);

  3.         CCLog("KM_GL_MODELVIEWPROJECTION: %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f", matrixMVP.mat[0],  matrixMVP.mat[1], matrixMVP.mat[2], matrixMVP.mat[3], matrixMVP.mat[4], matrixMVP.mat[5], matrixMVP.mat[6], matrixMVP.mat[7], matrixMVP.mat[8], matrixMVP.mat[9], matrixMVP.mat[10], matrixMVP.mat[11], matrixMVP.mat[12], matrixMVP.mat[13], matrixMVP.mat[14], matrixMVP.mat[15]);
复制代码
然后运行,运行结果放到3楼
  
回复

使用道具 举报

  
火星熊猫

19

主题

2

听众

489

积分

版主

Rank: 7Rank: 7Rank: 7

  • 收听TA
  • 发消息
板凳
 发表于 2013-3-7 08:45:58 |只看该作者

程序运行后效果如上图,红色是CCLayerColor 1,绿色是CCLayerColor2

1秒后,CCLayerColor 1被缩小,同时CCLayerColor 2也被同步的缩小
根据打印的log(因为log是每帧都打印,所以我只截取开始和缩放前后的log)
这时第一帧和第二帧的log,可以看到4个节点只在第一帧运行了nodeToParentTransform,CCScene和CCLayer的draw并不作实际绘制,所以只打印出两个CCLayerColor的MV矩阵这时是1,以及顶点数据是原始尺寸
  1. in nodeToParentTransform: 1.000000, 0.000000, -0.000000, 1.000000, 0.000000, 0.000000
  2. in CCScene //以上是CCscene的log,因为变形早于draw执行所以in xxx在下面,以下同理
  3. in nodeToParentTransform: 1.000000, 0.000000, -0.000000, 1.000000, 0.000000, 0.000000
  4. in CCLayer
  5. in nodeToParentTransform: 1.000000, 0.000000, -0.000000, 1.000000, 0.000000, 0.000000
  6. KM_GL_MODELVIEW: 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -480.000000, -360.000000, -622.514282, 1.000000
  7. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  8. KM_GL_MODELVIEWPROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -623.550964, -623.550964, 622.414246, 622.514282
  9. m_pSquareVertices[0]: 0.000000, 0.000000
  10. m_pSquareVertices[1]: 960.000000, 0.000000
  11. m_pSquareVertices[2]: 0.000000, 720.000000
  12. m_pSquareVertices[3]: 960.000000, 720.000000
  13. in CCLayerColor
  14. in nodeToParentTransform: 1.000000, 0.000000, -0.000000, 1.000000, 0.000000, 0.000000
  15. KM_GL_MODELVIEW: 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -480.000000, -360.000000, -622.514282, 1.000000
  16. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  17. KM_GL_MODELVIEWPROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -623.550964, -623.550964, 622.414246, 622.514282
  18. m_pSquareVertices[0]: 0.000000, 0.000000
  19. m_pSquareVertices[1]: 480.000000, 0.000000
  20. m_pSquareVertices[2]: 0.000000, 360.000000
  21. m_pSquareVertices[3]: 480.000000, 360.000000
  22. in CCLayerColor
  23. in CCScene
  24. in CCLayer
  25. KM_GL_MODELVIEW: 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -480.000000, -360.000000, -622.514282, 1.000000
  26. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  27. KM_GL_MODELVIEWPROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -623.550964, -623.550964, 622.414246, 622.514282
  28. m_pSquareVertices[0]: 0.000000, 0.000000
  29. m_pSquareVertices[1]: 960.000000, 0.000000
  30. m_pSquareVertices[2]: 0.000000, 720.000000
  31. m_pSquareVertices[3]: 960.000000, 720.000000
  32. in CCLayerColor
  33. KM_GL_MODELVIEW: 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -480.000000, -360.000000, -622.514282, 1.000000
  34. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  35. KM_GL_MODELVIEWPROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -623.550964, -623.550964, 622.414246, 622.514282
  36. m_pSquareVertices[0]: 0.000000, 0.000000
  37. m_pSquareVertices[1]: 480.000000, 0.000000
  38. m_pSquareVertices[2]: 0.000000, 360.000000
  39. m_pSquareVertices[3]: 480.000000, 360.000000
  40. in CCLayerColor
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册 

  
回复

使用道具 举报

  
火星熊猫

19

主题

2

听众

489

积分

版主

Rank: 7Rank: 7Rank: 7

  • 收听TA
  • 发消息
地板
 发表于 2013-3-7 08:57:53 |只看该作者
本帖最后由 火星熊猫 于 2013-3-7 09:00 编辑

这是缩放前一帧和缩放后一帧的log
  1. in CCScene
  2. in CCLayer
  3. KM_GL_MODELVIEW: 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -480.000000, -360.000000, -622.514282, 1.000000
  4. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  5. KM_GL_MODELVIEWPROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -623.550964, -623.550964, 622.414246, 622.514282
  6. m_pSquareVertices[0]: 0.000000, 0.000000
  7. m_pSquareVertices[1]: 960.000000, 0.000000
  8. m_pSquareVertices[2]: 0.000000, 720.000000
  9. m_pSquareVertices[3]: 960.000000, 720.000000
  10. in CCLayerColor
  11. KM_GL_MODELVIEW: 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -480.000000, -360.000000, -622.514282, 1.000000
  12. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  13. KM_GL_MODELVIEWPROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -623.550964, -623.550964, 622.414246, 622.514282
  14. m_pSquareVertices[0]: 0.000000, 0.000000
  15. m_pSquareVertices[1]: 480.000000, 0.000000
  16. m_pSquareVertices[2]: 0.000000, 360.000000
  17. m_pSquareVertices[3]: 480.000000, 360.000000
  18. in CCLayerColor
  19. before setscale //缩放前
  20. after setscale //缩放后
  21. in CCScene
  22. in CCLayer
  23. in nodeToParentTransform: 0.500000, 0.000000, -0.000000, 0.500000, 240.000000, 180.000000 //CCLayerColor 1重新进行了变形计算
  24. KM_GL_MODELVIEW: 0.500000, 0.000000, 0.000000, 0.000000, 0.000000, 0.500000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -240.000000, -180.000000, -622.514282, 1.000000 //计算后MV变成了0.5
  25. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  26. KM_GL_MODELVIEWPROJECTION: 0.649532, 0.000000, 0.000000, 0.000000, 0.000000, 0.866043, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -311.775482, -311.775482, 622.414246, 622.514282
  27. m_pSquareVertices[0]: 0.000000, 0.000000
  28. m_pSquareVertices[1]: 960.000000, 0.000000
  29. m_pSquareVertices[2]: 0.000000, 720.000000
  30. m_pSquareVertices[3]: 960.000000, 720.000000
  31. in CCLayerColor
  32. KM_GL_MODELVIEW: 0.500000, 0.000000, 0.000000, 0.000000, 0.000000, 0.500000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, -240.000000, -180.000000, -622.514282, 1.000000 //CCLayerColor 2 虽然没有重新计算 但是也变成了 0.5
  33. KM_GL_PROJECTION: 1.299065, 0.000000, 0.000000, 0.000000, 0.000000, 1.732086, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, 0.000000, 0.000000, -0.200016, 0.000000
  34. KM_GL_MODELVIEWPROJECTION: 0.649532, 0.000000, 0.000000, 0.000000, 0.000000, 0.866043, 0.000000, 0.000000, 0.000000, 0.000000, -1.000161, -1.000000, -311.775482, -311.775482, 622.414246, 622.514282
  35. m_pSquareVertices[0]: 0.000000, 0.000000
  36. m_pSquareVertices[1]: 480.000000, 0.000000
  37. m_pSquareVertices[2]: 0.000000, 360.000000
  38. m_pSquareVertices[3]: 480.000000, 360.000000
  39. in CCLayerColor
复制代码
首先 setScale的过程中不涉及任何的绘制动作,事实上setScale 除了记录缩放比和标记需要重新变形计算外也不做其他的操作
  1. void CCNode::setScale(float scale)
  2. {
  3.     m_fScaleX = m_fScaleY = scale;
  4.     m_bTransformDirty = m_bInverseDirty = true;
  5. }
复制代码
其次 setScale后一帧,除了CCLayerColor 1重新变形计算外,其他三个节点没有重新计算,这个符合之前的判断
然后 CCLayerColor 1 重新计算后 MV矩阵变为了 0.5(缩小二分之一),虽然CCLayerColor 2没有重新计算,但是节点MV矩阵的初始值是从父节点获得的,所以CCLayerColor 2的MV矩阵也变成了 0.5
最后 比较缩放前后的顶点数据,两个CCLayerColor的顶点数据都不变,这也就证明缩放是完全依靠对矩阵的操作来实现的。

  
回复

使用道具 举报

  
火星熊猫

19

主题

2

听众

489

积分

版主

Rank: 7Rank: 7Rank: 7

  • 收听TA
  • 发消息
5#
 发表于 2013-3-7 09:02:00 |只看该作者
本帖最后由 火星熊猫 于 2013-3-7 10:23 编辑

总结:之所以想要研究2dx的缩放原理,源于过年时和FD的讨论以及对缩放传递的好奇。当时理想的认为当父节点被缩放时,引擎应该是抛出一个缩放事件通知了子节点。但是从目前分析来看,完全不是想象的情况。根据实现机制,当父节点缩放时,子节点是完全不知道的,从原理上讲子节点也不需要知道。但是实际上子节点是否有必要知道父节点以上的节点有缩放呢?从目前的已知的CCScrollView的两个bug来看,都是当父节点缩放后,CCScrollView不知情造成的。如果某个组件中单独设置了某个独立于矩阵的尺寸(比如CCScrollView设置了裁剪区域,且这个区域不受矩阵影响),那么子节点还是需要知道父节点缩放事件的。当然也许可以让这些操作同样受矩阵影响,但是本人水平还有限,需要大神们去解决。
  
回复

使用道具 举报

  
firedragonpzy

51

主题

2

听众

812

积分

管理员

Rank: 9Rank: 9Rank: 9

最佳新人 活跃会员 热心会员

  • 收听TA
  • 发消息
6#
 发表于 2013-3-7 09:49:53 |只看该作者
【Software MyZone】:http://www.firedragonpzy.com.cn
  ------------------------火龙论坛:大家的平台----------------------
 
回复

使用道具 举报

  
然後の然後ヾ°

1

主题

1

听众

23

积分

新手上路

Rank: 1

  • 收听TA
  • 发消息
7#
 发表于 2013-4-12 17:53:22 |只看该作者
膜拜了。好文。赞一个
  
回复

使用道具 举报

  
 丶白墨

0

主题

0

听众

16

积分

新手上路

Rank: 1

  • 收听TA
  • 发消息
8#
 发表于 2013-5-18 10:12:07 |只看该作者
ding      希望论坛火起来
  
回复

使用道具 举报

  
firedragonpzy

51

主题

2

听众

812

积分

管理员

Rank: 9Rank: 9Rank: 9

最佳新人 活跃会员 热心会员

  • 收听TA
  • 发消息
9#
 发表于 2013-5-18 14:26:54 |只看该作者
 丶白墨 发表于 2013-5-18 10:12 
ding      希望论坛火起来

 有空多来转转……
【Software MyZone】:http://www.firedragonpzy.com.cn
  ------------------------火龙论坛:大家的平台----------------------
 
回复

使用道具 举报

  
 丶白墨

0

主题

0

听众

16

积分

新手上路

Rank: 1

  • 收听TA
  • 发消息
10#
 发表于 2013-5-19 23:35:29 |只看该作者
firedragonpzy 发表于 2013-5-18 14:26 
有空多来转转……

我基本每天都来,2DX新手,论坛为什么不搞大点 是个人时间还是经济问题啊,资源少了 不吸引人呀,我抽点时间把我收集的资源帖上 加点人气
0 0
原创粉丝点击