Di OpenGL, apakah ide buruk untuk "menggabungkan" mode langsung dan mode dipertahankan demi GUI?


8

Misalkan saya memiliki adegan 3D yang sedang digambar glDrawArrays(...)dan saya ingin membuat sesuatu yang sederhana, seperti overlay 2D. Apakah itu ide yang buruk untuk menggunakan mode langsung untuk hal seperti itu, daripada menyiapkan penyaji 2D dengan mode dipertahankan?

Contoh:

void Draw()
{
    // Draw the 3D scene:
    // *does stuff*
    glDrawArrays(...);
    // *some other stuff*

    // Setup a quad with immediate mode (for something like a vignette overlay)
    glBegin(GL_QUADS);
    glTexCoord2f(...); glVertex2f(...);
    glEnd();
}

Minecraft melakukan ini. Ini berfungsi dengan baik, kecuali untuk membatasi versi OpenGL Anda (ke <3.1 atau profil kompatibilitas) dan untuk membuat GUI Anda lebih cepat.
user253751

Catatan Minecraft juga memiliki serangkaian fungsi sendiri yang mensimulasikan mode langsung menggunakan array vertex - tidak sulit untuk menulis. Saya tidak yakin apakah mereka menggunakannya untuk GUI.
user253751

Jawaban:


7

Itu adalah ide yang buruk sejauh itu tidak masuk akal. Tidak ada "pengaturan" yang belum Anda lakukan, kecuali untuk matriks proyeksi ortho (yang harus Anda lakukan dalam hal apa pun).

Portabilitas mungkin bukan masalah, meskipun seharusnya begitu. IHV tampaknya sangat enggan untuk menjatuhkan dukungan untuk mode segera untuk masa mendatang (tampaknya "bekerja dengan baik" bahkan dalam profil inti), jadi meskipun mode langsung seharusnya sudah mati sejak lama, itu mungkin akan tetap selamanya. Kinerja adalah cerita lain. Apakah Anda benar-benar menginginkan sesuatu yang menyumbang 0,1% dari kompleksitas adegan untuk mengkonsumsi 15-20% dari waktu CPU - panggilan GL relatif ringan, dibandingkan dengan misalnya DX, tetapi mereka tidak gratis - dan 15-20% dari waktu bingkai nyata karena menunda pipa? Bisakah Anda membayarnya dengan anggaran waktu Anda? Sebagian besar permainan tidak bisa.

Dan tentu saja, keanehan. Oh kebiasaan itu. Keindahan nyata dari mode langsung adalah bahwa (tampaknya) mudah dan mudah untuk melakukan sesuatu seperti menggambar beberapa paha depan dengan cepat. Pada kenyataannya, mode langsung bisa sangat menyusahkan di belakang, begitu penuh dengan perangkap yang tidak jelas.
Di sisi lain, sama mudahnya (dan lebih mudah jika Anda bertanya kepada saya!) Hanya menulis fungsi 5-LOC kecil DrawQuadyang ketika dipanggil menambahkan koordinat titik dan indeks ke buffer memori dan menambah penghitung. Yang, mengejutkan, Anda kemudian dapat menggambar dengan glDrawArrays/Elementsdan yang dapat Anda gunakan kembali (salinan GPU, bukan hanya salinan pengguna!) Bingkai berikutnya apa adanya selama tidak ada yang berubah.
Mode langsung harus, tidak ada cara lain, mengalokasikan buffer dan melakukan transfer PCIe setiap waktu. Atau, sesuatu yang setara dalam latensi (GPU membaca memori utama melalui bus, apa pun). Pengemudi tidak mungkin tahu (atau berasumsi) bahwa data tetap sama persis dengan bingkai sebelumnya.

Mendapatkan data ke GPU adalah kecepatan tinggi, tetapi juga operasi latensi tinggi . Tidak hanya transfer bus per se rumit, protokol latency tinggi (beberapa lapisan protokol, packetizing, ucapan terima kasih, dll), tetapi juga tidak semua GPU bahkan mampu mentransfer dan menarik pada saat yang sama, atau jika mereka dapat melakukannya , mereka mungkin tidak dapat setiap saat untuk beralih di antara atau memulai operasi baru secara bebas saat melakukan sesuatu yang berbeda. Baca sebagai: Jangan mentransfer dengan sia-sia .


"Tidak ada yang perlu" diatur "yang belum Anda lakukan" rendering batch?
HolyBlackCat

2
Meskipun IHV enggan untuk segera drop mode, ada juga driver video di Linux yang tidak mendukung versi OpenGL yang lebih tinggi kecuali jika Anda meminta Core Profil. Ini khususnya berarti Intel HD graphics ( inteldriver), tetapi juga chip NVidia dan AMD ketika menggunakan driver open-source ( nouveaudan amdgpumasing - masing). Demikian pula, pada MacOS Anda juga tidak memiliki Profil Kompatibilitas dengan OpenGL> 2.1.
Ruslan

@HolyBlackCat: Saya tidak yakin apa yang Anda maksud? Negara OP memiliki pipeline 3D yang berfungsi berdasarkan glDrawArrays. Jadi ada semua yang diatur yang diperlukan untuk melakukan panggilan lain ke glDrawElements(atau Array, mana saja) untuk menggambar semua paha depan untuk GUI (setelah menulis simpul ke buffer). Fungsinya dimuat, Anda memiliki kerangka kerja untuk mengalokasikan buffer, dll. Tidak ada yang istimewa untuk dilakukan dengan menumpuk GUI, sungguh. Hanya mengikat (atau tidak, jika Anda memiliki cukup TU yang tersisa untuk membiarkannya terikat) tekstur GUI, atur matriks orto, dan lakukan satu panggilan draw tambahan. Bagaimana Anda ingin melakukan batch yang lebih baik?
Damon

(Tentu saja saya setuju bahwa mode langsung buruk.) Maaf jika saya tidak jelas. Maksud saya proses mengisi kata buffer vertex. Itu mudah, tetapi sedikit lebih banyak pekerjaan yang menggunakan mode langsung.
HolyBlackCat

12

Saya pribadi hanya melihatnya sebagai buruk karena dua alasan:

  1. Ini sangat ketinggalan jaman dan usang. Dan,
  2. Ini jauh lebih lambat daripada cara menggambar modern dengan OpenGL.

Tetapi, jika itu berhasil, dan kinerja tidak akan menjadi masalah, dan jika itu bukan masalah bagi Anda untuk menggunakan fungsi OpenGL yang sudah tidak digunakan lagi dalam program Anda, maka saya yakin Anda bisa melakukannya. Akan lebih lambat memiliki BANYAK dan BANYAK GUI, tetapi jika tidak banyak, sekali lagi, lakukanlah.

Pahamilah ini. Bahwa pada akhirnya, OpenGL melakukan hal yang sama; menggambar ke layar. Mode langsung hanya jauh lebih lambat jika Anda memiliki banyak hal yang sedang diproses. Jadi, Anda harus memilih apa yang paling berguna untuk tugas yang ada dalam pikiran Anda. Semoga ini bisa membantu Anda!


1

Kelemahan lain adalah membuat kode Anda kurang portabel. Varian OpenGL tertentu tidak mendukung mode langsung sama sekali, misalnya, OpenGL ES. (dan perangkat berbasis Android kaliber lebih besar seperti tablet mendapatkan lebih banyak daya tarik, itu bisa menjadi penting)


0

Menggunakan mode langsung sama sekali tidak perlu untuk pekerjaan terkait gui.

Untuk membuat item gui sederhana, katakanlah, tombol:

  1. Anda membutuhkan mesh strip quad / triangle,
  2. Tekstur untuk mesh
  3. Transformasi proyeksi ortografis

Dengan cara ini, Anda bisa menulis shader pass-through sederhana yang mengabaikan pertimbangan pencahayaan, dan Anda hanya menskala item gui ke skala piksel, atau beberapa persentase dari jendela, dan kemudian melakukan algoritma pelukis untuk rendering.

Dengan cara ini, Anda dapat melakukan sistem ui penuh dengan semua manfaat kinerja dari mode dipertahankan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.