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
Branches
Tags
No related merge requests found
......@@ -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)
......
......@@ -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);
......
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment