OpenGL: VBO atau glBegin () + glEnd ()?

16

Baru-baru ini saya diberi tautan ini ke situs tutorial dari seseorang yang saya berikan Buku Merah OGL asli ke. Header ketiga ke bawah mengatakan dengan jelas untuk melupakan glBegin () & glEnd () sebagai metode render yang khas. Saya belajar melalui metode Redbook, tetapi saya melihat beberapa manfaat dalam VBO. Apakah ini benar-benar cara untuk pergi, dan jika demikian, apakah ada cara untuk dengan mudah mengkonversi kode render, dan shader berikutnya, menjadi VBO dan tipe data berikutnya?

S. Fitzgerald
sumber

Jawaban:

27

Dengan OpenGL's VBO modern adalah cara untuk pergi, hal-hal fungsi tetap (termasuk glBegin / glEnd dan hal-hal di antaranya) telah ditinggalkan sejak 3.0 dan dihapus sejak 3.1.

Dengan Profil Inti OpenGL, OpenGL ES 2.0+ dan WebGL Anda bahkan tidak memiliki akses ke barang-barang lama.

Beberapa orang berpikir mempelajari hal-hal lama lebih baik karena itu sedikit lebih mudah, tetapi hal-hal yang Anda pelajari sebagian besar tidak berguna dan kemudian hal-hal yang harus Anda hilangkan.

Ini bukan hanya VBO, Anda harus menggunakan shader untuk semuanya dan melakukan matrik mengubah diri Anda (atau menggunakan GLM).

Satu-satunya alasan untuk menggunakan barang-barang lama adalah jika Anda ingin menargetkan OpenGL sebelum 2.0. yang kembali dirilis pada tahun 2003. Ada beberapa chipset netbook tertanam benar-benar jelek yang 1,5 tetapi bahkan 1,5 harus mendukung VBO hanya tidak shader. Atau OpenGL ES 1.x yang didasarkan pada pipeline fungsi tetap (misalnya digunakan pada iPhone yang lebih lama). Atau OpenGL SC (untuk sistem kritis keamanan).

Fungsi-fungsi yang umum digunakan berikut semuanya sudah usang:

  • glBegin
  • GlEnd
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

The opengl-tutorial.org tutorial memiliki apa yang saya pikir adalah cara terbaik untuk pergi tentang belajar OpenGL. Mereka bergantung pada beberapa hal kepatuhan warisan tetapi mereka tidak benar-benar mengajarkannya kepada Anda. Misalnya Anda tidak seharusnya membuat apa pun tanpa shader tetapi berhasil. Dan Anda perlu menangani operasi matriks sendiri (memutar, menerjemahkan, dll.) Sendiri tetapi secara default Anda akan mendapatkan viewport 2D dasar datar.

Selain menghindari hal-hal yang sudah usang ada banyak fungsi yang membuat pengkodean OpenGL jauh lebih baik tetapi dengan banyak dari mereka Anda harus memutuskan apakah Anda baik-baik saja dengan memerlukan versi 3.x + yang lebih baru dari OpenGL dan perangkat keras yang kompatibel.

Ada lebih banyak info dalam posting yang saya buat di sini .

Jika Anda perlu mendukung OpenGL yang lebih lama karena suatu alasan, Anda dapat menggunakan VBO bila memungkinkan dan ketika tidak, berikan fallback yang menggunakan glBegin / glEnd dan lewati data vertex Anda.

Di sisi lain, tidak ada cara 'mudah' nyata untuk mengubah kode render lama. Anda mungkin bisa mengimplementasikan versi Anda sendiri dari fungsi-fungsi yang menambahkan simpul ke array / vektor yang kemudian membuangnya ke VBO dan menariknya ketika Anda palsu glEnd dipanggil. tapi itu akan sangat tidak efisien karena akan melakukannya setiap frame (kecuali Anda memberi tanda centang untuk hanya melakukannya sekali tapi itu tidak berfungsi untuk objek animasi) dan mungkin akan lebih banyak pekerjaan yang hanya beralih ke VBO. Saya kira jika Anda memiliki banyak kode pendekatan yang mungkin berhasil.

David C. Bishop
sumber
7

Dengan VBO Anda umumnya memiliki dua keunggulan utama.

Keuntungan 1 berhubungan dengan data yang sepenuhnya statis dan berasal dari kemampuan untuk menyimpan data verteks Anda dalam memori yang lebih optimal untuk GPU.

Keuntungan 2 berhubungan dengan data dinamis dan berasal dari kemampuan untuk menentukan data verteks Anda kapan saja sebelum menggunakannya untuk rendering, yang dapat menyalurkan lebih baik.

Keuntungan ketiga berasal dari batch call draw, tetapi juga dibagikan dengan array vertex jadul jadi saya tidak memanggilnya khusus untuk VBO. Mengirim data ke GPU (atau menggunakan data yang sudah ada di GPU) serupa dalam banyak hal dengan I / O disk dan lalu lintas jaringan - jika Anda memiliki beberapa batch besar, itu lebih efisien daripada banyak batch kecil.

Analogi yang baik (tidak 100% akurat tetapi cukup untuk membantu Anda mendapatkan ide) untuk ini adalah jika Anda seorang pengemudi bus yang harus membawa 50 orang dari satu kota ke kota lain. Anda dapat memuatnya satu per satu dan melakukan 50 perjalanan terpisah - itulah glBegin / glEnd. Atau Anda dapat menempatkan semua 50 di bus dan hanya melakukan perjalanan tunggal - itu batching dengan array vertex atau VBO (dalam kasus VBO 50 orang sudah berada di bus;)).

Ini ada harganya, dan di sini harganya adalah Anda kehilangan kemampuan untuk hanya menentukan data titik saat dan ketika Anda membutuhkannya. Baiklah, Anda bisa melakukannya (dengan beberapa pekerjaan tambahan), tetapi Anda tidak akan mendapatkan kinerja penuh dari kode Anda. Alih-alih, Anda perlu lebih memikirkan data verteks Anda, bagaimana data itu digunakan, bagaimana (dan jika) itu perlu diperbarui, apakah ada animasi yang dapat dilakukan dalam shader (sehingga memungkinkan data tetap statis - VBO benar-benar membutuhkan shader untuk banyak kasus animasi agar bekerja dengan baik) atau apakah Anda perlu meresepkan data vertex setiap frame, strategi pembaruan yang efisien jika yang terakhir, dll. Jika Anda tidak melakukan ini dan hanya menerapkan konversi naif Anda memiliki risiko yang sangat tinggi untuk menempatkan dalam banyak pekerjaan hanya untuk hasil akhirnya benar-benar berjalan lebih lambat!

Ini bisa tampak seperti pekerjaan yang sangat buruk ketika Anda pertama kali menemukannya, tetapi sebenarnya tidak. Setelah Anda masuk ke mode berpikir seperti ini, Anda akan benar-benar menemukan bahwa itu sangat mudah dan hampir muncul secara alami. Tetapi Anda dapat mengacaukan beberapa upaya pertama Anda dan Anda tidak harus berkecil hati jika demikian - mengacaukan adalah kesempatan untuk belajar dari kesalahan Anda.

Beberapa pemikiran terakhir.

Memiliki data model Anda dalam format yang dapat dengan mudah dimuat ke VBO dapat membantu membuat seluruh proses ini jauh lebih mudah bagi Anda. Itu berarti Anda harus menghindari format yang lebih kompleks atau eksotis, setidaknya pada awalnya (dan sampai Anda lebih nyaman dengan prosesnya); pertahankan hal-hal sesederhana dan sesederhana mungkin saat belajar dan akan ada lebih sedikit hal yang salah, dan lebih sedikit tempat yang harus dicari kesalahannya jika (atau kapan!) ada yang salah.

Orang-orang kadang-kadang menunda jika mereka melihat implementasi VBO menggunakan lebih banyak memori daripada implementasi glBegin / glEnd yang dioptimalkan / terkompresi (mereka bahkan dapat menyebutnya sebagai "limbah"). Jangan seperti itu. Kecuali dalam kasus yang ekstrim, penggunaan memori benar-benar tidak begitu penting. Ini pertukaran yang jelas di sini - Anda menerima kemungkinan penggunaan memori yang lebih tinggi dengan imbalan kinerja yang jauh lebih tinggi. Juga membantu mengembangkan pola pikir bahwa ingatan adalah sumber daya yang murah dan berlimpah yang ada untuk digunakan; kinerja tidak.

Dan akhirnya kastanye tua - jika sudah cukup cepat maka pekerjaan Anda selesai. Jika Anda menekan framerate target Anda, jika Anda memiliki ruang kepala untuk kondisi sementara, maka itu cukup baik dan Anda dapat melanjutkan ke langkah berikutnya. Anda dapat membuang banyak waktu dan energi untuk memeras tambahan 10% dari sesuatu yang sebenarnya tidak membutuhkannya (pernah ada, melakukan itu, masih jatuh ke dalam perangkap) jadi selalu pertimbangkan penggunaan paling optimal dari waktu Anda sendiri. - karena waktu programmer bahkan lebih murah dan kurang melimpah dari kinerja!

Maximus Minimus
sumber