Saya melihat bahwa OpenGL versi 3 dan lebih tinggi menghilangkan penggunaan rendering sisi klien. Mode segera telah dihilangkan, dan array vertex tampaknya sudah usang. Sebaliknya, jika saya mengerti dengan benar, VBO adalah cara utama rendering simpul.
Sementara saya melihat logika di balik memiliki cara yang seragam untuk merender semuanya, apakah ini kasus bahwa VBO tidak memiliki kerugian besar atas array vertex? Saya pikir VBO seharusnya adalah buffer besar yang mengandung> 1MB data, secara umum. Bagaimana jika saya memiliki pemandangan yang memiliki banyak geometri yang lebih kecil? Saya memiliki grafik adegan dengan sejumlah besar node, yang masing-masing membutuhkan transformasi sendiri, dll. Setiap node juga harus dapat dihapus secara terpisah, ditambahkan secara terpisah, dll. Saya menggunakan array vertex sebelumnya. Jadi pertanyaan pertama saya adalah apakah, jika saya beralih ke VBO, akan ada overhead yang lebih besar untuk objek grafik adegan saya sekarang karena VBO perlu dialokasikan untuk setiap objek.
Kekhawatiran lain adalah bahwa geometri yang saya render bisa sangat dinamis. Dalam kasus terburuk, mungkin ada saat-saat ketika semua geometri perlu dikirim ulang setiap frame untuk beberapa periode waktu. Akankah VBO memiliki kinerja yang lebih buruk daripada array vertex dalam kasus penggunaan ini, atau apakah VBO paling buruk berfungsi seperti halnya array vertex tetapi tidak lebih?
Jadi, dalam format yang lebih ringkas, pertanyaan saya adalah:
1) Apakah ada overhead yang substansial untuk mengalokasikan / membatalkan alokasi VBO (maksud saya hanya tindakan mendirikan buffer)?
2) Jika saya memperbarui data dari CPU setiap frame, dapatkah ini jauh lebih buruk daripada jika saya menggunakan array vertex?
Dan akhirnya, saya ingin tahu:
3) Jika jawaban untuk salah satu dari pertanyaan di atas adalah "ya", mengapa mencabut mode rendering lain yang dapat memiliki keunggulan dibandingkan VBO? Apakah ada sesuatu yang saya lewatkan di sini, seperti teknik yang seharusnya saya gunakan untuk mengurangi beberapa biaya alokasi potensial ini, dll.?
4) Apakah jawaban untuk semua pertanyaan ini berubah secara substansial tergantung pada versi OpenGL apa yang saya gunakan? Jika saya refactor kode saya menjadi OpenGL 3 atau 4 yang kompatibel dengan maju dengan menggunakan VBO dengan cara yang performan, apakah teknik yang sama akan berfungsi dengan baik dengan OpenGL 2, atau kemungkinan teknik tertentu jauh lebih cepat dengan OpenGL 3 + dan yang lainnya dengan OpenGL 2?
Saya mengajukan pertanyaan ini pada stack overflow, tetapi saya memposting ulang di sini karena saya menyadari situs ini mungkin lebih sesuai untuk pertanyaan saya.
sumber
Jawaban:
Definisikan "substansial." Biasanya bijaksana untuk tidak membuatnya di tengah bingkai; mereka harus diatur selama inisialisasi atau di mana pun. Tapi ini berlaku untuk sebagian besar objek OpenGL, seperti tekstur, renderbuffers, atau shader.
Bisa kah? Iya nih. OpenGL mendefinisikan fungsionalitas, bukan kinerja . Anda memang bisa membuat banyak hal lebih lambat. Atau Anda dapat membuat segalanya lebih cepat. Itu semua tergantung pada bagaimana Anda menggunakannya.
Wiki OpenGL memiliki artikel bagus tentang cara mengalirkan data dengan benar .
Pertama, mereka tidak hanya ditinggalkan. Penghentian berarti menandai sesuatu sebagai "akan dihapus" di versi mendatang. Mereka tidak digunakan lagi di 3.0, dan dihapus di 3.1 core ke atas.
Kedua, ARB secara umum menjelaskan alasan mereka menghapus barang dari OpenGL. Itu membuat spec lebih kecil dan lebih sederhana. Itu membuat API lebih kecil dan lebih ramping. Ini membuatnya lebih mudah untuk mengetahui API apa yang seharusnya Anda gunakan; 2.1 memiliki 4 cara untuk menyediakan data titik; 3.1+ memiliki 1. Ini menghilangkan banyak celah. Dll
Kurang lebih tidak. Hanya pada MacOSX perbedaan antara versi 3.1 + inti dan pra-3.0 benar-benar tampak. Profil kompatibilitas diterapkan oleh semua driver untuk Linux dan Windows, sehingga Anda dapat mengasumsikan bahwa profil inti dari driver ini benar-benar hanya menambahkan pemeriksaan untuk mencegah Anda memanggil fungsi kompatibilitas.
Di bawah Mac OSX 10.7, GL 3.2 core tersedia, tetapi bukan profil kompatibilitas. Yang tidak selalu berarti apa-apa bagi kinerja teknik pada satu versus lain. Tetapi itu berarti bahwa jika ada perbedaan, itu adalah platform Anda akan melihatnya.
sumber
Cara OpenGL bekerja, kapan pun Anda menggunakan data non-VBO, driver harus membuat salinannya - dalam praktiknya membuat VBO sementara - karena tidak ada yang menghalangi Anda dari memodifikasi ruang kosong array pengguna-ruang Anda antara panggilan ke OpenGL.
Mungkin ada beberapa tipuan sisi pengemudi untuk membuat alokasi temp lebih cepat, tetapi tidak ada yang dapat Anda lakukan untuk menghindari penyalinan.
Jadi ya, selama Anda - dan pengembang driver - melakukan segalanya dengan benar, VBO harus (tm) selalu mempercepat.
sumber
glDrawRangeElements
untuk menggambar masing-masing objek, atau apakah itu tidak efisien seperti array vertex?glDrawRangeElements
beberapa kali pada setiap VBO dengan beberapa VBO daripada memberikan masing-masing objek VBO sendiri?Tidak terlalu. Array vertex adalah dasar untuk objek buffer verteks. Hanya penyimpanan yang dipindahkan dari klien ke sisi server.
Gabungkan set geometri yang lebih kecil menjadi VBO yang lebih besar. Tidak perlu memiliki satu VBO per batch geometri. Anda dapat dengan sempurna menangani subset VBO untuk rendering. Gunakan offset bukan-nol untuk parameter data Pointer ... gl.
Untuk ini ada flag penggunaan buffer GL_DYNAMIC_DRAW dan GL_STREAM_DRAW.
Karena tidak ada kelebihan. Bagaimanapun, data geometri harus ditransfer ke GPU. Menggunakan array sisi klien biasa masih akan menyebabkan transfer DMA ke GPU, dan mode langsung akan membangun batch untuk ditransfer terlebih dahulu juga.
Sama sekali tidak ada manfaatnya jika tidak menggunakan VBO.
sumber