I need to clip the drawing area of a custom layer so that it will only draw inside a box instead of drawing into the whole window.
I've come up with this solution, but it is not working:
void GameLayer::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags) {
auto director = Director::getInstance();
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
glEnable(GL_SCISSOR_TEST);
static Rect clippingRegion = {0,0,200,200};
director->getOpenGLView()->setScissorInPoints(
clippingRegion.origin.x + origin.x, clippingRegion.origin.y + origin.y,
clippingRegion.size.width, clippingRegion.size.height);
Layer::visit(renderer, parentTransform, parentFlags);
glDisable(GL_SCISSOR_TEST);
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
The layer will draw as if this code wasn't there. But if I remove the glDisable(GL_SCISSOR_TEST)
the whole window will be clipped to the {0,0,200,200}
rect.
Is it possible to clip a Layer
using this approach?
I've found a solution to this problem looking at how the Layout
class in cocos2d-x implements the clipping rect. All you have to do is add these two variables to the class:
CustomCommand _beforeVisitCmdScissor;
CustomCommand _afterVisitCmdScissor;
and then you can modify the visit(...)
method like this:
void GameLayer::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags) {
_beforeVisitCmdScissor.init(_globalZOrder);
_beforeVisitCmdScissor.func = CC_CALLBACK_0(GameLayer::onBeforeVisitScissor, this);
renderer->addCommand(&_beforeVisitCmdScissor);
Layer::visit(renderer, parentTransform, parentFlags);
_afterVisitCmdScissor.init(_globalZOrder);
_afterVisitCmdScissor.func = CC_CALLBACK_0(GameLayer::onAfterVisitScissor, this);
renderer->addCommand(&_afterVisitCmdScissor);
}
void GameLayer::onBeforeVisitScissor()
{
static float size = Tile::size;
static Rect clippingRegion = {0,0,200,200};
glEnable(GL_SCISSOR_TEST);
Director::getInstance()->getOpenGLView()->setScissorInPoints(
clippingRegion.origin.x + origin.x, clippingRegion.origin.y + origin.y,
clippingRegion.size.width, clippingRegion.size.height);
}
void GameLayer::onAfterVisitScissor()
{
glDisable(GL_SCISSOR_TEST);
}