Domanda

Sto scrivendo un'applicazione per iPhone che utilizza UIView con un caagliayer come il suo livello. Tutto va bene e lavora a parte 1 piccolo problema: a volte si blocca con exc_bad_access e la seguente traccia dello stack:

    [EAGLView draw]
    glDrawArrays_Exec
    PrepareToDraw
    DrawFramebufferMakeResident
    AttachmentMakeResident
    TextureMakeResident
    memmove
.

Si blocca sulla linea:

    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
.

L'applicazione si bloccherà solo durante il cambio di rotazione dell'interfaccia (che accade anche ad essere l'unico caso quando il fotogramma di vista cambia). Non si blocca spesso; La maggior parte del tempo impiega 3-5 minuti di dispositivo rotante per riprodurre questo problema.
Credo che sto commettendo un errore che sia correlato al cambiamento di inizializzazione / frame CAREAGLLYER da quando è dove si blocca (credo).
Quindi ecco i metodi di sottoviews Init and Layout:
Init:

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

Sul fotogramma Set imposta solo le matrici GL_ModelView e GL_Poiejection, quindi suppongo che nulla di male possa accadere lì.
Layoutsubviews:

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

Disegna il metodo stesso sembra:

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

Apprezzerei qualsiasi commento sul codice quotato o sui suggerimenti su come posso trovare la causa di questo bug.

È stato utile?

Soluzione

Sarei sospettoso della variabile totalPoints passata agli strappali, o forse i tuoi valori per VertExCorrdinates o Texturecoordinati, se quegli array non sono statici.Il tuo incidente implica che stai camminando dalla fine della memoria mentre disegni gli array.Sono meno sospettoso del tuo GL Setup e più preoccupato per la tua gestione della memoria e cosa stai disegnando diverso durante la rotazione.

(anche, fwiw, non penso che dovresti chiamare il resoresorage ogni volta che legate il tampone di rendering. Dovresti solo farlo una volta quando li crei. Detto, non sono sicuroche non dovresti effettivamente distruggere i tamponi quando cambi le loro dimensioni e li ricrea solo da zero.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top