Использование VAO вокруг VBO в приложении iPhone Open ES вызывает EXC_BAD_ACCESS при вызове glDrawElements - PullRequest
9 голосов
/ 05 июня 2011

Я пытаюсь перевести мой код на следующий уровень.Следуя рекомендациям Apple, я пытаюсь реализовать объекты Vertex Array вокруг моих объектов Vertex Buffer (VBO).Я настраиваю свои VBO и VAO следующим образом:

- (void)setupVBOs {  
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArrayOES(0);
    {
        glGenVertexArraysOES(1, &directArrayObject);
        glBindVertexArrayOES(directArrayObject);

    //    GLuint texCoordBuffer;
        glGenBuffers(1, &texCoordBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(DirectVertices), DirectVertices, GL_STATIC_DRAW);

        glVertexAttribPointer(directPositionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, position));
        glEnableVertexAttribArray(directPositionSlot);
        glVertexAttribPointer(texCoordSlot, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, texCoord));
        glEnableVertexAttribArray(texCoordSlot);

        glGenVertexArraysOES(1, &arrayObject);
        glBindVertexArrayOES(arrayObject);

    //    GLuint vertexBuffer;
        glGenBuffers(1, &vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

        glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
        glEnableVertexAttribArray(positionSlot);
        glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Color));
        glEnableVertexAttribArray(colorSlot);

    //    GLuint indexBuffer;
        glGenBuffers(1, &indexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
    }
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArrayOES(0);
}

, который я взял из http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287977, а затем использую его так:

- (void) render:(CADisplayLink*)displayLink {

    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glViewport(0, 0, backingWidth, backingHeight);

    [directProgram use];
    glBindVertexArrayOES(directArrayObject);
    glDisable(GL_DEPTH_TEST);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

//  // Update uniform values
    glUniform1i(videoFrameUniform, 0);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    [program use];
    glBindVertexArrayOES(arrayObject);
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);

    CC3GLMatrix *projection = [CC3GLMatrix matrix];
    float h = 4.0f * self.frame.size.height / self.frame.size.width;
    [projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
    glUniformMatrix4fv(projectionUniform, 1, 0, projection.glMatrix);

    CC3GLMatrix *modelView = [CC3GLMatrix matrix];
    [modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
    currentRotation += displayLink.duration * 90;
    [modelView rotateBy:CC3VectorMake(currentRotation, currentRotation, 0)];
    glUniformMatrix4fv(modelViewUniform, 1, 0, modelView.glMatrix);

    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);

    glBindVertexArrayOES(0);

    BOOL success = [context presentRenderbuffer:GL_RENDERBUFFER];
    if(!success)
        NSLog(@"present failed");
}

Работает вызов glDrawArrays,и он заполняет мою текстуру, однако вызов glDrawElements завершается неудачно с EXC_BAD_ACCESS.Мои шейдерные программы (я использую две) обернуты в объект GLProgram, который я взял из http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html

1 Ответ

11 голосов
/ 06 июня 2011

Удалите glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); из конца вашей функции настройки.

В соответствии со спецификацией для OES_vertex_array_object, объект массива вершин инкапсулирует все состояния , за исключением привязка буфера массива 1 , поэтому при рисовании элементный буфер не привязан, тогда как вы, вероятно, хотели, чтобы indexBuffer был связан.Оставляя indexBuffer связанным в то время, когда вы привязываетесь к объекту массива вершин, вы гарантируете, что он будет восстановлен, когда вы вернетесь к этому объекту массива вершин.


1 Если вам интересно, почему привязка буфера массива не отслеживается в объектах массива вершин, это, вероятно, связано с тем, что текущий буфер массива не используется напрямую при чтении данных вершин из массивов, скорее, каждый атрибут вершины имеет свойсобственная привязка буфера, которая заполняется соответствующей ей функцией gl*Pointer, просматривая привязку буфера массива при вызове функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...