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里面的内容的坐标布局的。