Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
747 views
in Technique[技术] by (71.8m points)

iphone - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...