Sự khác biệt giữa bộ đệm của bộ phận ăn liền và khu vực của bạn trong bộ phận OpenGL?


12

Khi tôi đọc doc trên webGL hoặc OpenGL, có thể thấy một số mẫu trong cách sử dụng tên của các hàm và đối tượng. Nhưng tôi không thể hiểu sự khác biệt giữa đối tượng đệm và một mảng.

Có "đối tượng bộ đệm đỉnh", "đối tượng mảng đỉnh" và thậm chí một số loại "mảng bộ đệm" hoặc "mảng bộ đệm".

Trong ngữ cảnh OpenGL, khi một cái gì đó là "mảng" và khi nào nó nên được gọi là "bộ đệm"?


Một số quan điểm, nghĩ về việc tìm nạp dữ liệu qua mạng và lưu trữ nhật ký của tất cả mọi thứ nhận được. Bạn cần đọc ổ cắm và đặt dữ liệu nhận được ở đâu đó để bạn có thể chuyển nó đi khắp nơi, đó là một bộ đệm. Nó thường có thể là một loại danh sách đơn giản được phân bổ cục bộ, được phân bổ động. Đôi khi nó đơn giản như một char* buffer = socketRead();(mã giả). Mặt khác, nhật ký tồn tại trong toàn bộ vòng đời của ứng dụng. Vì vậy, bạn tạo một mảng ở đâu đó và bắt đầu đọc ổ cắm, bất cứ khi nào bạn nhận được dữ liệu bạn viết đoạn đó vào mảng, cung cấp cho bạn một danh sách gọn gàng tất cả dữ liệu bạn nhận được.
Kevin

Câu trả lời:


5

Việc đặt tên của Vertex Array Object có phần đáng tiếc. Có ba thứ khác nhau xuất hiện (đã từng xuất hiện) trong / với / xung quanh ứng dụng của bạn và được (được đặt theo lịch sử) được đặt tên khác nhau, với "mảng" hoặc "bộ đệm" trong tên (cũng có các đối tượng bộ đệm khung, nhưng tôi sẽ bỏ qua điều đó).

  1. Dữ liệu sống trong ứng dụng của bạn, chính thức và thực tế, nhưng được OpenGL kéo trong một lần (trái ngược với đỉnh-by-vertex). Điều này đã từng có lúc bạn sẽ gọi mảng đỉnh .
    Mục đích của việc này là làm cho việc truy cập hiệu quả hơn vì OpenGL chỉ có thể sao chép toàn bộ nội dung trong một lần vào thời điểm được xác định rõ khi bạn đưa ra lời hứa rằng dữ liệu phù hợp và đẩy nó qua AGP hoặc bất cứ điều gì trong một khối. Điều này không còn tồn tại.
  2. Dữ liệu bị che khuất và có thể truy cập bằng tay cầm có thể bị "ràng buộc", tức là được kích hoạt. Dữ liệu thực tế có thể sống trong bộ nhớ chính hoặc trên card đồ họa hoặc được chuyển đến vùng có thể ánh xạ PCIe, bất kể cách nào, nhưng bạn không chính thức sở hữu (ngay cả khi nó nằm trong RAM vật lý và nếu dữ liệu đến từ ứng dụng của bạn ) nó - trừ khi bạn hiện đã "ánh xạ" nó thông qua API tương ứng, lấy lại một con trỏ có thể ghi (và đôi khi có thể đọc được). Bạn cũng bị hạn chế về khả năng kiểm soát những gì xảy ra với dữ liệu (bạn có thể đưa ra một số gợi ý, nhưng đó là khá nhiều).
    OpenGL có thể di chuyển dữ liệu này xung quanh ít nhiều một cách tự do và bạn chỉ được phép / có thể sao chép vào / từ bộ đệm thông qua API tương ứng hoặc truy cập dữ liệu trong khi nó được ánh xạ. Đó là những gì bạn gọi là một đối tượng đệm ( đối tượng đệm đỉnh nếu nó chứa các đỉnh, nhưng nó thực sự không phải, cũng có thể là dữ liệu hình ảnh hoặc đồng phục, chỉ các đỉnh là lần đầu tiên được hỗ trợ, một lần).
    Mục đích của việc này là để đảm bảo rằng OpenGL có thể (về nguyên tắc) có thể làm những gì nó muốn, thậm chí nó có thể đẩy bộ đệm qua PCIe một cách suy đoán trước khi bạn rút ra. Điều đó hoạt động vì bạn không sở hữu dữ liệu (OpenGL nào!) Và bạn chỉ có thể truy cập thông qua API đã cho, vì vậy mọi lúc mọi nơi dữ liệu đó đều hợp lệ. Trình điều khiển thậm chí có thể chọn bỏ đi bộ nhớ đệm trên card đồ họa khi cần bộ nhớ cho thứ gì đó khác và sau đó khôi phục nó từ bản sao bí mật của nó khi cần.
  3. Một cách hiểu sai thực sự ngu ngốc mà một cái tên tốt hơn nhiều sẽ là một cái gì đó giống như bộ đệm hoặc bộ mô tả, đây là đối tượng mảng đỉnh khét tiếng . Theo quan điểm của bạn, không có gì ngoài một bộ tay cầm đệm được bó lại với nhau dưới một tay cầm tối nghĩa khác (mà bạn có thể liên kết). Khi nó xảy ra, thực tế phức tạp hơn một chút. Trên thực tế, VAO gần gũi hơn với cách thức hoạt động của phần cứng thực tế. Các card đồ họa có một số lượng nhỏ (thường là 2, 4 hoặc 8) bộ mô tả (không chỉ cho bộ đệm, mà còn cho các bộ lấy mẫu) với các mục rất nhiều trong mỗi mục, giữa chúng có thể chuyển đổi rất hiệu quả .
    Bây giờ, mục đích của đối tượng mảng đỉnh là giảm số lượng lệnh gọi API và giảm số lượng kiểm tra tính nhất quán mà OpenGL phải thực hiện trong nội bộ và tất nhiên là sử dụng phần cứng như nó hoạt động. Nếu bạn liên kết 5 bộ đệm, thì mỗi bộ đệm phải trải qua một số kiểm tra đắt tiền và mỗi bộ là một ứng cử viên cho lỗi bộ nhớ cache trong trình điều khiển, cộng với mỗi bộ đệm yêu cầu giao tiếp với card đồ họa để thay đổi bộ mô tả, v.v. liên kết một VAO, trình điều khiển có thể (thường) chỉ cần chuyển bộ mô tả trên thẻ đồ họa và được thực hiện.

8

Đối tượng mảng Vertex (VAO) là một đối tượng có chứa một hoặc nhiều Đối tượng bộ đệm Vertex và được thiết kế để lưu trữ thông tin cho một đối tượng được hiển thị hoàn chỉnh.

(kéo từ khronos )

Mỗi bộ đệm có xu hướng tạo thành một thuộc tính của một mảng đỉnh (đối tượng). Một VAO có thể chứa nhiều thuộc tính đỉnh (ví dụ: vị trí, màu sắc, UV). Mỗi cái có thể được giữ trong bộ đệm riêng của nó, trong đó bộ đệm biểu thị một chuỗi các byte liền kề không được định dạng và ở đó bạn cần chỉ định rõ ràng kích thước (loại) cho mỗi phần tử bộ đệm cho cả các lệnh gọi OpenGL bên CPU và công cụ đổ bóng phía GPU.

Đó là một cách. Các cách khác có thể làm việc này là:

  • Tất cả các thuộc tính được lưu trữ xen kẽ trong một bộ đệm, HOẶC
  • Một số thuộc tính tồn tại trong bộ đệm chuyên dụng của riêng chúng, trong khi các thuộc tính khác chia sẻ bộ đệm.

Sơ đồ dưới đây minh họa hai trường hợp sau.

nhập mô tả hình ảnh ở đây

Dòng dưới cùng: Nếu cụm từ "mảng đỉnh" được sử dụng không đủ tiêu chuẩn trong OpenGL, bạn có thể giả sử nó có nghĩa là VAO, trong ngữ cảnh OpenGL (cụ thể) thực sự là một thứ rất khác so với bộ đệm.

EDIT re bình luận của bạn: GL_ARRAY_BUFFERcho biết ý định sử dụng đối tượng bộ đệm đó cho dữ liệu thuộc tính đỉnh, như được mô tả ở trên. Điều này là do bộ đệm không chỉ được sử dụng cho các thuộc tính đỉnh. Tuy nhiên, vì đây là trường hợp sử dụng phổ biến nhất và bạn đang hỏi về VAO, tôi sẽ không đi sâu vào những người khác; tuy nhiên đây là danh sách các loại bộ đệm khác có thể được thiết lập.


Vì vậy, bộ đệm là: 1. nằm trong GPU, 2. trong hầu hết thời gian chứa một loại dữ liệu (chỉ đỉnh, chỉ màu ect), 3.Data được xen kẽ, đó là 111122223333 ect. 4. không cung cấp phương thức để truy cập dữ liệu (không phải bộ đệm [2] hoặc bộ đệm [vertex_3434]) Bây giờ, các mảng là: 1. bộ sưu tập bộ đệm, 2. lưu trữ thông tin về cách phân tích bộ đệm mà nó chứa. (Đó là bước lưu trữ mảng , kích thước của một phần tử, độ lệch, do đó, dữ liệu từ bộ đệm có thể được truy cập chính xác. đúng không?
coobit

1. Bộ đệm tồn tại ở cả hai đầu và chuyển giữa CPU và GPU (có khả năng quay lại VÀ ra), nếu không bạn sẽ điền dữ liệu sẽ được tải lên GPU khi tải lưới từ đĩa như thế nào?. Có, các phần tử có kiểu đồng nhất trong toàn bộ bộ đệm, nhưng tùy thuộc vào công nghệ bạn đang sử dụng, mỗi phần tử bộ đệm có thể là kiểu nguyên thủy hoặc structkiểu. Dữ liệu có thể được xen kẽ hoặc hoàn toàn thống nhất, trên mỗi bộ đệm. Bạn có thể lập chỉ mục vào chúng, giống như với một mảng C truyền thống trên CPU. Các đối tượng mảng (sử dụng thuật ngữ chính xác này hoặc tự kết thúc một cách khó hiểu!) ... (tiếp theo bên dưới)
Kỹ sư

2. Có, bạn cần chắc chắn đảm bảo các khai báo bộ đệm trong shader của mình sẽ khớp với các thông số kỹ thuật bạn đã đặt trên VAO bên CPU: "Tất cả trạng thái liên quan đến định nghĩa dữ liệu được sử dụng bởi bộ xử lý đỉnh được gói gọn trong một đỉnh đối tượng mảng. " (khronos docs)
Kỹ sư

Vì vậy, chỉ cần nhấn móng tay nhiều hơn ... Mọi người đã làm việc như thế nào trước khi AO chỉ sử dụng BO? Hoặc AO luôn có mặt trong OpenGL và đó chỉ là VAO được giới thiệu sau đó là VBO?
coobit

@coobit io7m.com/document/history-vertex-spec - điều này cho bạn ý tưởng về sự khác biệt giữa đường ống cố định (trường cũ) OpenGL, 3Dfx, v.v. và đường ống lập trình hiện đại, OpenGL và Direct3D.
Kỹ sư

5

Thuật ngữ này bắt nguồn từ lịch sử của OpenGL. Điều quan trọng cần nhớ là, đối với hầu hết các phiên bản GL có liên quan ở đây, OpenGL đã được phát triển dần dần và bằng cách thêm chức năng mới vào API đã có sẵn thay vì thay đổi API.

Phiên bản đầu tiên của OpenGL không có loại đối tượng này. Vẽ đã đạt được bằng cách phát hành nhiều cuộc gọi glBegin / glEnd, và một vấn đề với mô hình này là nó rất không hiệu quả, về mặt chi phí gọi hàm.

OpenGL 1.1 đã thực hiện các bước đầu tiên để giải quyết vấn đề này bằng cách giới thiệu các mảng đỉnh. Thay vì trực tiếp chỉ định dữ liệu đỉnh, bây giờ bạn có thể lấy nguồn từ mảng C / C ++ - do đó có tên. Vì vậy, một mảng đỉnh chỉ là như vậy - một mảng các đỉnh và trạng thái GL cần thiết để chỉ định chúng.

Sự phát triển lớn tiếp theo đến với GL 1.5 và cho phép lưu trữ dữ liệu mảng đỉnh trong bộ nhớ GPU thay vì trong bộ nhớ hệ thống ("phía máy khách"). Một điểm yếu của đặc tả mảng đỉnh GL 1.1 là toàn bộ dữ liệu đỉnh phải được chuyển sang GPU mỗi khi bạn muốn sử dụng nó; nếu nó đã có trên GPU thì việc chuyển đổi này có thể tránh được và đạt được hiệu suất tiềm năng.

Vì vậy, một loại đối tượng GL mới đã được tạo để cho phép lưu trữ dữ liệu này trên GPU. Giống như một đối tượng kết cấu được sử dụng để lưu trữ dữ liệu kết cấu, đối tượng đệm đỉnh lưu trữ dữ liệu đỉnh. Đây thực sự chỉ là một trường hợp đặc biệt của một loại đối tượng bộ đệm tổng quát hơn có thể lưu trữ dữ liệu không cụ thể.

API để sử dụng các đối tượng bộ đệm đỉnh được hỗ trợ dựa trên API mảng đỉnh đã có sẵn, đó là lý do tại sao bạn thấy những điều kỳ lạ như chuyển đổi các byte bù sang con trỏ trong đó. Vì vậy, bây giờ chúng ta có API mảng đỉnh chỉ lưu trữ trạng thái, với dữ liệu được lấy từ các đối tượng bộ đệm thay vì từ mảng trong bộ nhớ.

Điều này đưa chúng ta gần như đến cuối câu chuyện của chúng tôi. API kết quả khá dài dòng khi chỉ định trạng thái mảng đỉnh, do đó, một cách tối ưu hóa khác là tạo một loại đối tượng mới tập hợp tất cả trạng thái này lại với nhau, cho phép nhiều thay đổi trạng thái mảng đỉnh trong một lệnh gọi API và cho phép GPU để có khả năng thực hiện tối ưu hóa do có thể biết trạng thái nào sẽ được sử dụng trước thời hạn.

Nhập đối tượng mảng đỉnh, tập hợp tất cả những thứ này lại với nhau.

Vì vậy, để tóm tắt, một mảng đỉnh bắt đầu cuộc sống như một tập hợp trạng thái và dữ liệu (được lưu trữ trong một mảng) để vẽ với. Bộ đệm đỉnh thay thế bộ lưu trữ mảng trong bộ nhớ bằng loại đối tượng GL, để mảng đỉnh chỉ ở trạng thái. Một đối tượng mảng đỉnh chỉ là một đối tượng chứa cho trạng thái này, cho phép nó được thay đổi dễ dàng hơn và với ít lệnh gọi API hơn.


0

Tôi chưa từng làm việc với OpenGL trong một thời gian, vì vậy tôi chỉ có thể là một nửa đúng. Nói chung: Bộ đệm lưu trữ một mảng bộ nhớ chưa được định dạng. Một mảng là một thuật ngữ chung của bộ nhớ liền kề.

Một bộ đệm cần được liên kết với bối cảnh, trong khi một mảng chỉ là một mảng dữ liệu. Nếu tôi nhớ lại chính xác, dữ liệu trong bộ đệm có nghĩa là được sao chép vào card đồ họa (do đó ràng buộc).

Mong cái này giúp được chút ít


GL_ARRAY_BUFFER là gì? Tại sao nó được gọi như vậy? Theo giả thuyết của bạn, đó là "Bộ nhớ tiếp giáp không được định dạng" :)
coobit

Chà, ví dụ cụ thể này chỉ là một id cho một bộ đệm (mà bạn liên kết mảng của mình). Bộ đệm mảng (trong ví dụ của bạn) được sử dụng cho các thuộc tính đỉnh, vì vậy về cơ bản, bạn liên kết mảng thuộc tính đỉnh của mình với bộ đệm. Âm thanh khó hiểu vì vậy hãy để tôi cho bạn một ví dụ. Bạn có một số mảng ở phía cpu có thể là màu, bình thường, vị trí, v.v. và bây giờ bạn muốn gpu truy cập nó. Đó là khi bindBuffer xuất hiện, về cơ bản ánh xạ "mảng cpu" của bạn sang "mảng gpu".
Juicef

Về lý do tại sao nó được gọi như vậy, tôi không thể trả lời điều đó. Tôi sẽ cho rằng đó là vì bạn có một loạt các dữ liệu khác nhau xuất hiện ở đó, màu sắc, bình thường, v.v.
Juicef
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.