2011-06-05 14 views
9

Kodumu bir sonraki seviyeye taşımaya çalışıyorum. Apple'ın bazı en iyi uygulamalarını takip ederek Vertex Tampon Nesnelerim (VBO) etrafında Vertex Array Objects kullanmaya çalışıyorum. Böyle kurulum benim VBOS ve VAOs:Open ES iPhone uygulamasında VBO çevresinde VAO kullanımı EXC_BAD_ACCESS glDrawElements çağrısı yaparken

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

böyle kullanmak sonra http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287977 aldı ve: bununla birlikte,

- (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 çağrısı çalışır ve bu benim dokusunu doldurur, glDrawElements çağrısı bir EXC_BAD_ACCESS ile başarısız olur. Gölgelendirme programım (iki tane kullanıyorum), http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html

cevap

11

Kurulum işlevinin sonundan glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);'u kaldırdığım bir GLProgram nesnesine sarılır. Çizim konum zamanında bağlanmış bir element arabellek olup böylece muhtemelen için indexBuffer istediği ise OES_vertex_array_object için tarifname başına

, bir tepe dizi nesne, dışında bağlayıcı dizi tamponu bütün durum kapsüller bağlı olmak Köşe diziniz nesnesinden uzaklaştığınız anda bağlı olan indexBuffer'u bırakarak, bu köşe dizisi nesnesine geri döndüğünüzde yeniden oynatıldığından emin olursunuz. dizilerden tepe verilerini okurken şu anda bağlı dizisi tampon doğrudan kullanılmaz çünkü


Eğer dizi tampon köşe dizisi nesnelerde izlenmez bağlanma neden merak ediyorsanız, bu büyük olasılıkla —herher, her köşe özniteliği, işlev çağrıldığında dizi arabelleği bağlamasına bakarak ilgili gl*Pointer işlevi tarafından doldurulmuş kendi arabellek bağlamasına sahiptir.

+0

Harika. Bu hile yaptı. Şimdi, uygulamamı analiz ettiğimde, Instruments, görüntüleme kodumun üst kısmındaki glDrawArrays yerine glDrawElements ve endeksleri kullanmamı öneriyor. Eğer öyleyse, iki eleman dizisi arabellek olacak. Bu önemli mi? İkisi de bağlı kalacak mı? – davidbitton

+0

Sadece bir dörtlü çizmek için glDrawArrays kullanıyorsanız ve köşe yeniden kullanımı için gerçek bir olasılık yoksa, glDrawElements uygulamasına geçmenin hiçbir anlamı yoktur. Öyle olsa bile, hangi verttex array nesnesinin draws arasında değiştiğini değiştirirsiniz, bu yüzden iyi olur. – Pivot