Có nên cởi trói?


12

Tôi đang thực hiện một số thử nghiệm với OpenGL ES 2 và nhận được một số câu hỏi, chương trình hiện tại của tôi là như thế:

Init
-------
-> create index buffer
-> fill index buffer glBufferData 
-> create vertex buffer
-> fill vertex buffer glBufferData 

Draw
-------
 1. Apply vertex buffer

    -> Bind VAO
       -> bind vertex buffer
          - enable attributs (glVertexPointer, …)
       -> unbind vertex buffer
    -> Unbind VAO
    -> Bind VAO

 3. Apply index buffer
 4. Draw

Vấn đề

Sự cố mã đã cho, sau một số nghiên cứu, tôi đã hiểu tại sao: Tôi cần hủy liên kết bộ đệm chỉ mục của mình trong phần init (sau khi "điền vào bộ đệm chỉ số glBufferData") hoặc hủy liên kết trước "Bind VAO" đầu tiên

Câu hỏi của tôi là:

  • Tôi có thể đặt bộ đệm chỉ mục của mình trong VAO (bộ đệm chỉ mục chứng khoán VAO không?)?
  • Tôi có phải hủy liên kết bộ đệm sau mỗi lần cập nhật (glBufferData) không?

Trong ứng dụng của tôi, tôi đã có một số bộ đệm được cập nhật trên mỗi khung (Ví dụ: Hạt) vì vậy tôi đã có một ngăn xếp OpenGL như thế:

-> bind buffer 1
-> update buffer 1
-> close buffer 1
-> bind buffer 1
-> draw

3 dòng đầu tiên cập nhật bộ đệm Vertex, hai đối tượng vẽ cuối cùng, tương tự như vậy:

-> bind buffer 1
-> update buffer 1
-> draw

Cảm ơn

Câu trả lời:


12

Bạn dường như đang làm rất nhiều về ràng buộc / không ràng buộc không cần thiết. Nếu bạn đang sử dụng VAO, thì bạn chỉ nên liên kết VAO khi bạn thiết lập nó và khi vẽ hình học. Bạn chỉ ràng buộc VBO / IBO một lần nữa khi bạn cần cập nhật chúng.

Sau khi vẽ hoặc cập nhật bộ đệm, bạn không nhất thiết phải hủy liên kết nó, mặc dù đó có thể là một ý tưởng tốt để tránh việc ghi ngẫu nhiên vào bộ đệm bị ràng buộc.

Bây giờ thực hiện chuỗi thao tác đầu tiên của bạn, đây là thứ tự tổng thể tôi mong đợi để xem:

Trên init:

  1. Tạo và liên kết một VAO. Bất kỳ VBO và IBO nào bạn liên kết trong chuỗi sẽ được liên kết với VAO hiện tại (cái này).

  2. Tạo và liên kết bộ đệm chỉ mục.

    • Điền vào bộ đệm chỉ mục với glBufferData/glMapBuffer.
  3. Tạo và liên kết bộ đệm đỉnh.

    • Điền vào bộ đệm đỉnh glBufferData/glMapBuffer.
  4. Thiết lập các thuộc tính đỉnh với glEnableVertexAttribArray/glVertexAttribPointer, v.v.

  5. Tùy chọn hủy liên kết mọi thứ để tránh sự thay đổi ngẫu nhiên của bộ đệm và VAO. Hãy nhớ hủy liên kết VAO trước . Ví dụ:glBindVertexArray(0);

Rút thăm:

  1. Nếu chỉ vẽ bộ đệm :

    • Ràng buộc VAO;
    • Thực hiện cuộc gọi bốc thăm.
  2. Nếu cập nhật và vẽ :

    • Ràng buộc VAO, VBO, IBO;
    • Cập nhật bộ đệm (cập nhật các thuộc tính đỉnh chỉ cần thiết nếu định dạng đỉnh đã thay đổi);
    • Thực hiện cuộc gọi bốc thăm.
  3. Tùy chọn hủy liên kết để tránh sửa đổi ngẫu nhiên bộ đệm và VAO.

Điều đó đơn giản như thế. Thứ tự hoạt động này nên hoạt động mà không có vấn đề.


2
Tôi muốn thêm rằng trong các thử nghiệm của tôi (2014) với các trường hợp thực tế (nhưng các shader đơn giản để không bị tắc nghẽn tại GPU) Tôi thấy các cải tiến hiệu suất sử dụng VAO là không đáng kể (tiết kiệm CPU <2%) sau khi đặt hàng đúng các cuộc gọi kết xuất đã được triển khai để bỏ qua hoàn toàn thiết lập VBO khi sử dụng cùng một VBO cho các cuộc gọi kết xuất liên tiếp (tiết kiệm CPU 10 đến 33%) và tôi đã gặp một số lỗi trình điều khiển với VAO nên cuối cùng tôi tắt chúng đi. Nó thậm chí còn ít quan trọng hơn khi sử dụng các shader phức tạp, MSAA, v.v., mà nút cổ chai tại GPU khiến CPU không thể chờ đợi dù sao ngay cả trên thiết bị di động.
Stephane Hockenhull

2
Lưu ý rằng việc căn chỉnh dữ liệu đỉnh theo cách không được phần cứng hỗ trợ sẽ buộc trình điều khiển GPU sắp xếp lại dữ liệu VBO trên mỗi thiết lập trong khi trình điều khiển có thể sắp xếp lại dữ liệu một lần với VAO miễn là không có gì thay đổi vì vậy YMMV. Tốt nhất để căn chỉnh & pad dữ liệu đỉnh.
Stephane Hockenhull

1
Tại sao VAO phải được hủy bỏ trước mọi thứ khác?
Daniel Safari

@DanielSafari, ý bạn là sau khi thiết lập? Nếu bạn hủy liên kết bộ đệm trước (bộ đệm liên kết 0 / null), nó sẽ xóa điểm liên kết đó trong VAO hiện tại. Đó là lý do tại sao VAO null nên được đặt đầu tiên.
glampert

@glampert - không, đó không phải là cách các ràng buộc hoạt động; liên kết bộ đệm được sử dụng khi glVertexAttribPulum được gọi và không phải (ngoại trừ: GL_ELEMENT_ARRAY_BUFFER). Thay đổi liên kết bộ đệm sau khi gọi glVertexAttribPulum của bạn không có hiệu lực.
Maximus Minimus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.