Frage

Ich schreibe eine iPhone-Anwendung, die UIView mit einem CAEAGLayer als Layer verwendet.Alles ist in Ordnung und funktioniert bis auf 1 kleines Problem:manchmal stürzt es mit EXC_BAD_ACCESS und dem folgenden Stack-Trace ab:

    [EAGLView draw]
    glDrawArrays_Exec
    PrepareToDraw
    DrawFramebufferMakeResident
    AttachmentMakeResident
    TextureMakeResident
    memmove

es stürzt auf der Leitung ab:

    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

Die Anwendung stürzt nur während der Änderung der Schnittstellenrotation ab (dies ist auch der einzige Fall, wenn sich der Ansichtsrahmen ändert).Es stürzt nicht oft ab;meistens dauert das Drehen des Geräts 3-5 Minuten, um dieses Problem zu reproduzieren.
Ich glaube, ich mache einen Fehler, der mit der Initialisierung / Frame-Änderung von CAEAGLLayer zusammenhängt, da es dort abstürzt (glaube ich).
Hier sind also die Methoden init und layout subviews:
Initiieren:

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

Auf dem gesetzten Frame habe ich nur die Matrizen GL_MODELVIEW und GL_POJECTION gesetzt, also denke ich, dass dort nichts Schlimmes passieren kann.
Layoutunteransichten:

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

Die Zeichnungsmethode selbst sieht so aus:

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

Ich würde mich über Kommentare zum aufgelisteten Code oder Vorschläge freuen, wie ich die Ursache für diesen Fehler herausfinden kann.

War es hilfreich?

Lösung

Ich wäre misstrauisch gegenüber dem totalPoints variable, die an drawArrays übergeben wird, oder möglicherweise Ihre Werte für vertexCorrdinates oder textureCoordinates, wenn diese Arrays nicht statisch sind.Ihr Absturz impliziert, dass Sie beim Zeichnen der Arrays das Ende des Speichers verlassen.Ich bin weniger misstrauisch gegenüber Ihrem GL-Setup und mache mir mehr Sorgen um Ihre Speicherverwaltung und das, was Sie zeichnen, das während der Rotation anders ist.

(Außerdem, FWIW, ich denke nicht, dass Sie RenderBufferStorage jedes Mal aufrufen sollten, wenn Sie die Renderpuffer binden.Sie sollten das nur einmal tun müssen, wenn Sie sie erstellen.Das heißt, ich bin mir nicht sicher, ob Sie die Puffer nicht wirklich zerstören sollten, wenn Sie ihre Größe ändern und sie einfach von Grund auf neu erstellen.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top