Box2DView.mm
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:8k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. //
  2. //  Box2DView.mm
  3. //  Box2D OpenGL View
  4. //
  5. //  Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
  6. //
  7. #import <QuartzCore/QuartzCore.h>
  8. #import <OpenGLES/EAGLDrawable.h>
  9. #import "Box2DView.h"
  10. #define USE_DEPTH_BUFFER 0
  11. #define kAccelerometerFrequency 30
  12. #define FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK 10
  13. Settings settings;
  14. // A class extension to declare private methods
  15. @interface Box2DView ()
  16. @property (nonatomic, retain) EAGLContext *context;
  17. @property (nonatomic, assign) NSTimer *animationTimer;
  18. - (BOOL) createFramebuffer;
  19. - (void) destroyFramebuffer;
  20. @end
  21. @implementation Box2DView
  22. @synthesize context;
  23. @synthesize animationTimer;
  24. @synthesize animationInterval;
  25. @synthesize delegate=_delegate;
  26. // You must implement this method
  27. + (Class)layerClass {
  28.     return [CAEAGLLayer class];
  29. }
  30. //The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
  31. - (id)initWithCoder:(NSCoder*)coder {
  32.     
  33.     if ((self = [super initWithCoder:coder])) {
  34.         // Get the layer
  35.         CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
  36.         
  37.         eaglLayer.opaque = YES;
  38.         eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
  39.                                         [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
  40.         
  41.         context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
  42.         
  43.         if (!context || ![EAGLContext setCurrentContext:context]) {
  44.             [self release];
  45.             return nil;
  46.         }
  47.         
  48.         animationInterval = 1.0 / 60.0;
  49. sceneScale=10.0f;
  50. positionOffset=CGPointMake(0, 0);
  51. lastWorldTouch=CGPointMake(0, 0);
  52. [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
  53. [[UIAccelerometer sharedAccelerometer] setDelegate:self];
  54.     }
  55.     return self;
  56. }
  57. -(void) selectTestEntry:(int) testIndex
  58. {
  59. // Destroy existing scene
  60. delete test;
  61. entry = g_testEntries + testIndex;
  62. test = entry->createFcn();
  63. doubleClickValidCountdown=0;
  64. sceneScale=10.0f;
  65. positionOffset=CGPointMake(0, 0);
  66. lastWorldTouch=CGPointMake(0, 0);
  67. }
  68. - (void)drawView {
  69.     
  70. if (doubleClickValidCountdown>0) doubleClickValidCountdown--;
  71.     [EAGLContext setCurrentContext:context];
  72.     
  73.     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
  74.     glViewport(0, 0, backingWidth, backingHeight);
  75.     
  76.     glMatrixMode(GL_PROJECTION);
  77.     glLoadIdentity();
  78. glOrthof(-sceneScale, sceneScale, -sceneScale*1.5f, sceneScale*1.5f, -1.0f, 1.0f);
  79.     glMatrixMode(GL_MODELVIEW);
  80.     glLoadIdentity();
  81. glTranslatef(positionOffset.x, positionOffset.y,0);
  82.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  83.     glClear(GL_COLOR_BUFFER_BIT);
  84.     
  85. glEnable(GL_BLEND);
  86. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  87.     glEnableClientState(GL_VERTEX_ARRAY);
  88. test->Step(&settings);
  89. glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
  90.     [context presentRenderbuffer:GL_RENDERBUFFER_OES];
  91. }
  92. - (void)layoutSubviews {
  93.     [EAGLContext setCurrentContext:context];
  94.     [self destroyFramebuffer];
  95.     [self createFramebuffer];
  96.     [self drawView];
  97. }
  98. - (BOOL)createFramebuffer {
  99.     
  100.     glGenFramebuffersOES(1, &viewFramebuffer);
  101.     glGenRenderbuffersOES(1, &viewRenderbuffer);
  102.     
  103.     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
  104.     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
  105.     [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
  106.     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
  107.     
  108.     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
  109.     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
  110.     
  111.     if (USE_DEPTH_BUFFER) {
  112.         glGenRenderbuffersOES(1, &depthRenderbuffer);
  113.         glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
  114.         glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
  115.         glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
  116.     }
  117.     
  118.     if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
  119.         NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
  120.         return NO;
  121.     }
  122.     
  123.     return YES;
  124. }
  125. - (void)destroyFramebuffer {
  126.     
  127.     glDeleteFramebuffersOES(1, &viewFramebuffer);
  128.     viewFramebuffer = 0;
  129.     glDeleteRenderbuffersOES(1, &viewRenderbuffer);
  130.     viewRenderbuffer = 0;
  131.     
  132.     if(depthRenderbuffer) {
  133.         glDeleteRenderbuffersOES(1, &depthRenderbuffer);
  134.         depthRenderbuffer = 0;
  135.     }
  136. }
  137. - (void)startAnimation {
  138.     self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
  139. }
  140. - (void)stopAnimation {
  141.     self.animationTimer = nil;
  142. }
  143. - (void)setAnimationTimer:(NSTimer *)newTimer {
  144.     [animationTimer invalidate];
  145.     animationTimer = newTimer;
  146. }
  147. - (void)setAnimationInterval:(NSTimeInterval)interval {
  148.     
  149.     animationInterval = interval;
  150.     if (animationTimer) {
  151.         [self stopAnimation];
  152.         [self startAnimation];
  153.     }
  154. }
  155. - (void)dealloc {
  156.     
  157.     [self stopAnimation];
  158.     
  159.     if ([EAGLContext currentContext] == context) {
  160.         [EAGLContext setCurrentContext:nil];
  161.     }
  162.     
  163.     [context release];  
  164.     [super dealloc];
  165. }
  166. -(CGPoint) screenSpaceToWorldSpace:(CGPoint) screenLocation
  167. {
  168. screenLocation.x-=160;
  169. screenLocation.y-=240;
  170. screenLocation.x/=160;
  171. screenLocation.y/=160;
  172. screenLocation.x*=sceneScale;
  173. screenLocation.y*=-sceneScale;
  174. screenLocation.x-=positionOffset.x;
  175. screenLocation.y-=positionOffset.y;
  176. return screenLocation;
  177. }
  178. - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
  179. {
  180. if (doubleClickValidCountdown>0)
  181. {
  182. [_delegate leaveTest];
  183. return;
  184. }
  185. doubleClickValidCountdown=FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK;
  186. panning=false;
  187. for (UITouch *touch in touches)
  188. {
  189. CGPoint touchLocation=[touch locationInView:self];
  190. CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation];
  191. //printf("Screen touched %f,%f -> %f,%fn",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
  192. lastScreenTouch=touchLocation;
  193. lastWorldTouch=worldPosition;
  194. test->MouseDown(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
  195. if (!test->m_mouseJoint) panning=true;
  196. }
  197. }
  198. - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
  199. {
  200. for (UITouch *touch in touches)
  201. {
  202. CGPoint touchLocation=[touch locationInView:self];
  203. CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation];
  204. //printf("Screen touched %f,%f -> %f,%fn",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
  205. CGPoint screenDistanceMoved=CGPointMake(touchLocation.x-lastScreenTouch.x,touchLocation.y-lastScreenTouch.y);
  206. if (panning)
  207. {
  208. screenDistanceMoved.x/=160;
  209. screenDistanceMoved.y/=160;
  210. screenDistanceMoved.x*=sceneScale;
  211. screenDistanceMoved.y*=-sceneScale;
  212. positionOffset.x+=screenDistanceMoved.x;
  213. positionOffset.y+=screenDistanceMoved.y;
  214. }
  215. lastScreenTouch=touchLocation;
  216. lastWorldTouch=worldPosition;
  217. test->MouseMove(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
  218. }
  219. }
  220. - (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
  221. {
  222. test->MouseUp(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
  223. }
  224. - (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
  225. {
  226. // Only run for valid values
  227. if (acceleration.y!=0 && acceleration.x!=0)
  228. {
  229. if (test) test->SetGravity(acceleration.x,acceleration.y);
  230. }
  231. }
  232. @end