ios - Representación a petición de OpenGL ES utilizando GLKit
opengl-es (3)
Estoy buscando convertir mi código de representación OpenGL para aprovechar algunas de las características de GLKit
(a saber, la carga asíncrona de texturas y la automatización proporcionada por GLKView/Controller
). Sin embargo, parece que las clases están diseñadas principalmente para adaptarse a la representación de personas mediante un bucle de animación, mientras que estoy trabajando con la representación a petición. Además, parte de la representación es a una textura en lugar del framebuffer de GLKView, ¿así que debería buscar solo una subclase de GLKView y agregar FBO adicionales?
¿Hay un enfoque recomendado para este tipo de configuración? Yo esperaría algo como:
- Establezca el cuadro de control
preferredFramesPerSecond
de fotogramas por segundo en0
, o simplemente pause las actualizaciones de cuadros? - Ignore los
glkViewControllerUpdate
oglkView:drawInRect:
y simplemente dibuje lo que necesito, cuando lo necesite. - Use el
setNeedsDisplay
la vista como con unUIView
normal para mostrar el marco (¿necesito llamar abindDrawable
dado que también estaré renderizando a una textura?).
¿Quizás no valga la pena el esfuerzo si esto no es para lo que está diseñada la nueva API? Me gustaría que la documentación fuera un poco más completa de lo que es. Quizás se proporcionarán más muestras cuando la API haya ''madurado'' un poco ...
Gracias
Acabo de convertir mi código de usar un administrador de EAGLContext al que me dediqué a usar las clases de GLKit.
Usted sugiere que podría "... ignorar los ... glkView:drawInRect:
métodos y simplemente dibujar lo que [usted] necesite, cuando lo necesite". Esto parece una opción sensata en cuanto al rendimiento; Supongo (aunque no lo he intentado) si simplemente no especifica un GLKViewDelegate
o no proporciona un GLKView
subclasificado con su drawInRect:
definido, entonces no se producirá la representación en bucle de animación. ¿Has intentado esto?
La alternativa sería simplemente crear algún @property (assign, nonatomic) BOOL shouldUpdate;
en su MyController : GLKViewController <GLKViewDelegate>
que solo se actualizará si hay algo que hacer:
[self setDelegate:self]; // in init or awakeFromNib or other..
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
if ([self shouldUpdate]) { ...
Estoy seguro de que entiendes la idea, es apenas complicado.
Una cosa que vale la pena mencionar: los documentos oficiales de la API establecen que viewDidLoad
debe usarse en su GLKViewController
para la configuración inicial de GL. Tuve problemas con esto; por alguna razón, mis llamadas a glCreateShader
siempre devolvían cero. Esto puede deberse a que configuré la post-inicialización de EAGLContext
; No pude pasarlo como un parámetro de init
ya que creé el controlador en Storyboard. Sin embargo, no hubo ningún error lógico con el código, por lo que ofrezco esta advertencia amigable en caso de que encuentre problemas similares. Mi solución es simplemente tener lo siguiente en mi drawInRect:
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
if ([self initialGLSetupDone] == NO) {
[self beforeFirstRender];
[self setInitialGLSetupDone:YES];
}
// .. rest of render code goes here.
}
Obviamente, no es ideal tener un IF allí innecesariamente, pero fue una solución fácil.
Déjame saber cómo te va si intentas actualizar para usar GLKit.
Después de haber creado GLKView, agregue esta línea:
glkView.enableSetNeedsDisplay = TRUE;
(Debido a esto, nadie volverá a dibujar la vista automáticamente)
Cuando quieras volver a dibujar, inserta esta línea:
[glkView setNeedsDisplay];
... entonces la rutina drawInRect
se llamará solo una vez.
Espero eso ayude.
El enfoque que terminé usando era no molestarme con GLKViewController
, sino simplemente usar GLKView
directamente bajo una subclase UIViewController
.
Claramente, el GLKViewController
está diseñado para ser utilizado por personas que necesitan un bucle de representación consistente para aplicaciones como juegos. Sin él, dibujar en GLKView
es tan simple como llamar a [glkView setNeedsDisplay]
. Asegúrese de establecer enableSetNeedsDisplay
en YES
para habilitar este comportamiento.
Si aún desea hacer uso de un GLKViewController
, puede deshabilitar el bucle de renderizado de animación en la vista. viewWillAppear
así:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // setPaused automatically set to NO in super''s implementation
[self setPaused:YES];
}
Además, establezca resumeOnDidBecomeActive
en NO
para evitar que el controlador de vista se resumeOnDidBecomeActive
de nuevo automáticamente.
Sin embargo, el uso de un UIViewController
plano con un GLKView
es perfectamente aceptable, y lo he visto recomendado por un ingeniero de Apple como una forma adecuada de realizar dibujos a pedido.