Pregunta

Estoy escribiendo una aplicación para iPhone que usa UIView con CAEAGLayer como capa.Todo está bien y funcionando, salvo un pequeño problema:a veces falla con EXC_BAD_ACCESS y el siguiente seguimiento de pila:

    [EAGLView draw]
    glDrawArrays_Exec
    PrepareToDraw
    DrawFramebufferMakeResident
    AttachmentMakeResident
    TextureMakeResident
    memmove

se bloquea en la línea:

    glVertexPointer(3, GL_FLOAT, 0, vertexCoordinates);
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates);
    glBindTexture(GL_TEXTURE_2D, textures[kActiveSideLeft]);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, totalPoints); //<--Crash here

La aplicación solo fallará durante el cambio de rotación de la interfaz (ese también es el único caso cuando cambia el marco de vista).No falla con frecuencia;la mayoría de las veces, se necesitan entre 3 y 5 minutos de rotación del dispositivo para reproducir este problema.
Creo que estoy cometiendo un error relacionado con la inicialización/cambio de marco de CAEAGLLayer, ya que ahí es donde falla (creo).
Aquí están los métodos de subvistas de inicio y diseño:
En eso:

    ...
    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;     
    eaglLayer.opaque = TRUE;

    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    if (!context || ![EAGLContext setCurrentContext:context])
    {
        [self release];
        return nil;
    }

    glGenFramebuffersOES(1, &defaultFramebuffer);
    glGenRenderbuffersOES(1, &colorRenderbuffer);
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    ...

En el marco establecido solo configuro las matrices GL_MODELVIEW y GL_POJECTION, así que supongo que no puede pasar nada malo allí.
DiseñoSubvistas:

    - (void)layoutSubviews
    {
      [EAGLContext setCurrentContext:context];

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);

        NSAssert1(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES, @"Failed to make complete framebuffer object: %X", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
    }

El método de dibujo en sí se parece a:

        if ([EAGLContext currentContext] != context) {
            [EAGLContext setCurrentContext:context];
        }

        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
        glViewport(0, 0, backingWidth, backingHeight);

        ...//drawing different triangle strips here

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        [context presentRenderbuffer:GL_RENDERBUFFER_OES];

Agradecería cualquier comentario sobre el código listado o sugerencias sobre cómo puedo descubrir la causa de este error.

¿Fue útil?

Solución

Yo sospecharía del totalPoints variable que se pasa a drawArrays, o tal vez sus valores para vertexCorrdinates o texturaCoordinates, si esas matrices no son estáticas.Su falla implica que se está quedando sin memoria mientras dibuja las matrices.Sospecho menos de tu configuración GL y me preocupa más tu administración de memoria y lo que estás dibujando que es diferente durante la rotación.

(Además, FWIW, no creo que debas llamar a RenderBufferStorage cada vez que vinculas los búferes de renderizado.Sólo deberías necesitar hacerlo una vez cuando los crees.Dicho esto, no estoy seguro de que no debas destruir los buffers cuando cambias su tamaño y simplemente recrearlos desde cero).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top