Central Processing Unit (CPU) dan Graphics Processing Unit (GPU) komputer Anda berinteraksi setiap saat Anda menggunakan komputer Anda untuk memberikan antarmuka visual yang tajam dan responsif. Baca terus untuk lebih memahami bagaimana mereka bekerja sama.
foto oleh sskennel.dll .
Sesi Tanya & Jawab hari ini hadir atas kebaikan SuperUser — subdivisi Stack Exchange, pengelompokan situs web Tanya Jawab yang didorong komunitas.
Pertanyaan
Pembaca SuperUser Sathya mengajukan pertanyaan:
Di sini Anda dapat melihat tangkapan layar dari program C ++ kecil bernama Triangle.exe dengan segitiga berputar berdasarkan OpenGL API.
Memang contoh yang sangat mendasar tetapi saya pikir itu berlaku untuk operasi kartu grafis lainnya.
Saya hanya ingin tahu dan ingin mengetahui keseluruhan proses mulai dari mengklik dua kali pada Triangle.exe di bawah Windows XP sampai saya dapat melihat segitiga berputar di monitor. Apa yang terjadi, bagaimana CPU (yang pertama menangani .exe) dan GPU (yang akhirnya menampilkan segitiga di layar) berinteraksi?
Saya kira yang terlibat dalam menampilkan segitiga berputar ini terutama perangkat keras / lunak berikut antara lain:
Perangkat keras
- HDD
- Memori Sistem (RAM)
- CPU
- Memori video
- GPU
- layar LCD
Perangkat lunak
- Sistem operasi
- DirectX / OpenGL API
- Pengemudi Nvidia
Adakah yang bisa menjelaskan prosesnya, mungkin dengan semacam diagram alir untuk ilustrasi?
Ini seharusnya bukan penjelasan yang rumit yang mencakup setiap langkah (tebakan yang akan melampaui cakupan), tetapi penjelasan yang dapat diikuti oleh orang TI perantara.
Saya cukup yakin banyak orang yang bahkan menyebut diri mereka profesional TI tidak dapat menjelaskan proses ini dengan benar.
Jawabannya
Meskipun beberapa anggota komunitas menjawab pertanyaan tersebut, Oliver Salzburg bekerja ekstra dan menjawabnya tidak hanya dengan tanggapan yang terperinci tetapi juga grafik yang menyertai sangat baik.
Gambar oleh JasonC, tersedia sebagai wallpaper di sini .
Dia menulis:
Saya memutuskan untuk menulis sedikit tentang aspek pemrograman dan bagaimana komponen berbicara satu sama lain. Mungkin ini akan menjelaskan beberapa area tertentu.
Presentasi
Apa yang diperlukan untuk membuat gambar tunggal itu, yang Anda posting dalam pertanyaan Anda, digambar di layar?
Ada banyak cara untuk menggambar segitiga di layar. Untuk kesederhanaan, anggap saja tidak ada buffer vertex yang digunakan. (SEBUAH penyangga simpul adalah area memori tempat Anda menyimpan koordinat.) Mari kita asumsikan program hanya memberi tahu pipeline pemrosesan grafis tentang setiap simpul tunggal (simpul hanyalah koordinat dalam ruang) dalam satu baris.
Tapi , sebelum kita bisa menggambar apa pun, pertama-tama kita harus menjalankan beberapa perancah. Kita lihat saja nanti Mengapa kemudian:
// Bersihkan Layar Dan Penyangga Kedalaman glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Setel Ulang Matriks Modelview Saat Ini glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Menggambar Menggunakan Segitiga glBegin (GL_TRIANGLES); // Merah glColor3f (1.0f, 0.0f, 0.0f); // Top Of Triangle (Depan) glVertex3f (0.0f, 1.0f, 0.0f); // Hijau glColor3f (0.0f, 1.0f, 0.0f); // Left Of Triangle (Depan) glVertex3f (-1.0f, -1.0f, 1.0f); // Biru glColor3f (0.0f, 0.0f, 1.0f); // Right Of Triangle (Depan) glVertex3f (1.0f, -1.0f, 1.0f); // Selesai Menggambar glEnd ();
Jadi apa yang dilakukannya?
Saat Anda menulis program yang ingin menggunakan kartu grafis, Anda biasanya akan memilih semacam antarmuka untuk driver. Beberapa antarmuka terkenal untuk pengemudi adalah:
- OpenGL
- Direct3D
- KEAJAIBAN
Untuk contoh ini kami akan tetap menggunakan OpenGL. Sekarang, milikmu antarmuka ke pengemudi itulah yang memberi Anda semua alat yang Anda butuhkan untuk membuat program Anda berbicara ke kartu grafis (atau driver, yang kemudian pembicaraan ke kartu).
Antarmuka ini terikat untuk memberi Anda kepastian alat . Alat ini berbentuk file API yang dapat Anda panggil dari program Anda.
API itu adalah apa yang kami lihat digunakan dalam contoh di atas. Mari kita lihat lebih dekat.
Perancah
Sebelum Anda benar-benar dapat menggambar, Anda harus melakukan mendirikan . Anda harus menentukan area pandang Anda (area yang benar-benar akan dirender), perspektif Anda ( kamera ke dalam dunia Anda), anti-aliasing apa yang akan Anda gunakan (untuk menghaluskan tepi segitiga Anda)…
Tapi kami tidak akan melihat semua itu. Kami hanya akan mengintip hal-hal yang harus Anda lakukan setiap bingkai . Suka:
Membersihkan layar
Pipa grafik tidak akan membersihkan layar untuk Anda setiap bingkai. Anda harus mengatakannya. Mengapa? Ini sebabnya:
Jika Anda tidak membersihkan layar, Anda akan melakukannya
menarik
itu setiap bingkai. Itulah mengapa kami menelepon
glClear
dengan
GL_COLOR_BUFFER_BIT
set. Bit lainnya (
GL_DEPTH_BUFFER_BIT
) memberi tahu OpenGL untuk menghapus file
kedalaman
penyangga. Buffer ini digunakan untuk menentukan piksel mana yang berada di depan (atau di belakang) piksel lain.
Transformasi
Transformasi adalah bagian di mana kita mengambil semua koordinat input (simpul segitiga kita) dan menerapkan matriks ModelView kita. Ini adalah matriks itu menjelaskan bagaimana kami model (simpul) diputar, diskalakan, dan diterjemahkan (dipindahkan).
Selanjutnya, kami menerapkan matriks Proyeksi kami. Ini memindahkan semua koordinat sehingga menghadap kamera kita dengan benar.
Sekarang kita mengubah sekali lagi, dengan matriks Viewport kita. Kami melakukan ini untuk mengukur kami model dengan ukuran monitor kami. Sekarang kita memiliki satu set simpul yang siap untuk dirender!
Kita akan kembali ke transformasi nanti.
Gambar
Untuk menggambar segitiga, kita cukup memberi tahu OpenGL untuk memulai yang baru
daftar segitiga
dengan menyebut
glBegin
dengan
GL_TRIANGLES
konstan.
Ada juga bentuk lain yang bisa Anda gambar. Seperti
strip segitiga
atau a
kipas segitiga
. Ini terutama pengoptimalan, karena memerlukan lebih sedikit komunikasi antara CPU dan GPU untuk menggambar jumlah segitiga yang sama.
Setelah itu, kita dapat memberikan daftar himpunan 3 simpul yang harus membentuk setiap segitiga. Setiap segitiga menggunakan 3 koordinat (karena kita berada dalam ruang 3D). Selain itu, saya juga menyediakan file
warna
untuk setiap simpul, dengan memanggil
glColor3f
sebelum
panggilan
glVertex3f
.
Bayangan antara 3 simpul (3 sudut segitiga) dihitung dengan OpenGL secara otomatis . Ini akan menginterpolasi warna di seluruh permukaan poligon.
Interaksi
Sekarang, saat Anda mengklik jendela. Aplikasi hanya perlu menangkap file pesan jendela yang menandakan klik. Kemudian Anda dapat menjalankan tindakan apa pun dalam program yang Anda inginkan.
Ini mendapat a banyak lebih sulit setelah Anda ingin mulai berinteraksi dengan pemandangan 3D Anda.
Pertama-tama Anda harus mengetahui dengan jelas piksel mana yang diklik pengguna pada jendela. Kemudian, ambil file perspektif ke dalam akun, Anda dapat menghitung arah sinar, dari titik klik mouse ke adegan Anda. Anda kemudian dapat menghitung jika ada objek dalam pemandangan Anda berpotongan dengan sinar itu . Sekarang Anda tahu jika pengguna mengklik suatu objek.
Jadi, bagaimana cara membuatnya berputar?
Transformasi
Saya mengetahui dua jenis transformasi yang umumnya diterapkan:
- Transformasi berbasis matriks
- Transformasi berbasis tulang
Perbedaannya adalah itu tulang mempengaruhi lajang sudut . Matriks selalu memengaruhi semua simpul yang digambar dengan cara yang sama. Mari kita lihat contohnya.
Contoh
Sebelumnya, kami memuat file matriks identitas sebelum menggambar segitiga kita. Matriks identitas adalah matriks yang menyediakan tidak ada transformasi sama sekali. Jadi, apapun yang saya gambar, hanya dipengaruhi oleh perspektif saya. Jadi, segitiga tidak akan diputar sama sekali.
Jika saya ingin memutarnya sekarang, saya bisa melakukan matematika sendiri (pada CPU) dan cukup memanggil
glVertex3f
dengan
lain
koordinat (yang diputar). Atau saya bisa membiarkan GPU melakukan semua pekerjaan, dengan menelepon
glRotatef
sebelum menggambar:
// Putar Segitiga Pada Sumbu Y glRotatef (jumlah, 0.0f, 1.0f, 0.0f);
jumlah
adalah, tentu saja, hanyalah nilai tetap. Jika Anda menghendaki
animasi
, Anda harus terus memantau
jumlah
dan tingkatkan setiap frame.
Jadi, tunggu, apa yang terjadi dengan semua pembicaraan matriks tadi?
Dalam contoh sederhana ini, kita tidak perlu peduli dengan matriks. Kami hanya menelepon
glRotatef
dan itu mengurus semua itu untuk kita.
glRotatemenghasilkan rotasisudutderajat di sekitar vektor x y z. Matriks saat ini (lihat glMatrixMode ) dikalikan dengan matriks rotasi dengan produk yang menggantikan matriks saat ini, seolah-olah glMultMatrix dipanggil dengan matriks berikut sebagai argumennya:x 2 1 - c + cx y 1 - c - z sx z 1 - c + y s 0 y x 1 - c + z sy 2 1 - c + cy z 1 - c - x s 0 x z 1 - c - y sy z 1 - c + x sz 2 1 - c + c 0 0 0 0 1
Terima kasih untuk itu!
Kesimpulan
Yang menjadi jelas adalah, banyak pembicaraan untuk OpenGL. Tapi itu tidak memberi tahu kami apa pun. Dimana komunikasinya?
Satu-satunya hal yang dikatakan OpenGL kepada kita dalam contoh ini adalah setelah selesai . Setiap operasi akan memakan waktu tertentu. Beberapa operasi membutuhkan waktu yang sangat lama, yang lainnya sangat cepat.
Mengirim simpul GPU akan sangat cepat, saya bahkan tidak tahu bagaimana cara mengekspresikannya. Mengirim ribuan simpul dari CPU ke GPU, setiap frame, kemungkinan besar, tidak ada masalah sama sekali.
Membersihkan layar dapat memakan waktu satu milidetik atau lebih buruk (perlu diingat, Anda biasanya hanya memiliki waktu sekitar 16 milidetik untuk menggambar setiap bingkai), bergantung pada seberapa besar area pandang Anda. Untuk menghapusnya, OpenGL harus menggambar setiap piksel dengan warna yang ingin Anda hapus, itu bisa jutaan piksel.
Selain itu, kami hanya dapat menanyakan OpenGL tentang kapabilitas adaptor grafis kami (resolusi maks, anti-aliasing maks, kedalaman warna maksimal,…).
Tapi kita juga bisa mengisi tekstur dengan piksel yang masing-masing memiliki warna tertentu. Setiap piksel memiliki nilai dan teksturnya adalah “file” raksasa yang berisi data. Kita dapat memuatnya ke kartu grafis (dengan membuat buffer tekstur), lalu memuat file shader , beri tahu shader itu untuk menggunakan tekstur kami sebagai masukan dan menjalankan beberapa kalkulasi yang sangat berat pada "file" kami.
Kemudian kita dapat “merender” hasil komputasi kita (dalam bentuk warna baru) menjadi tekstur baru.
Begitulah cara Anda membuat GPU berfungsi untuk Anda dengan cara lain. Saya berasumsi CUDA memiliki kinerja yang mirip dengan aspek itu, tetapi saya tidak pernah memiliki kesempatan untuk mengerjakannya.
Kami benar-benar hanya menyentuh sedikit keseluruhan subjek. Pemrograman grafis 3D adalah binatang buas.
Punya sesuatu untuk ditambahkan ke penjelasannya? Suarakan di komentar. Ingin membaca lebih banyak jawaban dari pengguna Stack Exchange yang paham teknologi? Lihat utas diskusi lengkap di sini .