Pergunta

Estou escrevendo um aplicativo para iPhone que usa UIView com um CAEAGLayer como camada.Está tudo bem e funcionando, exceto por um pequeno problema:às vezes ele trava com EXC_BAD_ACCESS e o seguinte rastreamento de pilha:

    [EAGLView draw]
    glDrawArrays_Exec
    PrepareToDraw
    DrawFramebufferMakeResident
    AttachmentMakeResident
    TextureMakeResident
    memmove

trava na linha:

    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

O aplicativo só travará durante a mudança de rotação da interface (esse também é o único caso quando o quadro de visualização muda).Não trava com frequência;na maioria das vezes, leva de 3 a 5 minutos girando o dispositivo para reproduzir esse problema.
Acredito que estou cometendo um erro relacionado à inicialização/mudança de quadro do CAEAGLLayer, pois é aí que ele trava (acredito).
Então aqui estão os métodos de subvisualização init e layout:
Iniciar:

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

No set frame eu defino apenas as matrizes GL_MODELVIEW e GL_POJECTION, então acho que nada de ruim pode acontecer lá.
LayoutSubvisualizações:

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

O próprio método Draw se parece com:

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

Eu apreciaria quaisquer comentários sobre o código listado ou sugestões sobre como posso descobrir a causa desse bug.

Foi útil?

Solução

Eu suspeitaria do totalPoints variável sendo passada para drawArrays, ou talvez seus valores para vertexCorrdinates ou texturaCoordenadas, se essas matrizes não forem estáticas.Sua falha implica que você está saindo do limite da memória enquanto desenha as matrizes.Estou menos desconfiado da configuração do GL e mais preocupado com o gerenciamento de memória e com o que você está desenhando de diferente durante a rotação.

(Além disso, FWIW, não acho que você deveria chamar RenderBufferStorage toda vez que vincular o (s) buffer (s) de renderização.Você só precisará fazer isso uma vez ao criá-los.Dito isto, não tenho certeza se você não deveria destruir os buffers ao alterar seu tamanho e apenas recriá-los do zero.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top