Game 2D dan OpenGL modern


10

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, ...".


Saya pikir saya mengerti apa yang Anda tanyakan, tetapi Anda mungkin ingin memberikan pertanyaan ini sedikit lebih banyak arah. Agak tidak jelas apa yang diminta - yang sebenarnya merupakan alasan yang dekat.
Lysol

@AidanMueller Saya tidak yakin apa yang Anda maksud, tetapi jangan ragu untuk memberikan arahan lebih jika Anda merasa perlu.
Sepatu

Jawaban teratas saat ini dimulai dengan mengatakan "Kamu sepertinya pertanyaan utama". Itu menunjukkan bahwa tidak jelas apa yang Anda tanyakan. Mungkin Anda harus memberikan ringkasan tentang apa yang tidak perlu Anda ketahui di akhir pertanyaan Anda. Bagaimanapun, ini adalah Tanya Jawab, bukan diskusi.
Lysol

@AidanMueller Tidak dalam konteks itu, saya percaya. Itu mengatakan "Pertanyaan utama Anda tampaknya ..." dan kemudian dia mengutip pertanyaan yang saya posting. Yang sebenarnya menunjukkan bahwa itu cukup jelas untuk dikutip. Juga frasa ini menunjukkan bukan bahwa pertanyaan saya tidak jelas, melainkan bahwa ada pertanyaan utama dan pertanyaan sekunder lainnya (yaitu: apa solusi untuk kasus-kasus spesifik yang saya sampaikan). Saya benar-benar tidak melihat masalah dengan pertanyaan saya saat ini, dan tampaknya bahkan para penjawab tidak melakukannya karena saya menemukan kedua jawaban itu sangat berguna dan to the point.
Sepatu

Anda dapat menggambar lingkaran yang tepat dengan shader fragmen.
user253751

Jawaban:


5

Pertanyaan utama Anda tampaknya adalah:

Apa yang akan menjadi cara terbaik untuk menggambar secara teratur (sangat sering, pada dasarnya setiap frame) mengubah geometri dengan OpenGL modern?

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 berguna

  • Anda 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.

  • Saya pikir Anda menjawab pertanyaan Anda sendiri, untuk yang itu. Apa yang Anda sarankan akan bekerja dengan baik!

Fragmen-shader / radiusnya cukup rapi, terima kasih. Sehubungan dengan saya menjawab pertanyaan saya sendiri, saya pikir saya tidak mengerti apa yang Anda maksud.
Sepatu

Oh, sama seperti dengan kotak, Anda menyebutkan untuk mengontrol lebar (dengan seragam, saya kira), dan Anda menulis, "Anda hanya memiliki proporsi lebar / tinggi dan hanya itu, tetapi setiap persegi panjang mungkin berbeda jika ukurannya berubah" . Jadi, untuk persegi panjang, lakukan hal yang sama dengan persegi tetapi Anda akan membutuhkan 4 nilai (x, y, w, h) alih-alih 3 (x, y, w). Atau lewat (xlow, xhigh, ylow, yhigh) sebagai empat seragam. Dengan input (0,0) hingga (1,1) Anda, itu sudah cukup bagi Vertex Shader untuk melakukan apa yang dibutuhkan.
david van brink

Oh, begitu, masuk akal.
Sepatu

Apakah ada penggemar otomatis dalam GL modern seperti GL_TRIANGLE_FAN dari pipa fungsi tetap?
John P

5

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:

glVertexAttribPointer(..., n * sizeof(VERTEX_DATA), ...);

... 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.


2
"melangkah tweaker untuk memengaruhi jumlah simpul yang ditarik untuk lingkaran" Super cool!
david van brink
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.