2012-03-02 25 views
5

Tôi muốn có một đối tượng mảng đỉnh trong OpenGL ES 2.0 để giữ hai thuộc tính từ bộ đệm khác nhau, bộ đệm thứ hai được đọc từ bộ nhớ của khách hàng (glBindBuffer(GL_ARRAY_BUFFER, 0)) Nhưng tôi nhận được một lỗi runtime:OES_vertex_array_object và khách hàng nhà nước

GLuint my_vao; 
GLuint my_buffer_attrib0; 
GLfloat attrib0_data[] = { 0, 0, 0, 0 }; 
GLfloat attrib1_data[] = { 1, 1, 1, 1 }; 

void init() 
{ 
    // setup vao 
    glGenVertexArraysOES(1, &my_vao); 
    glBindVertexArrayOES(my_vao); 

    // setup attrib0 as a vbo 
    glGenBuffers(1, &my_buffer_attrib0); 
    glBindBuffer(GL_ARRAY_BUFFER, my_buffer_attrib0); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(attrib0_data), attrib0_data, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    // "end" vao 
    glBindVertexArrayOES(0); 

} 

void draw() 
{ 

    glBindVertexArrayOES(my_vao); 
    // (now I assume attrib0 is bound to my_buffer_attrib0, 
    // and attrib1 is not bound. but is this assumption true?) 

    // setup attrib1 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data); 

    // draw using attrib0 and attrib1 
    glDrawArrays(GL_POINTS, 0, 1); // runtime error: Thread1: EXC_BAD_ACCESS (code=2, address=0x0) 

} 

Những gì tôi muốn đạt được là để bọc các ràng buộc của hai thuộc tính như một bộ đệm mảng vertex:

void draw_ok() 
{ 
    glBindVertexArrayOES(0); 

    // setup attrib0 
    glBindBuffer(GL_ARRAY_BUFFER, my_buffer_attrib0); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    // setup attrib1 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    // draw using attrib0 and attrib1 
    glDrawArrays(GL_POINTS, 0, 1); // ok 
} 

Có thể liên kết hai bộ đệm khác nhau trong một đối tượng mảng đỉnh? Có phải OES_vertex_array_object khác với các đối tượng mảng OpenGL đỉnh (đơn giản) không? Cũng lưu ý rằng tôi nhận được lỗi này trong XCode chạy trình mô phỏng iOS. Đây là những liên kết liên quan:

Trả lời

6

Vâng, một trích dẫn từ các thông số kỹ thuật mở rộng giải thích nó khá đơn giản:

Should a vertex array object be allowed to encapsulate client vertex arrays?

RESOLVED: No. The OpenGL ES working group agreed that compatibility with OpenGL and the ability to to guide developers to more performant drawing by enforcing VBO usage were more important than the possibility of hurting adoption of VAOs.

Vì vậy, bạn có thể thực sự ràng buộc hai bộ đệm khác nhau trong một VAO, (tốt, các ràng buộc đệm không được lưu trữ trong VAO, dù sao, chỉ các bộ đệm nguồn của các thuộc tính riêng lẻ, được đặt thông qua glVertexAttribPointer) nhưng bạn không thể sử dụng bộ nhớ không gian của máy khách trong VAO, chỉ các VBO. Điều này cũng tương tự đối với máy tính để bàn GL.

Vì vậy, tôi khuyên bạn nên lưu trữ tất cả dữ liệu đỉnh của bạn trong VBO. Nếu bạn muốn sử dụng bộ nhớ máy khách vì dữ liệu được cập nhật động và bạn nghĩ rằng các VBO sẽ không mua cho bạn bất cứ thứ gì ở đó, đó vẫn là cách tiếp cận sai. Chỉ cần sử dụng VBO với mức sử dụng động (GL_DYNAMIC_DRAW hoặc thậm chí GL_STREAM_DRAW) và cập nhật nó bằng cách sử dụng glBuffer(Sub)Data hoặc glMapBuffer (hoặc kết hợp cũ tốt glBufferData(..., NULL); glMapBuffer(GL_WRITE_ONLY)).

+0

Bạn nhận được câu trả lời được chấp nhận vì bạn không phải là tôi và cũng trả lời nếu OES-VAO giống như máy tính để bàn-VAO :) cảm ơn bạn. – telephone

1

Tháo dòng sau:

glBindBuffer(GL_ARRAY_BUFFER, 0);

từ draw() chức năng. Bạn đã không liên kết bất kỳ bộ đệm trước và nó có thể gây rối lên trạng thái đệm.

+0

Tôi muốn các thuộc tính thứ hai (attrib1) để được đọc từ bộ nhớ của khách hàng, vì vậy GL_ARRAY_BUFFER phải cởi ra trước gọi glVertexAttribPointer. Nhưng điều này dường như làm hỏng mọi thứ, và tôi không chắc chắn tại sao. Một ví dụ về những gì tôi muốn đạt được là để cho hình ảnh lưu trữ VAO, và sau đó chỉ cần thiết lập một thuộc tính của VAO đó để màu sắc tùy chỉnh của tôi, sau khi ràng buộc VAO. – telephone

+0

@telephone Bạn chỉ không thể sử dụng bộ nhớ máy khách với VAO, xem câu trả lời của tôi. –

1

Sau một số lần đào (đọc), tìm thấy câu trả lời trong số OES_vertex_array_object. Dường như tập trung của OES_vertex_array_object về trạng thái ở phía máy chủ, và trạng thái máy khách được sử dụng nếu và chỉ khi đối tượng zero bị ràng buộc. Nó vẫn còn để trả lời nếu OES_vertex_array_object của là giống như đồng bằng OpenGL VAO của. Hãy bình luận nếu bạn biết câu trả lời cho điều này. Dưới đây là các trích dẫn từ OES_vertex_array_object:

 This extension introduces vertex array objects which encapsulate 
    vertex array states on the server side (vertex buffer objects). 



    * Should a vertex array object be allowed to encapsulate client 
    vertex arrays? 

    RESOLVED: No. The OpenGL ES working group agreed that compatibility 
    with OpenGL and the ability to to guide developers to more 
    performant drawing by enforcing VBO usage were more important than 
    the possibility of hurting adoption of VAOs. 



    An INVALID_OPERATION error is generated if 
    VertexAttribPointer is called while a non-zero vertex array object 
    is bound, zero is bound to the <ARRAY_BUFFER> buffer object binding 
    point and the pointer argument is not NULL [fn1]. 
     [fn1: This error makes it impossible to create a vertex array 
     object containing client array pointers, while still allowing 
     buffer objects to be unbound.] 



    And the presently attached vertex array object has the following 
    impacts on the draw commands: 

     While a non-zero vertex array object is bound, if any enabled 
     array's buffer binding is zero, when DrawArrays or 
     DrawElements is called, the result is undefined. 

Vì vậy, EXC_BAD_ACCESS là kết quả không xác định!

+1

+1 cho "Vì vậy, EXC_BAD_ACCESS là kết quả không xác định!". Tôi đã theo đuổi một lỗi trong * ngày *. Đối với một số lý do, trạng thái máy khách GL_VERTEX_ARRAY đã bị vô hiệu hóa bởi những người biết được ai sau một thời gian, vì vậy kích hoạt lại nó sau khi glDrawArray đã cứu tôi: glEnableClientState (GL_VERTEX_ARRAY); Tôi chưa bao giờ mặc dù EXC_BAD_ACCESS là một kết quả không xác định, nhưng là một bản phát hành bộ nhớ không mong muốn, nhưng không, không có bộ nhớ nào được phát hành ở đây. Cảm ơn gợi ý của bạn, nó rất hữu ích :) –

1

Các chức năng mà bạn mong muốn đã được chấp nhận bởi cộng đồng như một phần mở rộng để WebGL:

http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/

+0

Câu trả lời này dường như không liên quan đến câu hỏi. Liên kết cho biết rằng WebGL hiện hỗ trợ OES_vertex_array_object. Tốt, nhưng không giải quyết được câu hỏi. Câu trả lời được chấp nhận giải thích tại sao VAO không thể được sử dụng theo cách được hỏi, và đưa ra lời khuyên là phải làm gì để thay thế. – ToolmakerSteve

Các vấn đề liên quan