Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openGL ES retina support

I'm trying to get the avTouch sample code app to run on the retina display. Has anyone done this?

In the CALevelMeter class, I've tried the following:

- (id)initWithCoder:(NSCoder *)coder {
 if (self = [super initWithCoder:coder]) {
      CGFloat f = self.contentScaleFactor;
      if ([self respondsToSelector:@selector(contentScaleFactor)])
      {
           self.contentScaleFactor = [[UIScreen mainScreen] scale];
      }
      f = self.contentScaleFactor;

      _showsPeaks = YES;
      _channelNumbers = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:0], nil];
      _vertical = NO;
      _useGL = YES;
      _meterTable = new MeterTable(kMinDBvalue);
      [self layoutSubLevelMeters];
      [self registerForBackgroundNotifications];
 }
 return self;

}

and it sets the contentScaleFactor to "2". Great, that was expected. But then in the layoutSubviews, CALevelMeter frame is still 1/2 of what it should be.

Any ideas?

like image 526
Bryan Avatar asked Dec 21 '10 22:12

Bryan


1 Answers

Frames are in points, not pixels. When a scale factor is applied to the UIView hosting your CAEAGLLayer, it will be double the pixels, but its frame point size will remain the same.

If you look at the backing width and height for the color renderbuffer attached to the CAEAGLLayer using code like the following:

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

you should see that the width and height of the renderbuffer on a Retina display are twice the values they are on a standard iPhone display.

The code you show above should cause nice, sharp rendering on a Retina display.

EDIT (12/22/2010): In response to your further question, looking at the avTouch sample code shows that the current version of that code makes a mistake in looking up the bounds of the OpenGL-hosting view, rather than using the backing width and height of the renderbuffer. With a non-1.0 scale factor, this will cause the OpenGL content to be drawn at half size.

To fix this, replace the appropriate section within _drawView in GLLevelMeter with the following code:

if (_vertical)
{
    glTranslatef(0., _backingWidth, 0.);
    glScalef(1., -1., 1.);
    bds = CGRectMake(0., 0., _backingWidth, _backingHeight);
} else {
    glTranslatef(0., _backingHeight, 0.);
    glRotatef(-90., 0., 0., 1.);
    bds = CGRectMake(0., 0., _backingHeight, _backingWidth);
}

This will cause everything to work in the appropriate pixel space, and lead to crisp rendering at the correct size in the equalizer. I've filed a bug report on this.

like image 93
Brad Larson Avatar answered Sep 18 '22 02:09

Brad Larson