vrshoot

annotate src/ios/glview.mm @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 #import "glview.h"
nuclear@0 2 #include "game.h"
nuclear@0 3 #include "screen.h"
nuclear@0 4 #include "logger.h"
nuclear@0 5
nuclear@0 6 unsigned int default_fbo;
nuclear@0 7
nuclear@0 8 static GLView *view;
nuclear@0 9
nuclear@0 10 void request_redisplay()
nuclear@0 11 {
nuclear@0 12 // TODO
nuclear@0 13 }
nuclear@0 14
nuclear@0 15 void swap_buffers()
nuclear@0 16 {
nuclear@0 17 if(view) {
nuclear@0 18 [view swap_buffers];
nuclear@0 19 }
nuclear@0 20 }
nuclear@0 21
nuclear@0 22
nuclear@0 23 @implementation GLView
nuclear@0 24
nuclear@0 25 @synthesize animating;
nuclear@0 26 @dynamic anim_frame_interval;
nuclear@0 27
nuclear@0 28 // You must implement this method
nuclear@0 29 + (Class)layerClass
nuclear@0 30 {
nuclear@0 31 return [CAEAGLLayer class];
nuclear@0 32 }
nuclear@0 33
nuclear@0 34
nuclear@0 35 - (id)initWithFrame: (CGRect) frame
nuclear@0 36 {
nuclear@0 37 if((self = [super initWithFrame: frame]))
nuclear@0 38 {
nuclear@0 39 // Get the layer
nuclear@0 40 CAEAGLLayer *eaglLayer = (CAEAGLLayer*)self.layer;
nuclear@0 41
nuclear@0 42 //self.contentScaleFactor = 2.0;
nuclear@0 43
nuclear@0 44 eaglLayer.opaque = TRUE;
nuclear@0 45 eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:FALSE],
nuclear@0 46 kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8,
nuclear@0 47 kEAGLDrawablePropertyColorFormat, nil];
nuclear@0 48
nuclear@0 49 // initialize OpenGL ES context
nuclear@0 50 context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
nuclear@0 51 if(!context || ![EAGLContext setCurrentContext: context]) {
nuclear@0 52 [self release];
nuclear@0 53 return self;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 // create the framebuffer
nuclear@0 57 glGenFramebuffers(1, &fbo);
nuclear@0 58 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@0 59
nuclear@0 60 glGenRenderbuffers(1, &rbuf_color);
nuclear@0 61 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
nuclear@0 62 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbuf_color);
nuclear@0 63
nuclear@0 64 glGenRenderbuffers(1, &rbuf_depth);
nuclear@0 65 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth);
nuclear@0 66 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth);
nuclear@0 67
nuclear@0 68 default_fbo = fbo;
nuclear@0 69
nuclear@0 70 animating = FALSE;
nuclear@0 71 display_link_supported = FALSE;
nuclear@0 72 anim_frame_interval = 1;
nuclear@0 73 display_link = nil;
nuclear@0 74 anim_timer = nil;
nuclear@0 75
nuclear@0 76 // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
nuclear@0 77 // class is used as fallback when it isn't available.
nuclear@0 78 NSString *reqSysVer = @"3.1";
nuclear@0 79 NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
nuclear@0 80 if([currSysVer compare: reqSysVer options: NSNumericSearch] != NSOrderedAscending) {
nuclear@0 81 display_link_supported = TRUE;
nuclear@0 82 }
nuclear@0 83
nuclear@0 84 self.multipleTouchEnabled = 1;
nuclear@0 85
nuclear@0 86 if(!game_init()) {
nuclear@0 87 exit(1);
nuclear@0 88 }
nuclear@0 89 }
nuclear@0 90
nuclear@0 91 view = self;
nuclear@0 92 return self;
nuclear@0 93 }
nuclear@0 94
nuclear@0 95 - (void)drawView: (id)sender
nuclear@0 96 {
nuclear@0 97 game_display();
nuclear@0 98 }
nuclear@0 99
nuclear@0 100 - (void)swap_buffers
nuclear@0 101 {
nuclear@0 102 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
nuclear@0 103 [context presentRenderbuffer: GL_RENDERBUFFER];
nuclear@0 104 }
nuclear@0 105
nuclear@0 106 - (BOOL)resize: (CAEAGLLayer*)layer
nuclear@0 107 {
nuclear@0 108 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@0 109
nuclear@0 110 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
nuclear@0 111 [context renderbufferStorage: GL_RENDERBUFFER fromDrawable: layer];
nuclear@0 112 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &xsz);
nuclear@0 113 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &ysz);
nuclear@0 114
nuclear@0 115 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth);
nuclear@0 116 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, xsz, ysz);
nuclear@0 117
nuclear@0 118 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
nuclear@0 119 error_log("resize failed, framebuffer incomplete\n");
nuclear@0 120 return FALSE;
nuclear@0 121 }
nuclear@0 122 assert(glGetError() == GL_NO_ERROR);
nuclear@0 123
nuclear@0 124 game_reshape(xsz, ysz);
nuclear@0 125 return TRUE;
nuclear@0 126 }
nuclear@0 127
nuclear@0 128 - (void)layoutSubviews
nuclear@0 129 {
nuclear@0 130 [self resize: (CAEAGLLayer*)self.layer];
nuclear@0 131 [self drawView:nil];
nuclear@0 132 }
nuclear@0 133
nuclear@0 134 - (NSInteger)anim_frame_interval
nuclear@0 135 {
nuclear@0 136 return anim_frame_interval;
nuclear@0 137 }
nuclear@0 138
nuclear@0 139 - (void)setAnimationFrameInterval: (NSInteger)frameInterval
nuclear@0 140 {
nuclear@0 141 // Frame interval defines how many display frames must pass between each time the
nuclear@0 142 // display link fires. The display link will only fire 30 times a second when the
nuclear@0 143 // frame internal is two on a display that refreshes 60 times a second. The default
nuclear@0 144 // frame interval setting of one will fire 60 times a second when the display refreshes
nuclear@0 145 // at 60 times a second. A frame interval setting of less than one results in undefined
nuclear@0 146 // behavior.
nuclear@0 147 if(frameInterval >= 1) {
nuclear@0 148 anim_frame_interval = frameInterval;
nuclear@0 149
nuclear@0 150 if(animating) {
nuclear@0 151 [self stopAnimation];
nuclear@0 152 [self startAnimation];
nuclear@0 153 }
nuclear@0 154 }
nuclear@0 155 }
nuclear@0 156
nuclear@0 157 - (void)startAnimation
nuclear@0 158 {
nuclear@0 159 if(!animating) {
nuclear@0 160 if(display_link_supported) {
nuclear@0 161 // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
nuclear@0 162 // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
nuclear@0 163 // not be called in system versions earlier than 3.1.
nuclear@0 164
nuclear@0 165 display_link = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
nuclear@0 166 [display_link setFrameInterval: anim_frame_interval];
nuclear@0 167 [display_link addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
nuclear@0 168 } else {
nuclear@0 169 anim_timer = [NSTimer scheduledTimerWithTimeInterval: (NSTimeInterval)((1.0 / 60.0) * anim_frame_interval)
nuclear@0 170 target: self selector: @selector(drawView:) userInfo: nil repeats: TRUE];
nuclear@0 171 }
nuclear@0 172
nuclear@0 173 animating = TRUE;
nuclear@0 174 }
nuclear@0 175 }
nuclear@0 176
nuclear@0 177 - (void)stopAnimation
nuclear@0 178 {
nuclear@0 179 if(animating) {
nuclear@0 180 if(display_link_supported) {
nuclear@0 181 [display_link invalidate];
nuclear@0 182 display_link = nil;
nuclear@0 183 } else {
nuclear@0 184 [anim_timer invalidate];
nuclear@0 185 anim_timer = nil;
nuclear@0 186 }
nuclear@0 187
nuclear@0 188 animating = FALSE;
nuclear@0 189 }
nuclear@0 190 }
nuclear@0 191
nuclear@0 192 - (void)dealloc
nuclear@0 193 {
nuclear@0 194 game_cleanup();
nuclear@0 195
nuclear@0 196 if(fbo) {
nuclear@0 197 glDeleteFramebuffers(1, &fbo);
nuclear@0 198 fbo = 0;
nuclear@0 199 default_fbo = 0;
nuclear@0 200 }
nuclear@0 201 if(rbuf_color) {
nuclear@0 202 glDeleteRenderbuffers(1, &rbuf_color);
nuclear@0 203 rbuf_color = 0;
nuclear@0 204 }
nuclear@0 205 if(rbuf_depth) {
nuclear@0 206 glDeleteRenderbuffers(1, &rbuf_depth);
nuclear@0 207 rbuf_depth = 0;
nuclear@0 208 }
nuclear@0 209
nuclear@0 210 if([EAGLContext currentContext] == context) {
nuclear@0 211 [EAGLContext setCurrentContext: nil];
nuclear@0 212 }
nuclear@0 213 [context release];
nuclear@0 214 context = nil;
nuclear@0 215
nuclear@0 216 [super dealloc];
nuclear@0 217 }
nuclear@0 218
nuclear@0 219 #define MOUSEX(x) ((int)((x) * xsz / 320.0))
nuclear@0 220 #define MOUSEY(y) ((int)((y) * ysz / 480.0))
nuclear@0 221 static bool bn_pressed;
nuclear@0 222
nuclear@0 223 - (void)touchesBegan: (NSSet*)touches withEvent: (UIEvent*)event
nuclear@0 224 {
nuclear@0 225 UITouch *touch = [[touches allObjects] objectAtIndex: 0];
nuclear@0 226 CGPoint pt = [touch locationInView: self];
nuclear@0 227
nuclear@0 228 int x = MOUSEX(pt.x);
nuclear@0 229 int y = MOUSEY(pt.y);
nuclear@0 230 current_screen()->button(0, true, x, y);
nuclear@0 231
nuclear@0 232 bn_pressed = true;
nuclear@0 233 }
nuclear@0 234
nuclear@0 235 - (void)touchesMoved: (NSSet*)touches withEvent: (UIEvent*)event
nuclear@0 236 {
nuclear@0 237 UITouch *touch = [[touches allObjects] objectAtIndex: 0];
nuclear@0 238 CGPoint pt = [touch locationInView: self];
nuclear@0 239
nuclear@0 240 int x = MOUSEX(pt.x);
nuclear@0 241 int y = MOUSEY(pt.y);
nuclear@0 242 current_screen()->motion(x, y, bn_pressed);
nuclear@0 243 }
nuclear@0 244
nuclear@0 245 - (void)touchesEnded: (NSSet*)touches withEvent: (UIEvent*)event
nuclear@0 246 {
nuclear@0 247 UITouch *touch = [[touches allObjects] objectAtIndex: 0];
nuclear@0 248 CGPoint pt = [touch locationInView: self];
nuclear@0 249
nuclear@0 250 int x = MOUSEX(pt.x);
nuclear@0 251 int y = MOUSEY(pt.y);
nuclear@0 252 current_screen()->button(0, false, x, y);
nuclear@0 253 bn_pressed = false;
nuclear@0 254 }
nuclear@0 255
nuclear@0 256 - (void)touchesCancelled: (NSSet*)touches withEvent: (UIEvent*)event
nuclear@0 257 {
nuclear@0 258 [self touchesEnded: touches withEvent: event];
nuclear@0 259 }
nuclear@0 260
nuclear@0 261 @end