Skip to content
Snippets Groups Projects
Commit 84646015 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

fix translate/rotate with retina display

parent a470f0a0
No related branches found
No related tags found
No related merge requests found
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
static bool locked = false; static bool locked = false;
static bool onelabStop = false; static bool onelabStop = false;
drawContext::drawContext(float fontFactor) drawContext::drawContext(float fontFactor, bool retina)
{ {
GmshInitialize(); GmshInitialize();
GmshSetOption("General", "Terminal", 1.0); GmshSetOption("General", "Terminal", 1.0);
...@@ -67,6 +67,7 @@ drawContext::drawContext(float fontFactor) ...@@ -67,6 +67,7 @@ drawContext::drawContext(float fontFactor)
_fillMesh = false; _fillMesh = false;
_gradiant = true; _gradiant = true;
_fontFactor = fontFactor; _fontFactor = fontFactor;
_retina = retina;
} }
static void checkGlError(const char* op) static void checkGlError(const char* op)
...@@ -104,8 +105,14 @@ void drawContext::load(std::string filename) ...@@ -104,8 +105,14 @@ void drawContext::load(std::string filename)
void drawContext::eventHandler(int event, float x, float y) 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, _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 xx[3] = {1.,0.,0.};
double yy[3] = {0.,1.,0.}; double yy[3] = {0.,1.,0.};
double q[4]; double q[4];
...@@ -113,12 +120,13 @@ void drawContext::eventHandler(int event, float x, float y) ...@@ -113,12 +120,13 @@ void drawContext::eventHandler(int event, float x, float y)
case 0: // finger(s) press the screen case 0: // finger(s) press the screen
// in this case x and y represent the start point // in this case x and y represent the start point
_start.set(_scale, _translate, _right, _left, _start.set(_scale, _translate, _right, _left,
_bottom, _top, _width, _height, x, y); _bottom, _top, width, height, x, y);
_previous.set(_scale, _translate, _right, _left, _previous.set(_scale, _translate, _right, _left,
_bottom, _top, _width, _height, x, y); _bottom, _top, width, height, x, y);
break; break;
case 1: // finger move (translate) case 1: // finger move (translate)
// in this case x and y represent the current point // 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[0] += (_current.wnr[0] - _previous.wnr[0]);
_translate[1] += (_current.wnr[1] - _previous.wnr[1]); _translate[1] += (_current.wnr[1] - _previous.wnr[1]);
_translate[2] = 0.; _translate[2] = 0.;
...@@ -130,10 +138,10 @@ void drawContext::eventHandler(int event, float x, float y) ...@@ -130,10 +138,10 @@ void drawContext::eventHandler(int event, float x, float y)
_start.recenter(_scale, _translate); _start.recenter(_scale, _translate);
break; break;
case 3: // fingers move (rotate) case 3: // fingers move (rotate)
addQuaternion((2. * _previous.win[0] - _width) / _width, addQuaternion((2. * _previous.win[0] - width) / width,
(_height - 2. * _previous.win[1]) / _height, (height - 2. * _previous.win[1]) / height,
(2. * _current.win[0] - _width) / _width, (2. * _current.win[0] - width) / width,
(_height - 2. * _current.win[1]) / _height); (height - 2. * _current.win[1]) / height);
break; break;
case 4: // release the finger(s) case 4: // release the finger(s)
// Do nothing ? // Do nothing ?
...@@ -158,7 +166,7 @@ void drawContext::eventHandler(int event, float x, float y) ...@@ -158,7 +166,7 @@ void drawContext::eventHandler(int event, float x, float y)
break; break;
} }
_previous.set(_scale, _translate, _right, _left, _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) void drawContext::setQuaternion(double q0, double q1, double q2, double q3)
...@@ -185,7 +193,6 @@ void drawContext::buildRotationMatrix() ...@@ -185,7 +193,6 @@ void drawContext::buildRotationMatrix()
void drawContext::OrthofFromGModel() void drawContext::OrthofFromGModel()
{ {
#if 1 // new version
double Va = (double)_height / (double)_width; double Va = (double)_height / (double)_width;
double Wa = (CTX::instance()->max[1] - CTX::instance()->min[1]) / double Wa = (CTX::instance()->max[1] - CTX::instance()->min[1]) /
(CTX::instance()->max[0] - CTX::instance()->min[0]); (CTX::instance()->max[0] - CTX::instance()->min[0]);
...@@ -234,48 +241,6 @@ void drawContext::OrthofFromGModel() ...@@ -234,48 +241,6 @@ void drawContext::OrthofFromGModel()
_top = vymax; _top = vymax;
_bottom = vymin; _bottom = vymin;
_far = clip_far; _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) void drawContext::initView(int w, int h)
......
...@@ -39,12 +39,13 @@ private: ...@@ -39,12 +39,13 @@ private:
float _fontFactor; float _fontFactor;
bool _gradiant; // show the background gradiant bool _gradiant; // show the background gradiant
bool _fillMesh; // fill the Mesh bool _fillMesh; // fill the Mesh
bool _retina; // retina display
void OrthofFromGModel(void); void OrthofFromGModel(void);
void drawPView(PView *p); void drawPView(PView *p);
void drawVectorArray(PViewOptions *opt, VertexArray *va); void drawVectorArray(PViewOptions *opt, VertexArray *va);
public: public:
drawContext(float fontFactor=1.); drawContext(float fontFactor=1., bool retina=false);
~drawContext(){} ~drawContext(){}
void load(std::string filename); void load(std::string filename);
void eventHandler(int event, float x=0, float y=0); void eventHandler(int event, float x=0, float y=0);
......
...@@ -22,167 +22,169 @@ ...@@ -22,167 +22,169 @@
// You must implement this // You must implement this
+ (Class)layerClass + (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: //The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder - (id)initWithCoder:(NSCoder*)coder
{ {
if ((self = [super initWithCoder:coder])) { if ((self = [super initWithCoder:coder])) {
// Get the layer // Get the layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
int w = 320;
int w = 320; int h = 480;
int h = 480; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2f) {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2f) { // There is no retina display above 3.2 // There is no retina display above 3.2
UIScreen* mainscr = [UIScreen mainScreen]; UIScreen* mainscr = [UIScreen mainScreen];
w = mainscr.currentMode.size.width; w = mainscr.currentMode.size.width;
h = mainscr.currentMode.size.height; 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);
} }
rendering = NO; if ((w == 640 && h == 960) ||
return self; (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 - (void)drawView
{ {
if(rendering) return; if(rendering) return;
rendering = YES; rendering = YES;
[EAGLContext setCurrentContext:context]; [EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
mContext->initView(backingWidth, backingHeight); mContext->initView(backingWidth, backingHeight);
mContext->drawView(); mContext->drawView();
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES]; [context presentRenderbuffer:GL_RENDERBUFFER_OES];
rendering = NO; rendering = NO;
} }
- (void)load:(NSString*) file - (void)load:(NSString*) file
{ {
mContext->load(*new std::string([file fileSystemRepresentation])); mContext->load(*new std::string([file fileSystemRepresentation]));
[[NSNotificationCenter defaultCenter] postNotificationName:@"resetParameters" object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"resetParameters" object:nil];
[self drawView]; [self drawView];
} }
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ {
NSUInteger ntouch = [[event allTouches] count]; NSUInteger ntouch = [[event allTouches] count];
UITouch* touch = [touches anyObject]; UITouch* touch = [touches anyObject];
CGPoint position = [touch locationInView:self]; CGPoint position = [touch locationInView:self];
if(ntouch != 1) return; if(ntouch != 1) return;
if(rotate) if(rotate)
mContext->eventHandler(3,position.x,position.y); mContext->eventHandler(3,position.x,position.y);
else else
mContext->eventHandler(1,position.x,position.y); mContext->eventHandler(1,position.x,position.y);
[self drawView]; [self drawView];
} }
- (void)layoutSubviews - (void)layoutSubviews
{ {
[super layoutSubviews]; [super layoutSubviews];
[EAGLContext setCurrentContext:context]; [EAGLContext setCurrentContext:context];
[self destroyFramebuffer]; [self destroyFramebuffer];
[self createFramebuffer]; [self createFramebuffer];
[self drawView]; [self drawView];
} }
- (BOOL)createFramebuffer - (BOOL)createFramebuffer
{ {
glGenFramebuffersOES(1, &viewFramebuffer); glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer); glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); 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_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (USE_DEPTH_BUFFER) { if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, &depthRenderbuffer); glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
} }
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO; return NO;
} }
return YES; return YES;
} }
- (void)destroyFramebuffer - (void)destroyFramebuffer
{ {
glDeleteFramebuffersOES(1, &viewFramebuffer); glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0; viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer); glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0; viewRenderbuffer = 0;
if(depthRenderbuffer) { if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer); glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0; depthRenderbuffer = 0;
} }
} }
- (void)dealloc - (void)dealloc
{ {
if ([EAGLContext currentContext] == context) { if ([EAGLContext currentContext] == context) {
[EAGLContext setCurrentContext:nil]; [EAGLContext setCurrentContext:nil];
} }
} }
- (UIImage*) getGLScreenshot - (UIImage*) getGLScreenshot
{ {
NSInteger myDataLength = backingWidth * backingHeight * 4; NSInteger myDataLength = backingWidth * backingHeight * 4;
GLubyte *buffer = (GLubyte *) malloc(myDataLength); GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y <backingHeight; y++) for(int y = 0; y <backingHeight; y++){
{ for(int x = 0; x <backingWidth * 4; x++){
for(int x = 0; x <backingWidth * 4; x++) buffer2[(backingHeight - 1 - y) * backingWidth * 4 + x] = buffer[y * 4 * backingWidth + 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 bitsPerComponent = 8;
int bitsPerPixel = 32; int bitsPerPixel = 32;
int bytesPerRow = 4 * backingWidth; int bytesPerRow = 4 * backingWidth;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
free(buffer); free(buffer);
free(buffer2); free(buffer2);
return [UIImage imageWithCGImage:imageRef]; return [UIImage imageWithCGImage:imageRef];
} }
- (void)saveGLScreenshotToPhotosAlbum { - (void)saveGLScreenshotToPhotosAlbum {
UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil); UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil);
} }
@end @end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment