diff --git a/contrib/mobile/drawContext.cpp b/contrib/mobile/drawContext.cpp index 24a19cb4c14e8fed6fc4fbe1203593aea82c7812..c0ca2160bbff5a56aa01bc8bec9a982036b89478 100644 --- a/contrib/mobile/drawContext.cpp +++ b/contrib/mobile/drawContext.cpp @@ -53,7 +53,7 @@ static bool locked = false; static bool onelabStop = false; -drawContext::drawContext(float fontFactor) +drawContext::drawContext(float fontFactor, bool retina) { GmshInitialize(); GmshSetOption("General", "Terminal", 1.0); @@ -67,6 +67,7 @@ drawContext::drawContext(float fontFactor) _fillMesh = false; _gradiant = true; _fontFactor = fontFactor; + _retina = retina; } static void checkGlError(const char* op) @@ -104,8 +105,14 @@ void drawContext::load(std::string filename) void drawContext::eventHandler(int event, float x, float y) { + int width = _width, height = _height; + if(_retina){ // x,y for retina are still the same as for non-retina + width /= 2; + height /= 2; + } + _current.set(_scale, _translate, _right, _left, - _bottom, _top, _width, _height, x, y); + _bottom, _top, width, height, x, y); double xx[3] = {1.,0.,0.}; double yy[3] = {0.,1.,0.}; double q[4]; @@ -113,12 +120,13 @@ void drawContext::eventHandler(int event, float x, float y) case 0: // finger(s) press the screen // in this case x and y represent the start point _start.set(_scale, _translate, _right, _left, - _bottom, _top, _width, _height, x, y); + _bottom, _top, width, height, x, y); _previous.set(_scale, _translate, _right, _left, - _bottom, _top, _width, _height, x, y); + _bottom, _top, width, height, x, y); break; case 1: // finger move (translate) // in this case x and y represent the current point + printf("currx=%g prevx=%g\n", _current.wnr[0],_previous.wnr[0]); _translate[0] += (_current.wnr[0] - _previous.wnr[0]); _translate[1] += (_current.wnr[1] - _previous.wnr[1]); _translate[2] = 0.; @@ -130,10 +138,10 @@ void drawContext::eventHandler(int event, float x, float y) _start.recenter(_scale, _translate); break; case 3: // fingers move (rotate) - addQuaternion((2. * _previous.win[0] - _width) / _width, - (_height - 2. * _previous.win[1]) / _height, - (2. * _current.win[0] - _width) / _width, - (_height - 2. * _current.win[1]) / _height); + addQuaternion((2. * _previous.win[0] - width) / width, + (height - 2. * _previous.win[1]) / height, + (2. * _current.win[0] - width) / width, + (height - 2. * _current.win[1]) / height); break; case 4: // release the finger(s) // Do nothing ? @@ -158,7 +166,7 @@ void drawContext::eventHandler(int event, float x, float y) break; } _previous.set(_scale, _translate, _right, _left, - _bottom, _top, _width, _height, x, y); + _bottom, _top, width, height, x, y); } void drawContext::setQuaternion(double q0, double q1, double q2, double q3) @@ -185,7 +193,6 @@ void drawContext::buildRotationMatrix() void drawContext::OrthofFromGModel() { -#if 1 // new version double Va = (double)_height / (double)_width; double Wa = (CTX::instance()->max[1] - CTX::instance()->min[1]) / (CTX::instance()->max[0] - CTX::instance()->min[0]); @@ -234,48 +241,6 @@ void drawContext::OrthofFromGModel() _top = vymax; _bottom = vymin; _far = clip_far; - -#else - SBoundingBox3d bb = GModel::current()->bounds(); - double ratio = (double)(_width ? _width : 1.) / - (double)(_height ? _height : 1.); - double bbRation = (bb.max().x() - bb.min().x()) / (bb.max().y() - bb.min().y()); - double xmin = -ratio, xmax = ratio, ymin = -1., ymax = 1.; - if(bbRation < 1) { - xmin = bb.min().y() * ratio + bb.max().x() + bb.min().x(); - xmax = bb.max().y() * ratio + bb.max().x() + bb.min().x(); - ymin = bb.min().y() + bb.max().y() + bb.min().y(); - ymax = bb.max().y() + bb.max().y() + bb.min().y(); - } - else { - xmin = bb.min().x() + bb.max().x() + bb.min().x(); - xmax = bb.max().x() + bb.max().x() + bb.min().x(); - ymin = bb.min().x() / ratio + bb.max().y() + bb.min().y(); - ymax = bb.max().x() / ratio + bb.max().y() + bb.min().y(); - } - xmax += (xmax - xmin) / 5.; - xmin -= (xmax - xmin) / 5.; - ymax += (ymax - ymin) / 5.; - ymin -= (ymax - ymin) / 5.; - - // clipping - double zmax = std::max(std::max(std::max(fabs(bb.min().z()), fabs(bb.max().z())), - std::max(fabs(bb.min().x()), fabs(bb.max().x()))), - std::max(fabs(bb.min().y()), fabs(bb.max().y()))); - double clip = zmax * 1.5; - - GLint matrixMode; - glGetIntegerv(GL_MATRIX_MODE, &matrixMode); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - _left = (xmin != 0 || xmax != 0)? xmin : -ratio; - _right = (xmin != 0 || xmax != 0)? xmax : ratio; - _top = (xmin != 0 || xmax != 0)? ymax : 1.0; - _bottom = (xmin != 0 || xmax != 0)? ymin : -1.0; - _far = -clip; - glOrthof(_left, _right, _bottom, _top, -clip, clip); - glMatrixMode(matrixMode); -#endif } void drawContext::initView(int w, int h) diff --git a/contrib/mobile/drawContext.h b/contrib/mobile/drawContext.h index 4ce28c79057d0951f3389480fe11dee4c01f8610..3929eff03bd7b863555a603e204c56b310e4dae4 100644 --- a/contrib/mobile/drawContext.h +++ b/contrib/mobile/drawContext.h @@ -39,12 +39,13 @@ private: float _fontFactor; bool _gradiant; // show the background gradiant bool _fillMesh; // fill the Mesh - + bool _retina; // retina display + void OrthofFromGModel(void); void drawPView(PView *p); void drawVectorArray(PViewOptions *opt, VertexArray *va); public: - drawContext(float fontFactor=1.); + drawContext(float fontFactor=1., bool retina=false); ~drawContext(){} void load(std::string filename); void eventHandler(int event, float x=0, float y=0); diff --git a/contrib/mobile/iOS/Onelab/EAGLView.mm b/contrib/mobile/iOS/Onelab/EAGLView.mm index 04b4cba825a7507506db8d8f3c97dce297716d0b..3314df0db6a6f1d28fc56e0e6899d2d2f73ce8d7 100644 --- a/contrib/mobile/iOS/Onelab/EAGLView.mm +++ b/contrib/mobile/iOS/Onelab/EAGLView.mm @@ -22,167 +22,169 @@ // You must implement this + (Class)layerClass { - return [CAEAGLLayer class]; + 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; - - int w = 320; - int h = 480; - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2f) { // There is no retina display above 3.2 - UIScreen* mainscr = [UIScreen mainScreen]; - w = mainscr.currentMode.size.width; - h = mainscr.currentMode.size.height; - } - if ((w == 640 && h == 960) || (h == 1136 && w == 640) || (h == 1536 && w == 2048)) { // Retina display (iPhone or iPhone 4-inch or iPad/iPad mini) - self.contentScaleFactor = 2.0; - eaglLayer.contentsScale=2; - } - - 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; - } - mContext = new drawContext((eaglLayer.contentsScale==2)? 1.5:1); + if ((self = [super initWithCoder:coder])) { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + int w = 320; + int h = 480; + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2f) { + // There is no retina display above 3.2 + UIScreen* mainscr = [UIScreen mainScreen]; + w = mainscr.currentMode.size.width; + h = mainscr.currentMode.size.height; } - rendering = NO; - return self; + if ((w == 640 && h == 960) || + (h == 1136 && w == 640) || + (h == 1536 && w == 2048)) { + // Retina display (iPhone or iPhone 4-inch or iPad/iPad mini) + self.contentScaleFactor = 2.0; + eaglLayer.contentsScale=2; + } + 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; + } + mContext = new drawContext((eaglLayer.contentsScale==2) ? 1.5 : 1, + eaglLayer.contentsScale==2); + } + rendering = NO; + return self; } - (void)drawView { - if(rendering) return; - rendering = YES; - [EAGLContext setCurrentContext:context]; - - glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); - mContext->initView(backingWidth, backingHeight); - mContext->drawView(); - - glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); - [context presentRenderbuffer:GL_RENDERBUFFER_OES]; - rendering = NO; + if(rendering) return; + rendering = YES; + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + mContext->initView(backingWidth, backingHeight); + mContext->drawView(); + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; + rendering = NO; } - (void)load:(NSString*) file { - mContext->load(*new std::string([file fileSystemRepresentation])); - [[NSNotificationCenter defaultCenter] postNotificationName:@"resetParameters" object:nil]; - [self drawView]; + mContext->load(*new std::string([file fileSystemRepresentation])); + [[NSNotificationCenter defaultCenter] postNotificationName:@"resetParameters" object:nil]; + [self drawView]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSUInteger ntouch = [[event allTouches] count]; - UITouch* touch = [touches anyObject]; - CGPoint position = [touch locationInView:self]; - if(ntouch != 1) return; - if(rotate) - mContext->eventHandler(3,position.x,position.y); - else - mContext->eventHandler(1,position.x,position.y); - - [self drawView]; + NSUInteger ntouch = [[event allTouches] count]; + UITouch* touch = [touches anyObject]; + CGPoint position = [touch locationInView:self]; + if(ntouch != 1) return; + if(rotate) + mContext->eventHandler(3,position.x,position.y); + else + mContext->eventHandler(1,position.x,position.y); + + [self drawView]; } - (void)layoutSubviews { - [super layoutSubviews]; - [EAGLContext setCurrentContext:context]; - [self destroyFramebuffer]; - [self createFramebuffer]; - [self drawView]; + [super 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; + 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; - } + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + if(depthRenderbuffer) { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } } - (void)dealloc { - if ([EAGLContext currentContext] == context) { - [EAGLContext setCurrentContext:nil]; - } + if ([EAGLContext currentContext] == context) { + [EAGLContext setCurrentContext:nil]; + } } - (UIImage*) getGLScreenshot { - NSInteger myDataLength = backingWidth * backingHeight * 4; - - GLubyte *buffer = (GLubyte *) malloc(myDataLength); - glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - - GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); - for(int y = 0; y <backingHeight; y++) - { - for(int x = 0; x <backingWidth * 4; x++) - { - buffer2[(backingHeight - 1 - y) * backingWidth * 4 + x] = buffer[y * 4 * backingWidth + x]; - } + NSInteger myDataLength = backingWidth * backingHeight * 4; + + GLubyte *buffer = (GLubyte *) malloc(myDataLength); + glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); + for(int y = 0; y <backingHeight; y++){ + for(int x = 0; x <backingWidth * 4; x++){ + buffer2[(backingHeight - 1 - y) * backingWidth * 4 + x] = buffer[y * 4 * backingWidth + x]; } + } - CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); - int bitsPerComponent = 8; - int bitsPerPixel = 32; - int bytesPerRow = 4 * backingWidth; - CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); - CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; - CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; + int bitsPerComponent = 8; + int bitsPerPixel = 32; + int bytesPerRow = 4 * backingWidth; + CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); + CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; + CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; - CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); - free(buffer); - free(buffer2); - return [UIImage imageWithCGImage:imageRef]; + CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); + free(buffer); + free(buffer2); + return [UIImage imageWithCGImage:imageRef]; } - (void)saveGLScreenshotToPhotosAlbum { - UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil); + UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil); } @end