Skip to content

Instantly share code, notes, and snippets.

Created August 26, 2010 06:50
Show Gist options
  • Save anonymous/550953 to your computer and use it in GitHub Desktop.
Save anonymous/550953 to your computer and use it in GitHub Desktop.
cocos2d Viewport class which provides clipping for all nodes added to the Viewport
//
// Viewport.h
//
// Created by Benjamin Broll on 21.01.10.
// Copyright 2010 NEXT Munich. All rights reserved.
//
#import "cocos2d.h"
/**
* Implements a viewport which will only render the content that lies within its
* rectangle.
*/
@interface Viewport : CCNode {
// the clipping rectangle
CGRect rect;
}
@property (assign) CGRect rect;
+ (Viewport*) viewportWithRect:(CGRect)rect;
- (id) initWithRect:(CGRect)rect;
@end
//
// Viewport.m
// Think
//
// Created by Benjamin Broll on 21.01.10.
// Copyright 2010 NEXT Munich. All rights reserved.
//
#import "Viewport.h"
@implementation Viewport
@synthesize rect;
#pragma mark Clipping logic
- (void) visit {
if (!self.visible)
return;
glPushMatrix();
glEnable(GL_SCISSOR_TEST);
// convert from node space to world space
CGPoint bottomLeft = [self convertToWorldSpace:self.position];
CGPoint topRight = ccpAdd(self.position, ccp(self.contentSize.width, self.contentSize.height));
topRight = [self convertToWorldSpace:topRight];
// calculate scissor rect in world space
CGSize size = [[CCDirector sharedDirector] winSize];
CGRect scissorRect = CGRectMake(bottomLeft.x, bottomLeft.y, topRight.x-bottomLeft.x, topRight.y-bottomLeft.y);
// transform the clipping rectangle to adjust to the current screen
// orientation: the rectangle that has to be passed into glScissor is
// always based on the coordinate system as if the device was held with the
// home button at the bottom. the transformations account for different
// device orientations and adjust the clipping rectangle to what the user
// expects to happen.
ccDeviceOrientation orientation = [[CCDirector sharedDirector] deviceOrientation];
switch (orientation) {
case kCCDeviceOrientationPortrait:
break;
case kCCDeviceOrientationPortraitUpsideDown:
scissorRect.origin.x = size.width-scissorRect.size.width-scissorRect.origin.x;
scissorRect.origin.y = size.height-scissorRect.size.height-scissorRect.origin.y;
break;
case kCCDeviceOrientationLandscapeLeft:
{
float tmp = scissorRect.origin.x;
scissorRect.origin.x = scissorRect.origin.y;
scissorRect.origin.y = size.width-scissorRect.size.width-tmp;
tmp = scissorRect.size.width;
scissorRect.size.width = scissorRect.size.height;
scissorRect.size.height = tmp;
}
break;
case kCCDeviceOrientationLandscapeRight:
{
float tmp = scissorRect.origin.y;
scissorRect.origin.y = scissorRect.origin.x;
scissorRect.origin.x = size.height-scissorRect.size.height-tmp;
tmp = scissorRect.size.width;
scissorRect.size.width = scissorRect.size.height;
scissorRect.size.height = tmp;
}
break;
}
glScissor(scissorRect.origin.x, scissorRect.origin.y,
scissorRect.size.width, scissorRect.size.height);
[super visit];
glDisable(GL_SCISSOR_TEST);
glPopMatrix();
}
#pragma mark Init & Dealloc
+ (Viewport*) viewportWithRect:(CGRect)rect {
return [[[self alloc] initWithRect:rect] autorelease];
}
- (id) initWithRect:(CGRect)r {
if ((self = [super init])) {
self.position = r.origin;
self.contentSize = r.size;
}
return self;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment