I'm using the clipping node here: http://www.learn-cocos2d.com/2011/01/cocos2d-gem-clippingnode

ClippingNode.h

#import "cocos2d.h"
@interface ClippingNode : CCNode {
    CGRect clippingRegionInNodeCoordinates;
    CGRect clippingRegion;
}
@property (nonatomic) CGRect clippingRegion;
@end

ClippingNode.m

#import "ClippingNode.h"

@interface ClippingNode (PrivateMethods)
-(void) deviceOrientationChanged:(NSNotification*)notification;
@end

@implementation ClippingNode
-(CGRect) clippingRegion {
    return clippingRegionInNodeCoordinates;
}

-(void) setClippingRegion:(CGRect)region {

    // keep the original region coordinates in case the user wants them back unchanged
    clippingRegionInNodeCoordinates = region;
    self.position = clippingRegionInNodeCoordinates.origin;
    self.contentSize = clippingRegionInNodeCoordinates.size;

    // convert to retina coordinates if needed
    region = CC_RECT_POINTS_TO_PIXELS(region);

    // respect scaling
    clippingRegion = CGRectMake(region.origin.x * scaleX_, region.origin.y * scaleY_,
                            region.size.width * scaleX_, region.size.height * scaleY_);
}

-(void) setScale:(float)newScale {
    [super setScale:newScale];
    // re-adjust the clipping region according to the current scale factor
    [self setClippingRegion:clippingRegionInNodeCoordinates];
}

-(void) deviceOrientationChanged:(NSNotification*)notification {
    // re-adjust the clipping region according to the current orientation
    [self setClippingRegion:clippingRegionInNodeCoordinates];
}

-(void) visit {

    glEnable(GL_SCISSOR_TEST);
    CGPoint worldPosition = [self convertToWorldSpace:CGPointZero];
    const CGFloat s = [[CCDirector sharedDirector] contentScaleFactor];
    glScissor((clippingRegion.origin.x) + (worldPosition.x*s), (clippingRegion.origin.y) + (worldPosition.y*s),
          (clippingRegion.size.width), (clippingRegion.size.height));

    [super visit];

    glDisable(GL_SCISSOR_TEST);

}
@end

However, I need to clip a rotated CCNode. Any idea on how I could accomplish such a task?

有帮助吗?

解决方案 2

It only needs CCRenderTexture to finish the job. Any suggestion will be greatly appreciated.

ClippingNode.h

#import "cocos2d.h"
@interface ClippingNode : CCNode
@property (nonatomic, assign) CGSize clippingSize;
@end

ClippingNode.m

#import "ClippingNode.h"
@interface ClippingNode()
@property (nonatomic, strong) CCRenderTexture * renderTexture;
@property (nonatomic, strong) CCSprite * clippedSprite;
@end


@implementation ClippingNode
@synthesize renderTexture;
@synthesize clippedSprite;
@synthesize clippingSize;

- (void) setClippingSize:(CGSize)newClippingSize {

    //assignment
    clippingSize = newClippingSize;

    //set contentSize
    self.contentSize = clippingSize;

    //configure renderTexture
    self.renderTexture = [CCRenderTexture renderTextureWithWidth:clippingSize.width height:clippingSize.height];
    renderTexture.contentSize = CGSizeMake(clippingSize.width, clippingSize.height);

    //configure the renderTexture sprite
    self.clippedSprite = [CCSprite spriteWithTexture:renderTexture.sprite.texture];
    clippedSprite.position = self.position;
    clippedSprite.rotation = rotation_;
    clippedSprite.scaleY = -1;
}

- (void)visit {
    [renderTexture beginWithClear:0 g:0 b:0 a:1];
    [super visit];
    [renderTexture end];

    [clippedSprite visit];
}

@end

Usage:

CCSprite * spriteImage = ...;
spriteImage.position = ccp(0,0);
spriteImage.anchorPoint = ccp(0.5,0.5);

//configure clipping Node
self.clippingNode = [ClippingNode node];
clippingNode.position = ccp(size.width * 0.5f, size.height * 0.5f);
clippingNode.anchorPoint = ccp(0.5f, 0.5f);
clippingNode.rotation = -10.0f;

//configure clipping region
[clippingNode setClippingSize:CGSizeMult(spriteImage.boundingBox.size, 1.5f)];

//add content to the clipping node
[clippingNode addChild:spriteImage]

其他提示

Replace the visit method in the class ClippingNode by this

-(void) visit
{

    float rotationAngle = 15;

    glPushMatrix();

    CCRenderTexture* renderTexture = [[CCRenderTexture renderTextureWithWidth:512 height:512] retain];

    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, clippingRegion.size.width, clippingRegion.size.height);

    [renderTexture begin];

    glPushMatrix();
    glRotatef(rotationAngle, 0, 0, 1);
    glTranslatef(-clippingRegion.origin.x, -clippingRegion.origin.y, 0);

    [super visit];

    glPopMatrix();

    [renderTexture end];

    glDisable(GL_SCISSOR_TEST);

    renderTexture.sprite.position = CGPointMake(clippingRegion.origin.x , clippingRegion.origin.y);
    renderTexture.sprite.anchorPoint = CGPointMake(0, 1);
    renderTexture.sprite.rotation = rotationAngle;
    [renderTexture.sprite visit];

    [renderTexture release];

    glPopMatrix();
}

Basically it creates a texture where to render the ClippingNode contents

Then translate the scene so that the origin in the clipping region is now at (0,0)

Rotate the entire scene by rotationAngle

Enable the scissor

Render the scene

Translate, rotate, and render the sprite containing the texture

enter image description here

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top