Ketika saya membaca dokumen di webGL atau OpenGL dapat dilihat beberapa pola bagaimana nama fungsi dan objek digunakan. Tapi saya tidak bisa mengerti perbedaan antara objek buffer dan array.
Ada "objek buffer vertex", "objek array vertex" dan bahkan semacam "buffer array" atau "arraybuffer".
Dalam konteks OpenGL, Kapan sesuatu "array" dan kapan seharusnya disebut "buffer"?
char* buffer = socketRead();
(pseudocode). Log di sisi lain, hidup melalui seluruh siklus hidup aplikasi. Jadi Anda membuat array di suatu tempat dan mulai membaca socket, kapan pun Anda mendapatkan data yang Anda tuliskan potongan itu ke array, memberi Anda daftar rapi semua data yang Anda terima.Jawaban:
Penamaan Objek Array Vertex agak disayangkan. Ada tiga hal berbeda yang muncul (dulu muncul) di / dengan / sekitar aplikasi Anda, dan yang (secara historis) dinamai berbeda, dengan "array" atau "buffer" pada namanya (well, ada juga objek framebuffer, tapi saya akan mengabaikan itu).
Maksud dari ini adalah untuk membuat pengaksesan menjadi lebih efisien karena OpenGL hanya dapat menyalin semuanya sekaligus dalam waktu yang ditentukan ketika Anda memberikan janji bahwa data konsisten, dan mendorongnya ke atas AGP atau apa pun dalam satu blok. Ini tidak ada lagi.
OpenGL dapat memindahkan data ini lebih kurang atau lebih bebas, dan Anda hanya diizinkan / dapat menyalin ke / dari buffer melalui API yang sesuai atau mengakses data saat sedang dipetakan. Itulah yang Anda sebut objek penyangga ( objek penyangga verteks jika berisi simpul, tetapi sebenarnya tidak harus, bisa juga data gambar atau seragam, hanya simpul yang pertama kali didukung, satu kali).
Maksudnya adalah untuk menjamin bahwa OpenGL dapat (pada prinsipnya) melakukan apa yang diinginkannya, bahkan dapat mendorong buffer lebih dari PCIe secara spekulatif bahkan sebelum Anda menggambar. Itu berfungsi karena Anda tidak memiliki data (OpenGL memilikinya!) Dan Anda hanya dapat mengaksesnya melalui API yang diberikan, sehingga diketahui setiap saat bahwa data itu valid. Pengemudi bahkan dapat memilih untuk membuang memori buffer pada kartu grafis ketika itu membutuhkan memori untuk sesuatu yang berbeda dan kemudian mengembalikannya dari salinan rahasia ketika diperlukan.
Sekarang, maksud dari objek array vertex adalah untuk mengurangi jumlah panggilan API dan untuk mengurangi jumlah pemeriksaan konsistensi yang harus dilakukan OpenGL secara internal, dan tentu saja, untuk menggunakan perangkat keras saat bekerja. Jika Anda mengikat 5 buffer, maka masing-masing harus melalui beberapa pemeriksaan yang mungkin mahal, dan masing-masing adalah kandidat untuk cache yang hilang dalam driver, ditambah setiap satu membutuhkan komunikasi dengan kartu grafis untuk mengubah deskriptor, dll. Jika Anda sebaliknya mengikat satu VAO, pengemudi dapat (sering) cukup mengganti deskriptor yang ditetapkan pada kartu grafis, dan dilakukan.
sumber
(ditarik dari khronos )
Setiap buffer cenderung membentuk satu atribut array verteks (objek). VAO dapat berisi banyak atribut simpul (misalnya posisi, warna, UV). Masing-masing mungkin disimpan dalam buffernya sendiri, di mana buffer menunjukkan serangkaian byte yang berdekatan yang tidak diformat, dan di mana Anda perlu secara eksplisit menentukan ukuran (jenis) per elemen buffer untuk panggilan OpenGL sisi CPU dan kerja shader sisi GPU.
Itu satu arah. Cara lain ini bisa bekerja adalah:
Diagram di bawah ini menggambarkan dua kasus terakhir ini.
Intinya: Jika frasa "array vertex" digunakan tidak memenuhi syarat dalam OpenGL, Anda dapat menganggap itu berarti VAO, yang, dalam konteks OpenGL (khusus) memang sangat berbeda dari buffer.
Sunting komentar Anda:
GL_ARRAY_BUFFER
menunjukkan niat untuk menggunakan objek buffer itu untuk data atribut vertex, seperti dijelaskan di atas. Ini karena buffer tidak hanya digunakan untuk atribut vertex. Namun, karena ini adalah kasus penggunaan yang paling umum dan Anda bertanya tentang VAO, saya tidak akan membahas yang lain; Namun di sini adalah daftar tipe buffer lain yang dapat diatur.sumber
struct
tipe. Data dapat disisipkan atau sepenuhnya seragam, per buffer. Anda dapat mengindeks ke dalamnya, sama seperti dengan array C tradisional pada CPU. Array objek (gunakan terminologi yang benar ini atau berakhir membingungkan Anda sendiri!) ... (lanjutan di bawah)Terminologi ini berakar pada sejarah OpenGL. Yang penting untuk diingat adalah bahwa, untuk sebagian besar versi GL yang relevan di sini, OpenGL berevolusi secara bertahap dan dengan menambahkan fungsionalitas baru ke API yang sudah ada daripada mengubah API.
Versi pertama OpenGL tidak memiliki tipe objek ini. Menggambar dicapai dengan mengeluarkan beberapa panggilan glBegin / glEnd, dan satu masalah dengan model ini adalah bahwa itu sangat tidak efisien, dalam hal fungsi panggilan overhead.
OpenGL 1.1 mengambil langkah pertama untuk mengatasinya dengan memperkenalkan array vertex. Alih-alih secara langsung menentukan data titik Anda sekarang dapat sumbernya dari array C / C ++ - karenanya namanya. Jadi array vertex hanya itu - array verteks dan status GL yang diperlukan untuk menentukannya.
Evolusi besar berikutnya datang dengan GL 1.5 dan memungkinkan menyimpan data array vertex dalam memori GPU daripada dalam memori sistem ("sisi klien"). Kelemahan dari spesifikasi vertex array GL 1.1 adalah set lengkap data vertex harus ditransfer ke GPU setiap kali Anda ingin menggunakannya; jika sudah ada pada GPU maka transfer ini dapat dihindari dan potensi peningkatan kinerja tercapai.
Jadi tipe objek GL baru dibuat untuk memungkinkan penyimpanan data ini pada GPU. Sama seperti objek tekstur digunakan untuk menyimpan data tekstur, objek buffer verteks menyimpan data verteks. Ini sebenarnya hanya kasus khusus dari tipe objek buffer yang lebih umum yang dapat menyimpan data non-spesifik.
API untuk menggunakan objek vertex buffer didukung oleh API array vertex yang sudah ada, itulah sebabnya Anda melihat hal-hal aneh seperti mengonversi byte offset ke pointer di dalamnya. Jadi sekarang kita memiliki API array vertex yang baru saja menyimpan status, dengan data yang bersumber dari objek buffer daripada dari dalam array memori.
Ini membawa kita hampir ke akhir cerita kita. API yang dihasilkan cukup bertele-tele ketika menentukan keadaan array vertex, jadi jalan lain optimasi adalah membuat tipe objek baru yang mengumpulkan semua state ini bersama-sama, memungkinkan beberapa perubahan status array vertex dalam satu panggilan API, dan memungkinkan GPU untuk berpotensi melakukan optimasi karena dapat mengetahui keadaan apa yang akan digunakan sebelumnya.
Masukkan objek array vertex, yang mengumpulkan semua ini bersama-sama.
Jadi, untuk meringkas, array vertex mulai hidup sebagai kumpulan status dan data (disimpan dalam array) untuk menggambar. Sebuah penyangga vertex menggantikan di memori penyimpanan array dengan tipe GL objek, meninggalkan berbagai titik hanya menjadi negara. Sebuah benda titik array yang hanya objek wadah untuk negara ini, yang memungkinkan untuk diubah lebih mudah dan dengan sedikit panggilan API.
sumber
Saya belum pernah bekerja dengan OpenGL dalam beberapa saat, jadi saya mungkin hanya setengah benar. Secara umum: Buffer menyimpan array memori yang belum diformat. Array adalah istilah umum dari memori yang berdekatan.
Buffer harus diikat ke konteks, sedangkan array hanyalah sebuah array data. Jika saya ingat dengan benar, data dalam buffer dimaksudkan untuk disalin ke kartu grafis (karenanya mengikat).
Semoga ini bisa membantu sedikit
sumber