Secara umum, jawabannya adalah "itu tergantung." Cara seseorang mengirim pembaruan partikel agak sedikit berbeda dari cara Anda mengirim serangkaian model berkulit GPU.
Vertex / Indeks Buffer
Dalam arti umum, bagaimanapun, semua hari ini dilakukan dengan VBO (objek vertex buffer ). API mode langsung lama ( glBegin
/ glEnd
) mungkin hanya diimplementasikan sebagai pembungkus lemak di sekitar sistem buffer vertex internal pengemudi.
Untuk objek statis, buat VBO statis dan isi dengan data titik Anda. Jika ada simpul yang dibagikan (biasanya case), Anda mungkin juga ingin membuat buffer indeks. Keduanya mengurangi kebutuhan untuk mengirim data yang sama lebih dari satu kali untuk mengubah jerat (berpotensi menghemat transfer bandwidth) dan pada pemrosesan (menghemat waktu shading vertex). Perhatikan bahwa Anda menggambar dengan berbagai fungsi saat membuat pengundian yang diindeks vs yang tidak diindeks.
Untuk objek dinamis, lakukan hal yang sama, meskipun dengan set buffer yang dinamis.
Catatan Lanjut
Untuk potongan yang lebih besar seperti medan, Anda mungkin tidak akan memecah jala menjadi beberapa bagian. Membuat GPU membuat seratus juta segitiga ketika hanya dua ratus ribu dari mereka yang terlihat adalah sangat besar, terutama jika itu tidak disortir dan ada banyak permintaan cerukan shader fragmen yang terbuang dan terbuang. Pisahkan mesh menjadi potongan besar dan kemudian hanya membuat orang-orang yang dalam pandangan frustrasi. Ada juga berbagai teknik pemusnahan yang lebih maju yang dapat Anda gunakan untuk menyingkirkan bongkahan-bongkahan yang mungkin berada dalam frustasi tetapi sepenuhnya di belakang bukit atau bangunan atau sesuatu. Mempertahankan hitung mundur panggilan imbang adalah baik, tetapi ada keseimbangan yang bisa didapat (yang harus Anda temukan untuk aplikasi / perangkat keras khusus Anda) antara meminimalkan panggilan draw dan meminimalkan menggambar geometri tersembunyi.
Salah satu hal utama yang perlu diingat dengan buffer GPU adalah bahwa Anda tidak dapat menulis kepadanya ketika GPU membaca dari itu. Anda perlu memberi tahu pengemudi bahwa tidak apa-apa untuk membuang salinan buffer yang lama (setelah selesai) dan memberi Anda yang baru (jika yang lama sibuk). Tentu saja untuk waktu yang lama tidak ada fungsi OpenGL untuk melakukan ini (sekarang ada InvalidateBufferData untuk GL 4.3 dan beberapa implementasi yang lebih lama sebagai ekstensi). Sebaliknya, ada perilaku non-standar tetapi umum yang diterapkan sebagian besar driver. Lakukan ini untuk membuang buffer sebelum memperbaruinya:
glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_DYNAMIC_DRAW);
Tentu saja berubah GL_ARRAY_BUFFER
dan GL_DYNAMIC_DRAW
ke nilai yang sesuai untuk buffer. Buffer statis tidak akan diperbarui (atau tidak boleh jadi) sehingga Anda tidak perlu khawatir tentang membuang buffer seperti itu.
Perhatikan bahwa mungkin lebih cepat digunakan glBufferData
atau glBufferSubData
lebih cepat glMapBuffer
. Itu benar-benar tergantung pada driver dan perangkat keras. Perangkat keras PC generasi sekarang mungkin akan paling cepat dengan glBufferData
tetapi uji untuk memastikan.
Teknik lain adalah menggunakan instancing . Instancing memungkinkan Anda untuk membuat satu panggilan undian yang menarik banyak salinan data dalam buffer vertex / indeks. Jika Anda memiliki, katakanlah, 100 batu identik maka Anda ingin menggambar semuanya dalam sekali jalan daripada membuat 100 undian independen.
Saat membuat instance, Anda harus memasukkan data per-instance ke buffer lain (seperti posisi objek masing-masing individu). Ini bisa berupa buffer seragam ( buffer konstan dalam terminologi D3D) atau buffer tekstur atau atribut vertex per-instance. Sekali lagi, mana yang lebih cepat tergantung. Atribut per-instance mungkin lebih cepat dan pasti jauh lebih mudah untuk digunakan, tetapi banyak implementasi GL umum masih tidak mendukung glBindingAttribDivisor
sehingga Anda harus melihat apakah itu tersedia untuk digunakan dan apakah itu benar-benar lebih cepat (beberapa driver yang lebih lama meniru instancing dengan menambahkan buffer dan akhirnya menjadi lebih lambat untuk menggunakan instancing pada mereka daripada membuat panggilan draw independen dan tidak ada cara standar untuk mengetahuinya ... kesenangan menggunakan OpenGL).
Ada juga algoritma untuk optimasi cache vertex , yang merupakan tindakan memesan simpul / indeks di buffer Anda untuk bermain akan dengan cache vertex pada GPU modern. GPU hanya akan menjalankan shader untuk sebuah vertex kemudian men-cache-nya dalam vertex cache tetapi mungkin harus diusir terlalu dini untuk memberi ruang bagi verteks lainnya. (Katakanlah, dua segitiga sama-sama berbagi satu simpul tetapi ada 100 segitiga lain yang ditarik di antara mereka; simpul bersama itu mungkin akan berakhir sia-sia dievaluasi oleh vertex shader dua kali.)
Beberapa fitur ini memerlukan versi GL atau GLES yang cukup baru. GLES2 tidak mendukung penerbitan, misalnya.
Selalu Profil
Sekali lagi, jika Anda peduli dengan kinerja, uji setiap metode yang mungkin dan lihat mana yang lebih cepat untuk aplikasi Anda pada perangkat keras target Anda. Tidak hanya perangkat keras / driver yang berbeda dari produsen yang berbeda akan berbeda, tetapi beberapa kelas perangkat keras juga berbeda secara bawaan. GPU seluler tipikal adalah binatang yang sangat berbeda dari GPU desktop diskrit yang khas. Teknik yang "terbaik" pada satu belum tentu terbaik pada yang lain.
Ketika berbicara tentang kinerja, selalu bersikap skeptis .