2010-12-21 12 views
6

Estoy tratando de que la aplicación de código de muestra avTouch se ejecute en la pantalla Retina. ¿Alguien ha hecho esto?openGL ES retina support

En la clase CALevelMeter, he intentado lo siguiente:

- (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; 

}

y se establece el contentScaleFactor a "2". Genial, eso era lo esperado. Pero luego en el layoutSubviews, CALevelMeter frame sigue siendo 1/2 de lo que debería ser.

¿Alguna idea?

Respuesta

11

Los marcos están en puntos, no en píxeles. Cuando se aplica un factor de escala al UIView que aloja su CAEAGLLayer, será el doble de píxeles, pero su tamaño de punto de marco seguirá siendo el mismo.

Si nos fijamos en el ancho respaldo y la altura de la renderbuffer de color unido a la CAEAGLLayer utilizando código como el siguiente:

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

debería ver que la anchura y la altura de la renderbuffer en una pantalla Retina son el doble de los valores que tienen en una pantalla estándar de iPhone.

El código que muestra arriba debe causar un renderizado agradable y nítido en una pantalla Retina.

EDITAR (12/22/2010): En respuesta a su pregunta adicional, al mirar el código de ejemplo de avTouch se muestra que la versión actual de ese código comete un error al buscar los límites de la vista de alojamiento de OpenGL, en lugar de que usar el ancho y la altura de respaldo del renderbuffer. Con un factor de escala no-1.0, esto hará que el contenido de OpenGL se dibuje a la mitad de tamaño.

Para solucionar este problema, reemplace la sección correspondiente dentro _drawView en GLLevelMeter con el siguiente código:

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); 
} 

Esto hará que todo funcione en el espacio de píxeles adecuada, y llevar a crujientes representación en el tamaño correcto en El Equalizador. He archivado un informe de error sobre esto.

+0

¿Pero la retina no muestra el doble del tamaño del marco para dar cuenta de la resolución más alta? Incluso después de agregar el código que mencioné, solo obtengo un medidor de 1/2 de altura. Este es solo el caso del medidor OpenGL. El medidor UIView funciona bien con retina. Estoy perplejo. – Bryan

+1

@Bryan: al mirar el código de muestra de avTouch, parece que Apple ha cometido un error en la forma en que implementaron '_drawView' en GLLevelMeter. Están usando los límites de la vista, que está en puntos, para determinar el tamaño de las cosas en OpenGL, cuando en su lugar deberían usar las variables de instancia '_backingWidth' y' _backingHeight'. Reemplace las referencias al tamaño y la altura de los límites con '_backingWidth' y' _backingHeight' y esto se dibujará correctamente en una pantalla Retina. Archivaré un informe de error en el código de muestra. –

+0

@Bryan: he localizado el código que debe modificarse en la edición de mi respuesta. –