OpenGL: VBO hoặc glBegin () + glEnd ()?


16

Gần đây tôi đã được cung cấp liên kết này đến một trang web hướng dẫn từ một người mà tôi đã đưa Sách đỏ OGL gốc cho. Tiêu đề thứ ba trở xuống nói rõ ràng là quên glBegin () & glEnd () làm phương thức kết xuất điển hình. Tôi đã học qua phương pháp của Redbook, nhưng tôi thấy một số lợi ích trong VBO. Đây thực sự là con đường để đi, và nếu vậy, có cách nào để dễ dàng chuyển đổi mã kết xuất và các shader tiếp theo, thành VBO và các kiểu dữ liệu tiếp theo không?

Câu trả lời:


27

Với các VBO hiện đại của OpenGL là cách để đi, các công cụ chức năng cố định (bao gồm glBegin / glEnd và các công cụ ở giữa) đã bị từ chối kể từ 3.0 và bị xóa kể từ 3.1.

Với Cấu hình lõi OpenGL, OpenGL ES 2.0+ và WebGL, bạn thậm chí không có quyền truy cập vào nội dung cũ.

Một số người nghĩ rằng học những thứ cũ trước là tốt hơn bởi vì nó dễ hơn một chút, nhưng những thứ bạn học hầu hết là vô dụng và sau đó là thứ bạn phải học.

Mặc dù không chỉ là VBO, bạn cần sử dụng các shader cho mọi thứ và tự biến đổi ma trận (hoặc sử dụng GLM).

Lý do duy nhất để sử dụng những thứ cũ sẽ là nếu bạn muốn nhắm mục tiêu OpenGL trước 2.0. được phát hành trở lại vào năm 2003. Có một số chipset netbook nhúng thực sự nhảm nhí là 1.5 nhưng thậm chí 1.5 nên hỗ trợ VBO chứ không phải shader. Hoặc OpenGL ES 1.x dựa trên đường ống chức năng cố định (ví dụ: nó được sử dụng trên các iPhone cũ hơn). Hoặc OpenGL SC (cho các hệ thống quan trọng an toàn).

Các hàm thường được sử dụng sau đây đều không dùng nữa:

  • glBegin
  • glEnd
  • glVertex *
  • glN normal *
  • glTextCoord *
  • glTransTable *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

Các hướng dẫn của opengl-tutorial.org có những gì tôi nghĩ là cách tốt nhất để học về OpenGL. Họ dựa vào một số công cụ tương thích kế thừa nhưng họ không thực sự dạy nó cho bạn. Ví dụ, bạn không cần phải kết xuất bất cứ thứ gì mà không có shader nhưng nó hoạt động. Và bạn cần tự xử lý các hoạt động ma trận (xoay, dịch, v.v.) nhưng theo mặc định, bạn sẽ có được chế độ xem 2D phẳng cơ bản.

Ngoài việc tránh những thứ không dùng nữa, có một loạt các chức năng giúp mã hóa OpenGL đẹp hơn rất nhiều nhưng với nhiều trong số đó bạn phải quyết định xem bạn có ổn không khi yêu cầu phiên bản OpenGL và phần cứng tương thích 3.x + mới hơn.

Có nhiều thông tin hơn trong một bài đăng tôi đã thực hiện ở đây .

Nếu bạn cần hỗ trợ OpenGL cũ hơn vì một số lý do, bạn có thể sử dụng VBO khi có thể và khi không, hãy cung cấp dự phòng sử dụng glBegin / glEnd và các vòng lặp trên dữ liệu đỉnh của bạn.

Mặt khác, không có cách 'dễ dàng' thực sự nào để chuyển đổi mã kết xuất cũ. Bạn có thể có thể thực hiện phiên bản riêng của các hàm thêm các đỉnh vào một mảng / vectơ sau đó kết xuất nó vào VBO và vẽ nó khi bạn gọi glEnd giả. nhưng điều đó sẽ rất không hiệu quả vì nó sẽ thực hiện mọi khung hình (trừ khi bạn kiểm tra chỉ thực hiện một lần nhưng điều đó không hiệu quả đối với các đối tượng hoạt hình) và có lẽ sẽ hiệu quả hơn nếu chỉ chuyển sang VBO. Tôi cho rằng nếu bạn có nhiều mã thì cách tiếp cận có thể hoạt động.


7

Với VBO bạn thường có hai lợi thế lớn.

Ưu điểm 1 liên quan đến dữ liệu tĩnh hoàn toàn và xuất phát từ việc có thể giữ dữ liệu đỉnh của bạn trong bộ nhớ tối ưu hơn cho GPU.

Ưu điểm 2 liên quan đến dữ liệu động và xuất phát từ việc có thể chỉ định dữ liệu đỉnh của bạn tại bất kỳ thời điểm nào trước khi sử dụng nó để kết xuất, có thể dẫn đường tốt hơn.

Một lợi thế thứ ba đến từ việc phân nhóm cuộc gọi rút thăm, nhưng cũng được chia sẻ với các mảng đỉnh của trường học cũ vì vậy tôi không gọi nó là đặc biệt cho VBO. Gửi dữ liệu tới GPU (hoặc sử dụng dữ liệu đã có trên GPU) tương tự như nhiều cách để vào I / O và lưu lượng mạng - nếu bạn có một vài lô lớn thì hiệu quả hơn nhiều đợt nhỏ.

Một sự tương tự tốt (không chính xác 100% nhưng đủ để giúp bạn có ý tưởng) tương tự như vậy nếu bạn là tài xế xe buýt phải đưa 50 người từ thành phố này sang thành phố khác. Bạn có thể tải chúng lên từng cái một và thực hiện 50 chuyến đi riêng biệt - đó là glBegin / glEnd. Ngoài ra, bạn có thể đặt tất cả 50 người trong số họ lên xe buýt và chỉ thực hiện một chuyến đi - đó là việc tạo ra các mảng đỉnh hoặc VBO (trong trường hợp VBO, 50 người sẽ ở trên xe buýt;)).

Điều này có giá mặc dù, và ở đây giá là bạn mất khả năng chỉ định dữ liệu đỉnh và khi bạn yêu cầu. Chà, OK, bạn có thể làm điều đó (với một số công việc bổ sung), nhưng bạn sẽ không nhận được hiệu suất đầy đủ từ mã của mình. Thay vào đó, bạn cần suy nghĩ nhiều hơn về dữ liệu đỉnh của mình, cách sử dụng, cách thức (và nếu) nó cần được cập nhật, liệu có thể thực hiện bất kỳ hoạt ảnh nào trong trình đổ bóng hay không (do đó cho phép dữ liệu duy trì trạng thái tĩnh - VBO thực sự cần shader cho rất nhiều trường hợp hoạt hình để hoạt động tốt) hoặc cho dù bạn cần bảo vệ dữ liệu đỉnh mỗi khung, chiến lược cập nhật hiệu quả nếu sau này, v.v. Nếu bạn không làm điều này và chỉ thực hiện chuyển đổi ngây thơ, bạn có nguy cơ rất cao khi đặt trong rất nhiều công việc chỉ để kết quả cuối cùng thực sự chạy chậm hơn!

Điều này có vẻ như là rất nhiều công việc khi bạn lần đầu tiên gặp nó, nhưng thực sự không phải vậy. Khi bạn bước vào chế độ suy nghĩ như thế này, bạn sẽ thực sự thấy rằng nó cực kỳ dễ dàng và gần như đến một cách tự nhiên. Nhưng bạn có thể làm hỏng vài lần thử đầu tiên của mình và bạn không nên nản lòng nếu vậy - vặn vẹo là một cơ hội để học hỏi từ những gì bạn đã làm sai.

Một vài suy nghĩ cuối cùng.

Có dữ liệu mô hình của bạn ở định dạng có thể dễ dàng tải vào VBO có thể giúp làm cho toàn bộ quá trình này dễ dàng hơn cho bạn. Điều đó có nghĩa là bạn nên tránh các định dạng phức tạp hoặc kỳ lạ hơn, ít nhất là vào lúc đầu (và cho đến khi bạn cảm thấy thoải mái hơn với quy trình này); giữ mọi thứ đơn giản và cơ bản nhất có thể khi học và sẽ có ít sai sót hơn và ít nơi phải tìm lỗi nếu (hoặc khi nào!) xảy ra lỗi.

Mọi người đôi khi bị trì hoãn nếu họ thấy một triển khai VBO sử dụng nhiều bộ nhớ hơn so với triển khai glBegin / glEnd được tối ưu hóa / nén (thậm chí họ có thể gọi nó là "lãng phí"). Đừng như vậy. Ngoại trừ trong trường hợp nghiêm trọng, sử dụng bộ nhớ thực sự không quan trọng. Đây là một sự đánh đổi rõ ràng ở đây - bạn chấp nhận sử dụng bộ nhớ có khả năng cao hơn để đổi lấy hiệu năng cao hơn đáng kể. Cũng giúp phát triển tư duy rằng bộ nhớ là một nguồn tài nguyên rẻ và dồi dào đang được sử dụng; hiệu suất thì không.

Và cuối cùng là hạt dẻ cũ - nếu nó đã đủ nhanh thì công việc của bạn đã hoàn thành. Nếu bạn đang đạt tốc độ khung hình mục tiêu, nếu bạn có khoảng trống trong điều kiện nhất thời, thì nó đủ tốt và bạn có thể chuyển sang bước tiếp theo. Bạn có thể lãng phí rất nhiều thời gian và năng lượng để vắt kiệt thêm 10% trong số những thứ không thực sự cần nó (đã ở đó, thực hiện được điều đó, vẫn rơi vào bẫy) vì vậy hãy luôn xem xét việc sử dụng thời gian tối ưu nhất của bạn là gì - bởi vì thời gian lập trình viên thậm chí còn rẻ hơn và kém hơn so với hiệu suất!

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.