Konsep awal
Ok, jadi yang saya kumpulkan sejauh ini adalah ini:
- jangan gunakan pipa tetap (usang atau akan ditinggalkan)
- vbos menyimpan "model objek" (sebagian besar data n)
- vaos menjelaskan bagaimana data diletakkan sehingga panggilan menarik tahu bagian apa dari masing-masing vbo untuk jenis informasi vertex apa (satu vao dapat merujuk ke beberapa vbos, sebaliknya agak sulit)
- setiap panggilan undian juga mengirim data titik ke shader
Bagaimana saya melihat 3D (opsional)
Dengan informasi ini, saya dapat melihat bagaimana menggambar objek rumit 3D sangat bagus dengan OpenGL modern. Anda pada dasarnya memuat banyak model objek (mungkin dari Blender atau perangkat lunak serupa lainnya) ke dalam VBO dengan koordinat lokal, dan kemudian Anda cukup menyediakan untuk setiap instance objek parameter shader yang berbeda (offset) untuk menarik ruang dunia.
Masalah / pertanyaan
Dalam masalah dan prioritas 2D sama sekali berbeda. Anda tidak menggambar banyak objek yang kompleks, Anda tidak perlu matriks proyeksi yang rumit dan yang lainnya dan shader jauh lebih sederhana.
Apa yang akan menjadi cara terbaik untuk menggambar secara teratur (sangat sering, pada dasarnya setiap frame) mengubah geometri dengan OpenGL modern?
Dalam paragraf berikut, Anda dapat melihat beberapa ide masalah (masalah lingkaran dan persegi panjang), yang lebih baik mengidentifikasi jenis perubahan yang saya minati.
Upaya saya (opsional)
Jadi, saya mulai berpikir bagaimana saya akan berurusan dengan menggambar geometri 2D dasar di layar:
- a square: memuat
[(1, 0), (1, 1), (0, 1), (0, 0)]
VBO untuk geometri persegi di ruang lokal, lalu berikan shader lebar aktual persegi dan koordinat dunia serta informasi warna
keren, terlihat mudah. Mari kita pindah ke lingkaran:
- a circle: triangle fan with ... eh. berapa presisi (jumlah vertex)? untuk presisi lingkaran kecil harus kecil dan untuk presisi lingkaran bug harus tinggi. Jelas memuat 1 VBO tidak mungkin cocok untuk semua kasus. Bagaimana jika saya perlu menambahkan presisi karena ukuran lingkaran diubah menjadi lebih besar?
Kurang keren Mari kita pindah ke sesuatu yang sedikit lebih mudah, persegi panjang:
- sebuah persegi panjang: eh. tidak ada "geometri persegi panjang umum". Anda hanya memiliki proporsi lebar / tinggi dan hanya itu, tetapi masing-masing persegi panjang mungkin berbeda jika ukurannya berubah.
Seperti yang Anda lihat, segalanya menjadi menurun dari sana. Terutama dengan poligon yang kompleks dan yang lainnya.
Tidak ada kebijakan kode: P
Saya hanya perlu ikhtisar ide, tidak ada kode yang diperlukan, terutama kode C atau C ++. Katakan saja hal-hal seperti: "buat VBO dengan data titik ini, lalu ikat, ...".
Jawaban:
Pertanyaan utama Anda tampaknya adalah:
Dalam banyak hal, tidak ada perbedaan besar antara OpenGL 2d dan 3d. Pipeline grafik memiliki satu koordinat tambahan, Z, yang tidak akan banyak digunakan dalam 2d, tapi hanya itu saja.
Ada beberapa cara untuk mengubah geometri pada setiap undian.
Anda dapat menekan vertex yang disediakan CPU setiap frame. (Lihat /programming/14155615/opengl-updating-vertex-buffer-with-glbufferdata untuk beberapa catatan tentang penggunaan kembali buffer.)
Anda dapat menggambar bagian berbeda dari buffer yang ada, dengan
glDrawArrays(mode, first, count)
. Jika animasi loop, mungkin Anda dapat menempatkan frame yang sudah dikomputasi dengan daftar simpul yang berbeda dalam satu buffer besar, dan menggambar bagian buffer yang sesuai masing-masing frame.Anda bisa memengaruhi daftar titik dengan beberapa data lain, seperti array yang seragam, atau tekstur. Di vertex shader Anda, baca data ini dan terapkan dengan tepat. Ini hanyalah idiom lain untuk menyajikan data ke GPU, dan mungkin tidak akan memiliki banyak perbedaan dalam kinerja.
Jika Anda memiliki banyak contoh geometri yang sama (mungkin dipengaruhi oleh atribut), maka
glDrawElementsInstanced()
mungkin bergunaAnda dapat memengaruhi daftar vertex secara algoritmik dalam shader vertex, geometri, atau tessellation. Jika animasi dapat dijelaskan secara matematis, Anda mungkin dapat menyimpan daftar titik yang sama, dan mengubah hanya beberapa seragam shader setiap frame.
Dan mungkin animasi Anda dapat dinyatakan sebagai tekstur murni, dengan semua animasi dilakukan piksel demi piksel oleh cpu, atau pra-render dari disk.
Secara keseluruhan, saya akan berkata, "Komputer itu cepat, membuatnya bekerja dengan cara termudah yang Anda bisa, yang mungkin dengan mengatur simpul buatan CPU baru setiap frame. Kemudian, lihat apakah itu cukup baik. Profil baterai / penggunaan CPU pertama, jejak memori kedua. "
Pertanyaan Anda yang lain , diparafrasekan, "Apa cara yang baik untuk menggambar lingkaran dan persegi panjang?"
Lingkaran.
Dengan tessellation shaders (atau shader geometri) Anda dapat membuat geometri Anda dinamis.
Anda bisa menggambar kotak, dan dalam shader fragmen Anda hanya buram (alpha = 1,0) dalam radius, dan transparan (alpha = 0,0) di luar radius. Maka itu pixel sempurna setiap waktu. (Buat simpul bujur sangkar Anda -1 hingga +1, dan dalam fragmen shader sesuatu seperti
outColor.a = dot(coord.xy, coord.xy) < 1.0 ? 1.0 : 0.0;
,. Bisa juga menghaluskan tepi sedikit, akan terlihat bagus di sana ...)Anda bisa selalu menggunakan, katakanlah, kipas 120-segitiga. Mungkin cukup bagus.
Persegi panjang.
sumber
Saya tidak bisa mengatakan menjadi ahli dalam hal ini, dan dalam proyek permainan saya, saya lebih berkonsentrasi pada sisi 3D, jadi sisi 2D saya cukup sederhana umumnya menggunakan hal-hal yang dibuat untuk sisi 3D; dan jelas, perspektif saya adalah di sisi permainan, jadi grafis 2D saya lebih tentang blitting sprite daripada geometri. Dari perspektif itu,
1) Kotak dan persegi panjang cukup mudah. Saya hanya memiliki satu kotak 1x1 dalam VBO yang saya gunakan untuk mencampur semuanya. Saya melewatkan matriks MVP ke shader dengan "kotak unit" ini, dan saya telah menggabungkannya dengan penskalaan tambahan untuk menskalakan kotak ke dimensi yang tepat - seperti yang Anda tahu, Anda dapat memiliki skala x dan y yang berbeda.
Untuk tujuan saya, saya telah berpikir untuk beralih dari menggunakan "kotak unit" ke beberapa jenis mesin partikel untuk mencabut sprite 2D, tapi itu cerita lain.
2) Saya belum banyak bekerja dengan lingkaran, saya hanya menggunakan VBO tetap dengan jumlah simpul tertentu. Tapi saya bisa membayangkan bahwa saya bisa membuat beberapa langkah untuk mempengaruhi jumlah simpul yang ditarik untuk lingkaran.
Saat menghubungkan data VBO ke atribut shader, saya menggunakan glVertexAttribPointer. Ini memiliki parameter langkah yang dimaksudkan untuk digunakan untuk data yang disisipkan (yang saya gunakan). Tetapi mungkin bisa menggunakannya seperti ini:
... untuk memilih setiap simpul ke-n dari buffer, sehingga memengaruhi jumlah simpul yang ditarik untuk lingkaran. Saya bisa membuat beberapa VAO yang memiliki VBO yang sama dengan langkah berbeda yang mempengaruhi jumlah simpul yang ditarik untuk lingkaran. Saya belum mencobanya, pikir.
Secara umum, ya, bekerja dengan VBO dan semacam itu membuat tweaking sisi-CPU sedikit lebih rumit, mengapa saya telah mempelajari berbagai hal untuk membuat tweaker di sisi GPU (shader). Namun, menurut artikel ini, menggunakan VBO lebih efisien pada perangkat keras modern bahkan jika Anda membutuhkan banyak "intervensi" sisi CPU:
http://www.quelsolaar.com/opengl_performance.txt
Semoga ini bisa membantu Anda sedikit merancang & memutuskan arah Anda.
sumber