Penyajian dari Buffer Vertex dan Indeks (Direct3D 9)

Metode gambar terindeks dan tidak terindeks didukung oleh Direct3D. Metode terindeks menggunakan satu set indeks untuk semua komponen vertex. Data vertex disimpan dalam buffer vertex, dan data indeks disimpan dalam buffer indeks. Tercantum di bawah ini adalah beberapa skenario umum untuk menggambar primitif menggunakan puncak dan buffer indeks.

Contoh-contoh ini membandingkan penggunaan IDirect3DDevice9::D rawPrimitive dan IDirect3DDevice9::D rawIndexedPrimitive

Skenario 1: Menggambar Dua Segitiga tanpa Pengindeksan

Katakanlah Anda ingin menggambar quad yang diperlihatkan dalam ilustrasi berikut.

ilustrasi persegi yang terdiri dari dua segitiga

Jika Anda menggunakan jenis primitif Daftar Segitiga untuk merender dua segitiga, setiap segitiga akan disimpan sebagai 3 simpul individual, menghasilkan buffer vertex serupa dengan ilustrasi berikut.

diagram buffer vertex yang mendefinisikan tiga simpul untuk dua segitiga

Panggilan menggambar sangat mudah; mulai dari lokasi 0 dalam buffer vertex, gambar dua segitiga. Jika pemisahan diaktifkan, urutan simpul akan menjadi penting. Contoh ini mengasumsikan status pemisahan berlawanan arah jarang default, sehingga segitiga yang terlihat harus digambar searah jarang. Jenis primitif Daftar Segitiga hanya membaca tiga simpul dalam urutan linier dari buffer untuk setiap segitiga, sehingga panggilan ini akan menggambar segitiga (0, 1, 2) dan (3, 4, 5):

DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
               0,                  // StartVertex
               2 );                // PrimitiveCount

Skenario 2: Menggambar Dua Segitiga dengan Pengindeksan

Seperti yang akan Anda perhatikan, buffer vertex berisi data duplikat di lokasi 0 dan 4, 2 dan 5. Itu masuk akal karena dua segitiga berbagi dua simpul umum. Data duplikat ini boros, dan buffer vertex dapat dikompresi dengan menggunakan buffer indeks. Buffer vertex yang lebih kecil mengurangi jumlah data vertex yang harus dikirim ke adaptor grafis. Yang lebih penting lagi, menggunakan buffer indeks memungkinkan adaptor untuk menyimpan simpul dalam cache vertex; jika primitif yang digambar berisi vertex yang baru-baru ini digunakan, puncak tersebut dapat diambil dari cache alih-alih membacanya dari buffer vertex, yang menghasilkan peningkatan performa besar.

Buffer indeks 'mengindeks' ke dalam buffer vertex sehingga setiap vertex unik hanya perlu disimpan sekali di buffer vertex. Diagram berikut menunjukkan pendekatan terindeks untuk skenario gambar sebelumnya.

diagram buffer indeks untuk buffer vertex sebelumnya

Buffer indeks menyimpan nilai Indeks VB, yang mereferensikan vertex tertentu dalam buffer vertex. Buffer vertex dapat dianggap sebagai array simpul, sehingga Indeks VB hanyalah indeks ke dalam buffer vertex untuk vertex target. Demikian pula, Indeks IB adalah indeks ke dalam buffer indeks. Ini bisa sangat membingungkan dengan sangat cepat jika Anda tidak berhati-hati, jadi pastikan Anda jelas pada kosakata yang digunakan: indeks nilai Indeks VB ke dalam buffer vertex, indeks nilai Indeks IB ke dalam buffer indeks, dan buffer indeks itu sendiri menyimpan nilai Indeks VB.

Panggilan gambar ditunjukkan di bawah ini. Arti dari semua argumen dibahas panjang lebar untuk skenario gambar berikutnya; untuk saat ini, perhatikan bahwa panggilan ini lagi menginstruksikan Direct3D untuk merender daftar segitiga yang berisi dua segitiga, mulai dari lokasi 0 dalam buffer indeks. Panggilan ini akan menggambar dua segitiga yang sama dalam urutan yang sama persis seperti sebelumnya, memastikan orientasi searah jajar yang tepat:

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    0,                  // StartIndex
                    2 );                // PrimitiveCount

Skenario 3: Menggambar Satu Segitiga dengan Pengindeksan

Pura-pura sekarang Anda hanya ingin menggambar segitiga kedua, tetapi Anda ingin menggunakan buffer vertex dan buffer indeks yang sama yang digunakan saat menggambar seluruh quad, seperti yang ditunjukkan dalam diagram berikut.

diagram buffer indeks dan buffer vertex untuk segitiga kedua

Untuk panggilan gambar ini, Indeks IB pertama yang digunakan adalah 3; nilai ini disebut StartIndex. Indeks VB terendah yang digunakan adalah 0; nilai ini disebut MinIndex. Meskipun hanya tiga puncak yang diperlukan untuk menggambar segitiga, ketiga simpul tersebut tersebar di empat lokasi yang berdampingan di buffer puncak; jumlah lokasi dalam blok yang berdampingan dari memori buffer vertex yang diperlukan untuk panggilan gambar disebut NumVertices, dan akan diatur ke 4 dalam panggilan ini. Nilai MinIndex dan NumVertices benar-benar hanya petunjuk untuk membantu Direct3D mengoptimalkan akses memori selama pemrosesan verteks perangkat lunak, dan hanya dapat diatur untuk menyertakan seluruh buffer vertex dengan harga performa.

Berikut adalah panggilan gambar untuk kasus segitiga tunggal; arti dari argumen BaseVertexIndex akan dijelaskan berikutnya:

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

Skenario 4: Menggambar Satu Segitiga dengan Pengindeksan Offset

BaseVertexIndex adalah nilai yang secara efektif ditambahkan ke setiap Indeks VB yang disimpan dalam buffer indeks. Misalnya, jika kita telah meneruskan nilai 50 untuk BaseVertexIndex selama panggilan sebelumnya, yang secara fungsional akan sama dengan menggunakan buffer indeks dalam diagram berikut selama panggilan DrawIndexedPrimitive:

diagram buffer indeks dengan nilai 50 untuk basevertexindex

Nilai ini jarang diatur ke apa pun selain 0, tetapi dapat berguna jika Anda ingin memisahkan buffer indeks dari buffer vertex: Jika ketika mengisi buffer indeks untuk jala tertentu lokasi jala dalam buffer vertex belum diketahui, Anda hanya dapat berpura-pura simpul jala akan terletak di awal buffer vertex; ketika tiba saatnya untuk melakukan panggilan gambar, cukup lewati lokasi awal aktual sebagai BaseVertexIndex.

Teknik ini juga dapat digunakan saat menggambar beberapa instans jala menggunakan buffer indeks tunggal; misalnya, jika buffer vertex berisi dua jala dengan urutan gambar yang identik tetapi simpul yang sedikit berbeda (mungkin warna atau koordinat tekstur yang berbeda), kedua jala dapat digambar dengan menggunakan nilai yang berbeda untuk BaseVertexIndex. Mengambil konsep ini selangkah lebih jauh, Anda dapat menggunakan satu buffer indeks untuk menggambar beberapa instans jala, masing-masing terkandung dalam buffer vertex yang berbeda, hanya dengan bersepeda buffer vertex mana yang aktif dan menyesuaikan BaseVertexIndex sesuai kebutuhan. Perhatikan bahwa nilai BaseVertexIndex juga secara otomatis ditambahkan ke argumen MinIndex, yang masuk akal ketika Anda melihat cara penggunaannya:

Berpura-puralah sekarang bahwa kita lagi ingin menggambar segitiga kedua dari quad menggunakan buffer indeks yang sama seperti sebelumnya; namun, buffer vertex yang berbeda sedang digunakan di mana quad terletak di Indeks VB 50. Urutan relatif simpul quad tetap tidak berubah, hanya lokasi awal dalam buffer vertex yang berbeda. Buffer indeks dan buffer vertex akan terlihat seperti diagram berikut.

diagram buffer indeks dan buffer vertex dengan indeks vb 50

Berikut adalah panggilan gambar yang sesuai; perhatikan bahwa BaseVertexIndex adalah satu-satunya nilai yang telah berubah dari skenario sebelumnya:

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    50,                 // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

Rendering Primitif