Trạng thái nào được lưu trữ trong Đối tượng mảng OpenGL Vertex (VAO) và làm cách nào để sử dụng VAO chính xác?


25

Tôi đã tự hỏi trạng thái nào được lưu trữ trong VGL OpenGL. Tôi đã hiểu rằng VAO chứa trạng thái liên quan đến thông số kỹ thuật đỉnh của các đỉnh được đệm (thuộc tính nào trong bộ đệm và bộ đệm nào bị ràng buộc, ...). Để hiểu rõ hơn về cách sử dụng chính xác của VAO, tôi muốn biết chính xác trạng thái họ nắm giữ.


Tôi nên sử dụng VAO như thế nào

Từ các ví dụ đơn giản, tôi đã hiểu rằng việc sử dụng VAO chính xác như sau:

Thiết lập

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

Kết xuất

Bind VAO
---- Draw
Unbind VAO

Từ điều này, tôi giả sử rằng ít nhất các ràng buộc bộ đệm đỉnh và các đặc tả thuộc tính đỉnh được lưu trữ trong VAO. Tuy nhiên, tôi không chắc chắn làm thế nào mô hình sử dụng này mở rộng đến các tình huống trong đó (nhiều) kết cấu và (nhiều) chương trình đổ bóng xuất hiện. Là chương trình shader hoạt động lưu trữ trong các VAO? Và các ràng buộc kết cấu (với các cài đặt lấy mẫu / gói của chúng ) có được lưu trong VAO không? Ditto cho đồng phục ?


Do đó, câu hỏi của tôi là:

  • Trạng thái chính xác nào được lưu trữ trong VGL OpenGL ? (Liên kết VBO, thông số kỹ thuật thuộc tính, chương trình đổ bóng hoạt động, liên kết kết cấu, cài đặt gói / lấy mẫu kết cấu, đồng phục ...?)
  • Làm cách nào để sử dụng chính xác VAO trong thiết lập kết xuất phức tạp hơn trong đó (nhiều) kết cấu với cài đặt lấy mẫu / gói liên quan, (nhiều) chương trình đổ bóng và đồng phục có liên quan?

1
VAO lưu trữ dữ liệu về vị trí thuộc tính đỉnh. Nó cũng lưu trữ ID của VBO trong đó các thuộc tính này được chứa. Bạn không cần phải liên kết VBO khi bạn vẽ một cái gì đó, bạn cần liên kết nó trước khi gọi glVertexAttribPulum () khi bạn tạo VAO.
HolyBlackCat

Câu trả lời:


18

VAO lưu trữ dữ liệu về vị trí thuộc tính đỉnh. (Và một số dữ liệu khác liên quan đến chúng.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"Hoàn toàn không liên quan đến nó.

Bạn có thể hỏi tại sao nó không nhớ ràng buộc VBO. Vì bạn không cần ràng buộc VBO để vẽ một cái gì đó, bạn chỉ cần liên kết nó khi tạo VAO: Khi bạn gọi glVertexAttribPointer(...), VAO nhớ những gì VBO hiện đang bị ràng buộc. Và VAO sẽ lấy các thuộc tính từ các VBO này khi bạn vẽ nó, ngay cả khi các VBO này hiện không bị ràng buộc.


Ngoài ra, VAO và VBO phải được sử dụng một chút khác nhau:

Điều này sẽ không hoạt động

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

bởi vì bạn cần liên kết VBO để chỉ định vị trí thuộc tính.

Vì vậy, bạn nên làm điều đó như thế này:

Generate VAO
BindVAO
Generate VBO's
BindVBO's
Specify vertex attributes

Bạn có thể thay đổi dữ liệu của VBO bất cứ khi nào bạn muốn, nhưng bạn phải liên kết nó trước đó.

Và bản vẽ sẽ trông như thế này:

Bind VAO
Draw


Như bạn có thể nhận thấy, tôi đã xóa unbindcác cuộc gọi khỏi danh sách của bạn. Chúng gần như hoàn toàn vô dụng và chúng sẽ làm chậm chương trình của bạn một chút, vì vậy tôi thấy không có lý do gì để gọi chúng.


9
"vì vậy tôi thấy không có lý do để gọi cho họ." để ngăn chặn vô tình thay đổi chúng. Đặc biệt là một vấn đề khi sử dụng thư viện của bên thứ 3.
ratchet freak

Cảm ơn bạn đã trả lời tuyệt vời! Vì vậy, trong ngắn hạn, VAO chỉ lưu trữ các vị trí thuộc tính đỉnh. VBO không hồi phục khi ràng buộc VAO, vì VAO biết bộ đệm nào cần tìm thuộc tính. Tất cả các trạng thái khác được chứa trong trạng thái OpenGL toàn cầu.
Jelle van Campen

@JellevanCampen Đúng, đúng. FYI, nó cũng lưu trữ tắt / bật trạng thái của các thuộc tính ( gl{Enable|Disable}VertexAttribArray()), giá trị mặc định của chúng ( glVertexAttrib*()), chế độ kích hoạt ( glVertexAttribDivisor()) và có thể là một cái gì đó khác.
HolyBlackCat

@HolyBlackCat bạn có chắc trạng thái mặc định (glVertexAttrib ()) là một phần của trạng thái VAO không? Wiki OpenGL tuyên bố khác, nói rằng chúng là trạng thái bối cảnh.
rdb

@ndb Không, tôi không chắc. Tôi đã dự đoán họ là một phần của bang VAO và tôi đã không kiểm tra nó.
HolyBlackCat 04/07/2015

4

Nó chỉ lưu trữ liên kết đỉnh và liên kết bộ đệm chỉ mục

Đó là tất cả các tham số glVertexAttribPointercộng với bộ đệm được liên kết với Vertex_Array_buffer tại thời điểm cuộc gọi đến glVertexAttribPointervà Element_Array_buffer bị ràng buộc.

Đồng phục là một phần của chương trình hiện tại.

Mọi thứ khác là nhà nước toàn cầu.

Trong nghi ngờ, bạn có thể kiểm tra các bảng trạng thái trong thông số kỹ thuật của phiên bản bạn đang sử dụng.


Cảm ơn câu trả lời là tốt! Điều này xóa mọi thứ cho tôi.
Jelle van Campen

4

Dưới đây là một lời giải thích đơn giản nhưng hiệu quả, về cơ bản, một đối tượng bộ đệm có thông tin có thể được hiểu là chỉ đơn giản là các bit của dữ liệu thô, mà về bản thân nó không có nghĩa gì, vì vậy, đó là dữ liệu có thể được xem xét theo bất kỳ cách nào thực sự

i.e float vbo[]={1.0,2.0,34.0...}

và cách OpenGL được thiết kế để hoạt động là bạn phải xác định xem dữ liệu mà bạn chuyển đến các shader khác nhau sẽ trông như thế nào với các shader

trong đó bạn cũng phải xác định cách nó sẽ đọc dữ liệu đó, định dạng của dữ liệu đó và phải làm gì với dữ liệu đó và cách sử dụng và để làm gì, tất cả thông tin này được lưu trữ trong VAO

ví dụ bạn có thể khai báo dữ liệu được lưu trữ trong một mảng như thế này float vbo = {11.0,2.0,3.0,4.0}

Điều bắt buộc tiếp theo tại thời điểm này là làm thế nào để diễn giải dữ liệu đó từ VBO trong VAO và ý nghĩa của nó là như sau

VAO có thể được đặt để đọc 2 số float trên một đỉnh (sẽ tạo ra 2 vectơ với hai chiều x, y) hoặc bạn có thể yêu cầu vao diễn giải nó thành 1 vectơ với 4 chiều, ví dụ x, y, z, w, v.v.

nhưng các thuộc tính khác của dữ liệu đó được xác định và lưu trữ trong VAO, chẳng hạn như định dạng dữ liệu (mặc dù bạn đã khai báo một mảng float, bạn có thể yêu cầu shader đọc nó dưới dạng một số nguyên, tất nhiên là hệ thống chuyển đổi dữ liệu thô trong quá trình từ float sang số nguyên và có bộ quy tắc riêng phải làm gì trong những trường hợp như vậy)

Về cơ bản, VBO là dữ liệu và VAO lưu trữ cách diễn giải dữ liệu đó, bởi vì các shader và máy chủ OpenGL được thiết kế rất khó hiểu và cần biết mọi thứ trước khi quyết định xử lý nó và làm gì với nó và ở đâu cầm lấy nó

tất nhiên nó không thực sự tọc mạch, nó thực sự có vẻ hiệu quả nhất bởi vì nó cần lưu trữ dữ liệu đó trên bộ nhớ máy chủ đồ họa để nó được xử lý nhanh nhất và hiệu quả nhất (trừ khi nó quyết định rằng nó không cần phải làm điều này nếu dữ liệu không được xử lý theo cách như vậy và được sử dụng cho một số thông tin khác không được truy cập thường xuyên), và do đó tại sao các chi tiết phải làm với dữ liệu và cách xử lý dữ liệu được yêu cầu phải được lưu trữ trong VAO, vì vậy VAO giống như một tiêu đề và VBO giống như dữ liệu thô thuần mà tiêu đề sử dụng và định nghĩa (trong trường hợp này chuyển đến các thuộc tính đỉnh của shader) ngoại trừ VBO không bị giới hạn chỉ được sử dụng bởi một VAO, nó có thể được sử dụng và tái sử dụng và ràng buộc với nhiều VAO chẳng hạn:

Những gì bạn có thể làm là bạn có thể liên kết một đối tượng bộ đệm với VAO1 và cũng (riêng) liên kết cùng một đối tượng bộ đệm với VAO2 với mỗi cách diễn giải nó khác nhau để nếu shader của bạn xử lý dữ liệu, tùy thuộc vào VAO nào là đối tượng bị ràng buộc, nó sẽ xử lý cùng một dữ liệu thô khác với frambuffer (vẽ pixel cho cửa sổ) dẫn đến hiển thị khác nhau của cùng một dữ liệu dựa trên cách bạn xác định việc sử dụng nó trong VAO


Đây là câu trả lời tốt nhất!
CodingMade Easy
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.