Cara tercepat untuk menggambar paha depan di OpenGL ES?


22

Saya menggunakan OpenGL ES 2.0. Saya memiliki banyak quads untuk digambar, akan senang untuk dapat melewati hanya 4 simpul per quad seolah-olah saya menggunakan GL_QUADS, tetapi pada dasarnya saya hanya ingin tahu cara terbaik menggambar sebuah sekelompok paha depan yang terpisah.

Sejauh ini apa yang saya temukan dapat saya lakukan: -GL_TRIANGLES (6 simpul per quad) -Deregenerasi GL_TRIANGLE_STRIP (6 simpul per quad)

Kemungkinan yang saya temukan: -GL_TRIANGLE_STRIPS dengan nilai indeks khusus yang me-reset quad strip (ini berarti 5 indeks per quad, tapi saya rasa ini tidak mungkin adalah OpenGL ES 2.0)

Jawaban:


33

Cukup gunakan buffer indeks dan GL_TRIANGLES. Dalam hal ini Anda memerlukan 4 simpul + 6 indeks per quad (6 indeks tambahan mungkin terdengar overhead yang besar tetapi kenyataannya tidak - setelah Anda membuat buffer indeks Anda, Anda tidak perlu menyentuhnya lagi). Lihat halaman ini untuk informasi lebih lanjut (cari glDrawElements)

Contoh kode sederhana:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Juga, jika Anda menggambar hanya satu quad Anda hanya perlu 4 simpul untuk menggambarnya dengan strip segitiga ( seperti yang ditunjukkan dalam wikipedia ) tetapi saya kira Anda sudah tahu ini.


Trik tradisional untuk menggabungkan beberapa strip segitiga menjadi satu strip adalah "degenerate triangles": Mengulang elemen terakhir dari satu strip dan elemen pertama dari strip berikutnya menciptakan 2 segitiga dengan area nol, yang dengan demikian tidak menghasilkan apa-apa. Pertimbangkan indeks quad kedua (4, 5, 6, 7). Buffer indeks untuk GL_TRIANGLE_STRIP dari dua quads dapat berupa: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Segitiga yang merosot adalah 3,3,4dan 3,4,4. Apakah layak melakukan ini? Tidak, kecuali paha depan Anda cenderung berpasangan (atau lebih) dengan tepi yang sama. Jika quad kedua adalah {3, 2, 4, 5} maka strip adalah {0,1,3,2,5,4}.
ToolmakerSteve

8
Dan untuk memperjelas ini kepada siapa pun yang datang dan perlu menggambar sekelompok paha depan: Demi kinerja, JANGAN menyalin kode di atas, dan membuat panggilan glDrawElements SEKALI UNTUK SETIAP QUAD . Alih-alih, buat SATU array array dan ONE array indeks yang mencakup SEMUA paha depan yang ingin Anda gambar. Menggunakan GL_TRIANGLES, dua paha depan bisa memiliki indeks {0,1,2, 0,2,3, 4,5,6, 4,6,7}atau sama baiknya {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Kelas yang bagus untuk membantu ini adalah glText-Android / SpriteBatch
ToolmakerSteve

6

Menggunakan buffer indeks tidak selalu lebih cepat, seperti yang ditunjukkan dalam dokumen Apple, "Untuk kinerja terbaik, model Anda harus diserahkan sebagai strip segitiga tidak terindeks menggunakan glDrawArrays" .

Jadi, sementara a GL_TRIANGLE_STRIPakan melakukannya dalam 4 simpul tanpa memerlukan buffer indeks, dan Anda dapat menggunakan buffer indeks, itu cukup lemah untuk mencoba "menyimpan" mengulangi 2 simpul . Untuk alasan ini, saya sarankan Anda menggambar 2 terpisah GL_TRIANGLESdan ulangi 2 simpul pada diagonal .


8
Um, tidak. Apa yang dikatakan oleh dok adalah bahwa model Anda dikirimkan sebagai strip segitiga INDEXED tunggal. Dan kalimat berikutnya adalah, "Untuk menghindari menentukan data untuk vertex yang sama beberapa kali dalam buffer vertex, gunakan buffer indeks terpisah dan gambarkan strip segitiga menggunakan fungsi glDrawElements". Yang persis seperti yang Anda putuskan adalah 'lumpuh'.
davidf2281

3
Mengingat bahwa paragraf dokumen sekarang merujuk ke glDrawElements daripada glDrawArrays, mungkin telah ditulis ulang sejak jawaban ini. Namun demikian, poin yang dibuat oleh dok adalah bahwa, untuk kinerja, menyediakan satu strip (daripada beberapa strip, maka beberapa panggilan). Dalam situasi ini, saya percaya perbedaan antara menggunakan indeks atau tidak tidak signifikan ; yang penting adalah memasukkan semuanya ke dalam satu vertex array (ditambah array indeks opsional), sehingga Anda dapat membuat panggilan gl tunggal.
ToolmakerSteve

0

Keuntungan besar pada desktop adalah memindahkan data ke GL_STATIC_DRAW VBOs. Agaknya ini juga berlaku pada GPU MBX iPhone.


-2

Menggunakan GL_TRIANGLE_FANuntuk quad menggunakan 4 simpul, bukan 6.


Yap, tetapi begitu juga GL_TRIANGLE_STRIP, seperti yang sudah ditunjukkan oleh jawaban lain.
Anko

@Bapak. Blah - Anda telah melewatkan inti pertanyaan, yaitu bagaimana melakukan sekelompok paha depan secara efisien . Seseorang seharusnya tidak membuat panggilan gl untuk setiap quad, tetapi menggabungkan banyak paha depan menjadi satu array, yang dapat ditarik dengan panggilan gl tunggal. GL_TRIANGLE_FAN tidak akan membantu dengan ini, karenanya jarang berguna dalam rendering kinerja tinggi.
ToolmakerSteve
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.