forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
			
		
		
	
	
			451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
| #import "GLView.h"
 | |
| 
 | |
| #include <kinc/graphics5/graphics.h>
 | |
| #include <kinc/graphics5/rendertarget.h>
 | |
| #include <kinc/input/acceleration.h>
 | |
| #include <kinc/input/keyboard.h>
 | |
| #include <kinc/input/mouse.h>
 | |
| #include <kinc/input/pen.h>
 | |
| #include <kinc/input/rotation.h>
 | |
| #include <kinc/input/surface.h>
 | |
| #include <kinc/system.h>
 | |
| 
 | |
| #ifdef KINC_OPENGL
 | |
| #include <kinc/backend/graphics4/OpenGLWindow.h>
 | |
| #endif
 | |
| 
 | |
| static const int touchmaxcount = 20;
 | |
| static void *touches[touchmaxcount];
 | |
| 
 | |
| static void initTouches(void) {
 | |
| 	for (int i = 0; i < touchmaxcount; ++i) {
 | |
| 		touches[i] = NULL;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static int getTouchIndex(void *touch) {
 | |
| 	for (int i = 0; i < touchmaxcount; ++i) {
 | |
| 		if (touches[i] == touch)
 | |
| 			return i;
 | |
| 	}
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| static int addTouch(void *touch) {
 | |
| 	for (int i = 0; i < touchmaxcount; ++i) {
 | |
| 		if (touches[i] == NULL) {
 | |
| 			touches[i] = touch;
 | |
| 			return i;
 | |
| 		}
 | |
| 	}
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| static int removeTouch(void *touch) {
 | |
| 	for (int i = 0; i < touchmaxcount; ++i) {
 | |
| 		if (touches[i] == touch) {
 | |
| 			touches[i] = NULL;
 | |
| 			return i;
 | |
| 		}
 | |
| 	}
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| static GLint backingWidth, backingHeight;
 | |
| 
 | |
| int kinc_window_width(int window) {
 | |
| 	return backingWidth;
 | |
| }
 | |
| 
 | |
| int kinc_window_height(int window) {
 | |
| 	return backingHeight;
 | |
| }
 | |
| 
 | |
| @implementation GLView
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| + (Class)layerClass {
 | |
| 	return [CAMetalLayer class];
 | |
| }
 | |
| #else
 | |
| + (Class)layerClass {
 | |
| 	return [CAEAGLLayer class];
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef KINC_OPENGL
 | |
| extern int kinc_ios_gl_framebuffer;
 | |
| #endif
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| - (id)initWithFrame:(CGRect)frame {
 | |
| 	self = [super initWithFrame:(CGRect)frame];
 | |
| 	self.contentScaleFactor = [UIScreen mainScreen].scale;
 | |
| 
 | |
| 	backingWidth = frame.size.width * self.contentScaleFactor;
 | |
| 	backingHeight = frame.size.height * self.contentScaleFactor;
 | |
| 
 | |
| 	initTouches();
 | |
| 
 | |
| 	device = MTLCreateSystemDefaultDevice();
 | |
| 	commandQueue = [device newCommandQueue];
 | |
| 	library = [device newDefaultLibrary];
 | |
| 
 | |
| 	CAMetalLayer *metalLayer = (CAMetalLayer *)self.layer;
 | |
| 
 | |
| 	metalLayer.device = device;
 | |
| 	metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
 | |
| 	metalLayer.framebufferOnly = YES;
 | |
| 	// metalLayer.presentsWithTransaction = YES;
 | |
| 
 | |
| 	metalLayer.opaque = YES;
 | |
| 	metalLayer.backgroundColor = nil;
 | |
| 
 | |
| 	return self;
 | |
| }
 | |
| #else
 | |
| - (id)initWithFrame:(CGRect)frame {
 | |
| 	self = [super initWithFrame:(CGRect)frame];
 | |
| 	self.contentScaleFactor = [UIScreen mainScreen].scale;
 | |
| 
 | |
| 	backingWidth = frame.size.width * self.contentScaleFactor;
 | |
| 	backingHeight = frame.size.height * self.contentScaleFactor;
 | |
| 
 | |
| 	initTouches();
 | |
| 
 | |
| 	CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
 | |
| 
 | |
| 	eaglLayer.opaque = YES;
 | |
| 	eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
 | |
| 	                                                                          kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
 | |
| 
 | |
| 	context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
 | |
| 
 | |
| 	if (!context || ![EAGLContext setCurrentContext:context]) {
 | |
| 		//[self release];
 | |
| 		return nil;
 | |
| 	}
 | |
| 
 | |
| 	glGenFramebuffersOES(1, &defaultFramebuffer);
 | |
| 	glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
 | |
| 	kinc_ios_gl_framebuffer = defaultFramebuffer;
 | |
| 
 | |
| 	glGenRenderbuffersOES(1, &colorRenderbuffer);
 | |
| 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
 | |
| 	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
 | |
| 
 | |
| 	glGenRenderbuffersOES(1, &depthStencilRenderbuffer);
 | |
| 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
 | |
| 	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
 | |
| 	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
 | |
| 
 | |
| 	// Start acceletometer
 | |
| 	hasAccelerometer = false;
 | |
| #ifndef KINC_TVOS
 | |
| 	motionManager = [[CMMotionManager alloc] init];
 | |
| 	if ([motionManager isAccelerometerAvailable]) {
 | |
| 		motionManager.accelerometerUpdateInterval = 0.033;
 | |
| 		[motionManager startAccelerometerUpdates];
 | |
| 		hasAccelerometer = true;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| #ifndef KINC_TVOS
 | |
| 	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardHide:) name:UIKeyboardWillHideNotification object:nil];
 | |
| #endif
 | |
| 
 | |
| 	return self;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| - (void)begin {
 | |
| }
 | |
| #else
 | |
| - (void)begin {
 | |
| 	[EAGLContext setCurrentContext:context];
 | |
| 	// glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
 | |
| 	// glViewport(0, 0, backingWidth, backingHeight);
 | |
| 
 | |
| #ifndef KINC_TVOS
 | |
| 	// Accelerometer updates
 | |
| 	if (hasAccelerometer) {
 | |
| 
 | |
| 		CMAcceleration acc = motionManager.accelerometerData.acceleration;
 | |
| 
 | |
| 		if (acc.x != lastAccelerometerX || acc.y != lastAccelerometerY || acc.z != lastAccelerometerZ) {
 | |
| 
 | |
| 			kinc_internal_on_acceleration(acc.x, acc.y, acc.z);
 | |
| 
 | |
| 			lastAccelerometerX = acc.x;
 | |
| 			lastAccelerometerY = acc.y;
 | |
| 			lastAccelerometerZ = acc.z;
 | |
| 		}
 | |
| 	}
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| - (void)end {
 | |
| }
 | |
| #else
 | |
| - (void)end {
 | |
| 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
 | |
| 	[context presentRenderbuffer:GL_RENDERBUFFER_OES]; // crash at end
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void kinc_internal_call_resize_callback(int window, int width, int height);
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| - (void)layoutSubviews {
 | |
| 	backingWidth = self.frame.size.width * self.contentScaleFactor;
 | |
| 	backingHeight = self.frame.size.height * self.contentScaleFactor;
 | |
| 
 | |
| 	CAMetalLayer *metalLayer = (CAMetalLayer *)self.layer;
 | |
| 	metalLayer.drawableSize = CGSizeMake(backingWidth, backingHeight);
 | |
| 
 | |
| 	kinc_internal_call_resize_callback(0, backingWidth, backingHeight);
 | |
| }
 | |
| #else
 | |
| - (void)layoutSubviews {
 | |
| 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
 | |
| 	[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
 | |
| 
 | |
| 	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
 | |
| 	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
 | |
| 
 | |
| 	printf("backingWitdh/Height: %i, %i\n", backingWidth, backingHeight);
 | |
| 
 | |
| 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
 | |
| 	glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, backingWidth, backingHeight);
 | |
| 
 | |
| 	if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
 | |
| 		NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
 | |
| 	}
 | |
| 
 | |
| 	kinc_internal_call_resize_callback(0, backingWidth, backingHeight);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| - (void)dealloc {
 | |
| }
 | |
| #else
 | |
| - (void)dealloc {
 | |
| 	if (defaultFramebuffer) {
 | |
| 		glDeleteFramebuffersOES(1, &defaultFramebuffer);
 | |
| 		defaultFramebuffer = 0;
 | |
| 	}
 | |
| 
 | |
| 	if (colorRenderbuffer) {
 | |
| 		glDeleteRenderbuffersOES(1, &colorRenderbuffer);
 | |
| 		colorRenderbuffer = 0;
 | |
| 	}
 | |
| 
 | |
| 	if (depthStencilRenderbuffer) {
 | |
| 		glDeleteRenderbuffersOES(1, &depthStencilRenderbuffer);
 | |
| 		depthStencilRenderbuffer = 0;
 | |
| 	}
 | |
| 
 | |
| 	if ([EAGLContext currentContext] == context)
 | |
| 		[EAGLContext setCurrentContext:nil];
 | |
| 
 | |
| 	//[context release];
 | |
| 	context = nil;
 | |
| 
 | |
| 	//[super dealloc];
 | |
| }
 | |
| #endif
 | |
| 
 | |
| - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 | |
| 	for (UITouch *touch in touches) {
 | |
| 		int index = getTouchIndex((__bridge void *)touch);
 | |
| 		if (index == -1)
 | |
| 			index = addTouch((__bridge void *)touch);
 | |
| 		if (index >= 0) {
 | |
| 			CGPoint point = [touch locationInView:self];
 | |
| 			float x = point.x * self.contentScaleFactor;
 | |
| 			float y = point.y * self.contentScaleFactor;
 | |
| 			if (index == 0) {
 | |
| 				kinc_internal_mouse_trigger_press(0, event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
 | |
| 			}
 | |
| 			kinc_internal_surface_trigger_touch_start(index, x, y);
 | |
| 
 | |
| 			if (touch.type == UITouchTypePencil) {
 | |
| 				kinc_internal_pen_trigger_press(0, x, y, 0.0);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 | |
| 	for (UITouch *touch in touches) {
 | |
| 		int index = getTouchIndex((__bridge void *)touch);
 | |
| 		if (index >= 0) {
 | |
| 			CGPoint point = [touch locationInView:self];
 | |
| 			float x = point.x * self.contentScaleFactor;
 | |
| 			float y = point.y * self.contentScaleFactor;
 | |
| 			if (index == 0) {
 | |
| 				kinc_internal_mouse_trigger_move(0, x, y);
 | |
| 			}
 | |
| 			kinc_internal_surface_trigger_move(index, x, y);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| - (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches {
 | |
| 	for (UITouch *touch in touches) {
 | |
| 		if (touch.type == UITouchTypePencil) {
 | |
| 			CGPoint point = [touch locationInView:self];
 | |
| 			float x = point.x * self.contentScaleFactor;
 | |
| 			float y = point.y * self.contentScaleFactor;
 | |
| 			kinc_internal_pen_trigger_move(0, x, y, touch.force);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 | |
| 	for (UITouch *touch in touches) {
 | |
| 		int index = removeTouch((__bridge void *)touch);
 | |
| 		if (index >= 0) {
 | |
| 			CGPoint point = [touch locationInView:self];
 | |
| 			float x = point.x * self.contentScaleFactor;
 | |
| 			float y = point.y * self.contentScaleFactor;
 | |
| 			if (index == 0) {
 | |
| 				kinc_internal_mouse_trigger_release(0, event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
 | |
| 			}
 | |
| 			kinc_internal_surface_trigger_touch_end(index, x, y);
 | |
| 
 | |
| 			if (touch.type == UITouchTypePencil) {
 | |
| 				kinc_internal_pen_trigger_release(0, x, y, 0.0);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
 | |
| 	for (UITouch *touch in touches) {
 | |
| 		int index = removeTouch((__bridge void *)touch);
 | |
| 		if (index >= 0) {
 | |
| 			CGPoint point = [touch locationInView:self];
 | |
| 			float x = point.x * self.contentScaleFactor;
 | |
| 			float y = point.y * self.contentScaleFactor;
 | |
| 			if (index == 0) {
 | |
| 				kinc_internal_mouse_trigger_release(0, event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
 | |
| 			}
 | |
| 			kinc_internal_surface_trigger_touch_end(index, x, y);
 | |
| 
 | |
| 			if (touch.type == UITouchTypePencil) {
 | |
| 				kinc_internal_pen_trigger_release(0, x, y, 0.0);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static NSString *keyboardstring;
 | |
| static UITextField *myTextField = NULL;
 | |
| static bool shiftDown = false;
 | |
| 
 | |
| - (void)showKeyboard {
 | |
| 	[self becomeFirstResponder];
 | |
| }
 | |
| 
 | |
| - (void)hideKeyboard {
 | |
| 	[self resignFirstResponder];
 | |
| }
 | |
| 
 | |
| - (BOOL)hasText {
 | |
| 	return YES;
 | |
| }
 | |
| 
 | |
| - (void)insertText:(NSString *)text {
 | |
| 	if ([text length] == 1) {
 | |
| 		unichar ch = [text characterAtIndex:[text length] - 1];
 | |
| 		if (ch == 8212)
 | |
| 			ch = '_';
 | |
| 		if (ch == L'\n') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_RETURN);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_RETURN);
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		if (ch == L'.') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_PERIOD);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_PERIOD);
 | |
| 		}
 | |
| 		else if (ch == L'%') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_PERCENT);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_PERCENT);
 | |
| 		}
 | |
| 		else if (ch == L'(') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_OPEN_PAREN);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_OPEN_PAREN);
 | |
| 		}
 | |
| 		else if (ch == L'&') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_AMPERSAND);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_AMPERSAND);
 | |
| 		}
 | |
| 		else if (ch == L'$') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_DOLLAR);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_DOLLAR);
 | |
| 		}
 | |
| 		else if (ch == L'#') {
 | |
| 			kinc_internal_keyboard_trigger_key_down(KINC_KEY_HASH);
 | |
| 			kinc_internal_keyboard_trigger_key_up(KINC_KEY_HASH);
 | |
| 		}
 | |
| 		else if (ch >= L'a' && ch <= L'z') {
 | |
| 			if (shiftDown) {
 | |
| 				kinc_internal_keyboard_trigger_key_up(KINC_KEY_SHIFT);
 | |
| 				shiftDown = false;
 | |
| 			}
 | |
| 			kinc_internal_keyboard_trigger_key_down(ch + KINC_KEY_A - L'a');
 | |
| 			kinc_internal_keyboard_trigger_key_up(ch + KINC_KEY_A - L'a');
 | |
| 		}
 | |
| 		else {
 | |
| 			if (!shiftDown) {
 | |
| 				kinc_internal_keyboard_trigger_key_down(KINC_KEY_SHIFT);
 | |
| 				shiftDown = true;
 | |
| 			}
 | |
| 			kinc_internal_keyboard_trigger_key_down(ch + KINC_KEY_A - L'A');
 | |
| 			kinc_internal_keyboard_trigger_key_up(ch + KINC_KEY_A - L'A');
 | |
| 		}
 | |
| 
 | |
| 		kinc_internal_keyboard_trigger_key_press(ch);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| - (void)deleteBackward {
 | |
| 	kinc_internal_keyboard_trigger_key_down(KINC_KEY_BACKSPACE);
 | |
| 	kinc_internal_keyboard_trigger_key_up(KINC_KEY_BACKSPACE);
 | |
| }
 | |
| 
 | |
| - (BOOL)canBecomeFirstResponder {
 | |
| 	return YES;
 | |
| }
 | |
| 
 | |
| - (void)onKeyboardHide:(NSNotification *)notification {
 | |
| 	kinc_keyboard_hide();
 | |
| }
 | |
| 
 | |
| #ifdef KINC_METAL
 | |
| - (CAMetalLayer *)metalLayer {
 | |
| 	return (CAMetalLayer *)self.layer;
 | |
| }
 | |
| 
 | |
| - (id<MTLDevice>)metalDevice {
 | |
| 	return device;
 | |
| }
 | |
| 
 | |
| - (id<MTLLibrary>)metalLibrary {
 | |
| 	return library;
 | |
| }
 | |
| 
 | |
| - (id<MTLCommandQueue>)metalQueue {
 | |
| 	return commandQueue;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| @end
 |