Added Box2D
This commit is contained in:
299
external/Box2D-2.3.1/Contributions/Platforms/iPhone/Classes/Box2DView.mm
vendored
Normal file
299
external/Box2D-2.3.1/Contributions/Platforms/iPhone/Classes/Box2DView.mm
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
//
|
||||
// Box2DView.mm
|
||||
// Box2D OpenGL View
|
||||
//
|
||||
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
|
||||
//
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <OpenGLES/EAGLDrawable.h>
|
||||
|
||||
#import "Box2DView.h"
|
||||
|
||||
#define USE_DEPTH_BUFFER 0
|
||||
#define kAccelerometerFrequency 30
|
||||
#define FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK 10
|
||||
|
||||
Settings settings;
|
||||
|
||||
// A class extension to declare private methods
|
||||
@interface Box2DView ()
|
||||
|
||||
@property (nonatomic, retain) EAGLContext *context;
|
||||
@property (nonatomic, assign) NSTimer *animationTimer;
|
||||
|
||||
- (BOOL) createFramebuffer;
|
||||
- (void) destroyFramebuffer;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation Box2DView
|
||||
|
||||
@synthesize context;
|
||||
@synthesize animationTimer;
|
||||
@synthesize animationInterval;
|
||||
@synthesize delegate=_delegate;
|
||||
|
||||
// You must implement this method
|
||||
+ (Class)layerClass {
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
|
||||
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
|
||||
- (id)initWithCoder:(NSCoder*)coder {
|
||||
|
||||
if ((self = [super initWithCoder:coder])) {
|
||||
// Get the layer
|
||||
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
|
||||
|
||||
eaglLayer.opaque = YES;
|
||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
|
||||
|
||||
if (!context || ![EAGLContext setCurrentContext:context]) {
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
animationInterval = 1.0 / 60.0;
|
||||
sceneScale=10.0f;
|
||||
positionOffset=CGPointMake(0, 0);
|
||||
lastWorldTouch=CGPointMake(0, 0);
|
||||
|
||||
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
|
||||
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
|
||||
|
||||
//[self setMultipleTouchEnabled:YES];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) selectTestEntry:(int) testIndex
|
||||
{
|
||||
// Destroy existing scene
|
||||
delete test;
|
||||
|
||||
entry = g_testEntries + testIndex;
|
||||
test = entry->createFcn();
|
||||
|
||||
doubleClickValidCountdown=0;
|
||||
|
||||
sceneScale=10.0f;
|
||||
positionOffset=CGPointMake(0, 0);
|
||||
lastWorldTouch=CGPointMake(0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)drawView {
|
||||
|
||||
|
||||
|
||||
if (doubleClickValidCountdown>0) doubleClickValidCountdown--;
|
||||
|
||||
[EAGLContext setCurrentContext:context];
|
||||
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
||||
glViewport(0, 0, backingWidth, backingHeight);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glOrthof(-sceneScale, sceneScale, -sceneScale*1.5f, sceneScale*1.5f, -1.0f, 1.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(positionOffset.x, positionOffset.y,0);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
test->Step(&settings);
|
||||
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
||||
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
|
||||
}
|
||||
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[EAGLContext setCurrentContext:context];
|
||||
[self destroyFramebuffer];
|
||||
[self createFramebuffer];
|
||||
[self drawView];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)createFramebuffer {
|
||||
|
||||
glGenFramebuffersOES(1, &viewFramebuffer);
|
||||
glGenRenderbuffersOES(1, &viewRenderbuffer);
|
||||
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
|
||||
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
|
||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
|
||||
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
||||
|
||||
if (USE_DEPTH_BUFFER) {
|
||||
glGenRenderbuffersOES(1, &depthRenderbuffer);
|
||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
|
||||
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
|
||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
|
||||
}
|
||||
|
||||
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
|
||||
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)destroyFramebuffer {
|
||||
|
||||
glDeleteFramebuffersOES(1, &viewFramebuffer);
|
||||
viewFramebuffer = 0;
|
||||
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
|
||||
viewRenderbuffer = 0;
|
||||
|
||||
if(depthRenderbuffer) {
|
||||
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
|
||||
depthRenderbuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)startAnimation {
|
||||
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
|
||||
}
|
||||
|
||||
|
||||
- (void)stopAnimation {
|
||||
self.animationTimer = nil;
|
||||
}
|
||||
|
||||
|
||||
- (void)setAnimationTimer:(NSTimer *)newTimer {
|
||||
[animationTimer invalidate];
|
||||
animationTimer = newTimer;
|
||||
}
|
||||
|
||||
|
||||
- (void)setAnimationInterval:(NSTimeInterval)interval {
|
||||
|
||||
animationInterval = interval;
|
||||
if (animationTimer) {
|
||||
[self stopAnimation];
|
||||
[self startAnimation];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
[self stopAnimation];
|
||||
|
||||
if ([EAGLContext currentContext] == context) {
|
||||
[EAGLContext setCurrentContext:nil];
|
||||
}
|
||||
|
||||
[context release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(CGPoint) screenSpaceToWorldSpace:(CGPoint) screenLocation
|
||||
{
|
||||
screenLocation.x-=160;
|
||||
screenLocation.y-=240;
|
||||
screenLocation.x/=160;
|
||||
screenLocation.y/=160;
|
||||
screenLocation.x*=sceneScale;
|
||||
screenLocation.y*=-sceneScale;
|
||||
|
||||
screenLocation.x-=positionOffset.x;
|
||||
screenLocation.y-=positionOffset.y;
|
||||
return screenLocation;
|
||||
}
|
||||
|
||||
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
|
||||
if (doubleClickValidCountdown>0)
|
||||
{
|
||||
[_delegate leaveTest];
|
||||
return;
|
||||
}
|
||||
|
||||
doubleClickValidCountdown=FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK;
|
||||
|
||||
|
||||
panning=false;
|
||||
for (UITouch *touch in touches)
|
||||
{
|
||||
CGPoint touchLocation=[touch locationInView:self];
|
||||
CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation];
|
||||
//printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
|
||||
lastScreenTouch=touchLocation;
|
||||
lastWorldTouch=worldPosition;
|
||||
b2Vec2 p = b2Vec2(lastWorldTouch.x,lastWorldTouch.y);
|
||||
test->MouseDown(p);
|
||||
//test->ShiftMouseDown(p);
|
||||
|
||||
if (!test->m_mouseJoint) panning=true;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
for (UITouch *touch in touches)
|
||||
{
|
||||
CGPoint touchLocation=[touch locationInView:self];
|
||||
CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation];
|
||||
//printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
|
||||
|
||||
|
||||
CGPoint screenDistanceMoved=CGPointMake(touchLocation.x-lastScreenTouch.x,touchLocation.y-lastScreenTouch.y);
|
||||
if (panning)
|
||||
{
|
||||
screenDistanceMoved.x/=160;
|
||||
screenDistanceMoved.y/=160;
|
||||
screenDistanceMoved.x*=sceneScale;
|
||||
screenDistanceMoved.y*=-sceneScale;
|
||||
positionOffset.x+=screenDistanceMoved.x;
|
||||
positionOffset.y+=screenDistanceMoved.y;
|
||||
}
|
||||
|
||||
lastScreenTouch=touchLocation;
|
||||
lastWorldTouch=worldPosition;
|
||||
test->MouseMove(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
|
||||
|
||||
}
|
||||
}
|
||||
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
test->MouseUp(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
|
||||
}
|
||||
|
||||
- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
|
||||
{
|
||||
// Only run for valid values
|
||||
if (acceleration.y!=0 && acceleration.x!=0)
|
||||
{
|
||||
if (test) test->SetGravity(acceleration.x,acceleration.y);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user