2012-04-03 23 views
7

Tôi chắc chắn rằng nếu bạn liên kết bộ đệm qua glBindBuffer(), bạn có thể giả định rằng nó vẫn bị ràng buộc, cho đến khi mục tiêu được phục hồi qua một cuộc gọi khác tới glBindBuffer(). Vì vậy, tôi đã khá ngạc nhiên khi tôi phát hiện ra rằng gọi glBindVertexArray() đặt đệm ràng buộc với mục tiêu GL_ELEMENT_ARRAY để 0.OpenGL 3: glBindVertexArray vô hiệu hóa GL_ELEMENT_ARRAY_BUFFER

Đây là C tối thiểu ++ mẫu mã:

GLuint buff; 
glGenBuffers(1, &buff); 
std::cout << "Buffer is " << buff << "\n"; 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff); 
GLuint vao; 
glGenVertexArrays(1, &vao); 

GLint bound_buff; 
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff); 
std::cout << "Bound before glBindVertexArray: " << bound_buff << "\n"; 

glBindVertexArray(vao);  
    // ^- an implicit glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); ? 

glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff); 
std::cout << "Bound after glBindVertexArray: " << bound_buff << "\n"; 

tôi chạy mã này ngay sau khi khởi tạo một OpenGL 3.2 bối cảnh thiết bị và nhận được kết quả như sau:

Buffer is 1 
Bound before glBindVertexArray: 1 
Bound after glBindVertexArray: 0 

các GL_ARRAY_BUFFER mặt khác là không thay đổi bởi các cuộc gọi. Tôi đã kiểm tra OpenGL 3.2 spec (2.10) cho glBindVertexArray và không tìm thấy đề cập đến tác dụng phụ bất ngờ đó.

  1. Hành vi này có tuân thủ Spec không?
  2. Nếu có, những tác dụng phụ nào khác có thể được mong đợi từ một cuộc gọi đến glBindVertexArray?
  3. Lý do đằng sau điều này là gì?

Tôi đã thử nghiệm thẻ này trên thẻ nvidia trên máy Win XPx64 với trình điều khiển 296,15 WHQL. Một thử nghiệm nhanh chóng trên OS X Lion với một nvidia GT330M cho kết quả tương tự.

+0

Tôi nghĩ rằng ràng buộc một VAO là hoàn toàn ràng buộc phần tử và bộ đệm mảng đỉnh. Đó là những gì VAO đang làm. Nếu bạn liên kết một VAO và sau đó liên kết một bộ đệm chỉ mục và đỉnh, các bộ đệm này sau đó sẽ bị ràng buộc hoàn toàn bất cứ khi nào bạn liên kết VAO sau này. Vì vậy, ràng buộc VAO ở trên có lẽ đã ngầm thiết lập các phần tử và các mảng đỉnh bằng không vì chúng chưa được bao gồm bởi bạn trong đối tượng VAO. Điều đó có ý nghĩa không? :-) – Robinson

+0

Nhưng tại sao nó chỉ thay đổi GL_ELEMENT_ARRAY_BUFFER chứ không phải GL_ARRAY_BUFFER? – ComicSansMS

+0

Vì bộ đệm mảng là bộ đệm đỉnh (ít nhất là các glEnableVertexAttribArray khác nhau và glVertexAttribPointer gọi thực hiện của bạn với nó), và nó bao gồm một phần tử đệm như một phần của trạng thái đó. – Robinson

Trả lời

15

Vertex Array Objects đóng gói tất cả trạng thái * cần thiết để hiển thị dữ liệu đỉnh. Do đó, họ phải đóng gói những bộ đệm bạn liên kết với các thuộc tính (thông qua glVertexAttribPointer), GL_ELEMENT_ARRAY_BUFFER (cần thiết cho các cuộc gọi glDrawElement*), v.v.

Tuy nhiên, tôi vẫn cảm thấy hơi bối rối bởi thực tế là tôi không thể tìm thấy bất kỳ đề cập nào về tác dụng phụ này trong tài liệu.

Đặc điểm kỹ thuật giải thích rõ ràng điều này, mặc dù nó yêu cầu hiểu cách thức hoạt động của thông số kỹ thuật để xem cách thực hiện.

OpenGL là tập hợp trạng thái, có nghĩa là tất cả các chức năng OpenGL (ngoại trừ những chức năng thực sự hiển thị nội dung nào đó) sửa đổi trạng thái OpenGL. Khi bạn gọi glVertexAttribPointer, chức năng này sẽ sửa đổi một số phần trạng thái OpenGL nội bộ.

OpenGL objects được xác định theo phần nào của trạng thái OpenGL mà chúng đóng gói. Do đó, nếu một hàm sửa đổi trạng thái được đóng gói bởi một đối tượng, thì hàm đó sửa đổi chính đối tượng đó. Ràng buộc một đối tượng có nghĩa là thay thế các phần trạng thái hiện tại mà chúng đóng gói với trạng thái hiện tại của đối tượng đó.

Đặc điểm xác định VAO dựa trên trạng thái đóng gói của chúng. Về cơ bản nó chỉ vào một trong các bảng trạng thái OpenGL và nói, "VAO là tất cả những điều đó". Phiên bản 3.x cốt lõi của chức năng này thực sự làm thay đổi các bảng trạng thái để làm cho nó rõ ràng hơn một chút (cùng hành vi, nhẹ lời giải thích khác nhau của chúng):

OpenGL 3.3 đặc điểm kỹ thuật, phần 2.10:

Đối tượng mảng đỉnh kết quả là một vectơ trạng thái mới, bao gồm tất cả các giá trị trạng thái được liệt kê trong bảng 6.4 và 6.5.

Tôi sẽ không in lại bảng 6.4 và 6.5; bạn có thể tự tìm kiếm chúng. Nhưng chúng rõ ràng bao gồm GL_ELEMENT_ARRAY_BUFFER_BINDING và khác nhau GL_VERTEX_ATTRIB_ARRAY_BUFFER_BIDNING (là các đối tượng đệm).

* Lưu ý: VAO không chứa trạng thái được đặt bởi các hàm glVertexAttrib. Chúng có thể ảnh hưởng đến kết xuất nếu mảng thuộc tính không được kích hoạt.