Reputation: 41
I'm really going crazy trying to figure this out, so any help would be really appreciated. I'm trying to hide most of a sprite and show it gradually. This works fine if I only work with rectangles. For example, I found someone's implementation of the "ClippingNode" class and it worked well, namely, this part of the code:
-(void) visit
{
glPushMatrix();
glEnable(GL_SCISSOR_TEST);
glScissor(clippingRegion.origin.x + positionInPixels_.x, clippingRegion.origin.y + positionInPixels_.y, clippingRegion.size.width, clippingRegion.size.height);
[super visit];
glDisable(GL_SCISSOR_TEST);
glPopMatrix();
}
The problem is I need an irregular shape, not just a rectangle. I was hoping I could stack calls to glScissor and create a shape with many smaller rectangles, but unfortunately glScissor only works once (the last time it was called).
It seems that cocos2d doesn't support OpenGLs stencil buffer (does it?) and even if it did, I find OpenGL so hard to understand, I'd still need someone to explain it to me. If I could set a bezier path on the sprite as a mask (which I think you can do in Quartz), that would be great, but it doesn't seem like that's supported.
Please, if anyone has any bit of wisdom here, that'd be great!
Upvotes: 3
Views: 2502
Reputation: 9326
It isn't possible with glScissor, but you could easily achieve this effect using the stencil buffer. Here is the documentation:
http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node117.html
There is also a NeHe tutorial on the stencil buffer, but it is in C++, not Objective C (though it should be easy to translate into whatever application you need):
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=26
EDIT: This is based on the assumption that you want to clip it to some arbitrary shape, for example a star, smiley whatever, instead of just a rectangle.
Upvotes: 1
Reputation: 41
Figured it out. You can call glScissor multiple times, you just also need to draw that scissored shape each time:
-(void) visit
{
NSEnumerator *enumerator;
NSValue *val;
CGRect aRegion;
glPushMatrix();
glEnable(GL_SCISSOR_TEST);
enumerator = [regions objectEnumerator];
while ((val = (NSValue *)[enumerator nextObject])) {
aRegion = [val CGRectValue];
glScissor(aRegion.origin.x, aRegion.origin.y,
aRegion.size.width, aRegion.size.height);
[super visit];
}
glDisable(GL_SCISSOR_TEST);
glPopMatrix();
}
Upvotes: 1