CCLayer中如何 控制只显示特定的区域
在CCLayer中,我们有时候要实现自己的CCLayer,当有内容超过我们的范围后,我们想不显示这个超出范围的内容,这个用opengGL的
beforeDraw 就是启用GL_SCISSOR_TEST,然后用glScissor函数设置要显示的范围,left,top,width,height,如果要显示从(0,0)开始的内容,那么left和top就设置为 self.position.x 和 self.position.y即可。
glScissor 函数可以实现。scissor的意思是剪切。
在CCLayer中,负责绘制的函数是在visit函数中,所以我们需要将这个函数重写。
- -(void) visit
- {
- // quick return if not visible. children won't be drawn.
- if (!visible_)
- return;
- kmGLPushMatrix();
- if ( grid_ && grid_.active)
- [grid_ beforeDraw];
- //add by tangaowen
- [self beforeDraw];
- [self transform];
- if(children_) {
- [self sortAllChildren];
- ccArray *arrayData = children_->data;
- NSUInteger i = 0;
- // draw children zOrder < 0
- for( ; i < arrayData->num; i++ ) {
- CCNode *child = arrayData->arr[i];
- if ( [child zOrder] < 0 )
- [child visit];
- else
- break;
- }
- // self draw
- [self draw];
- // draw children zOrder >= 0
- for( ; i < arrayData->num; i++ ) {
- CCNode *child = arrayData->arr[i];
- [child visit];
- }
- } else
- [self draw];
- // reset for next frame
- orderOfArrival_ = 0;
- if ( grid_ && grid_.active)
- [grid_ afterDraw:self];
- //add by tangaowen
- [self afterDraw];
- kmGLPopMatrix();
- //已经包含了 super的功能,没有必要去调用super visit了
- //[super visit];
- }
这个函数里面调用了两个辅助函数:
beforeDraw 和
afterDraw.
实际上上面的visit函数就是在 CCLayer的visit的默认实现基础上增加了对 beforeDraw和 afterDraw这两个函数的调用来实现我们的裁剪功能。如果以后我们有其他的特殊需求,我们就可以在beforeDraw和 afterDraw中实现。
好了,我们来看beforeDraw和afterDraw 两个函数的实现:
- /**
- * clip this view so that outside of the visible bounds can be hidden.
- */
- -(void)beforeDraw
- {
- glEnable(GL_SCISSOR_TEST);
- const CGFloat s = [[CCDirector sharedDirector] contentScaleFactor];
- glScissor(self.position.x *s - m_viewSize.width*s *0.5f,
- self.position.y * s - m_viewSize.height*s *0.5f,
- m_viewSize.width*s,
- m_viewSize.height*s);
- }
- /**
- * retract what's done in beforeDraw so that there's no side effect to
- * other nodes.
- */
- -(void)afterDraw
- {
- glDisable(GL_SCISSOR_TEST);
- }
beforeDraw 就是启用GL_SCISSOR_TEST,然后用glScissor函数设置要显示的范围,left,top,width,height,如果要显示从(0,0)开始的内容,那么left和top就设置为 self.position.x 和 self.position.y即可。
上面我们的显示是以self.position为中点的,所以需要减去size的一半,这个是基于你在当前layer里面的内容的坐标布局的。