Siapa pun yang pernah berpikir tentang cara kerja bagian grafis dari akselerator retro 2D, secara kasar mewakili cara menggambar Ubin terkenal ini, yang menurut definisi tidak harus berbentuk persegi panjang. Ubin adalah tentang ubin. Ya, paling sering pengembang api besi memahami ini dan metodenya disebut drawRect dan bukan drawTile. Persegi panjang apa pun memang bisa menjadi ubin, tetapi kebalikannya tidak benar! Dan kemudian pertanyaannya muncul: Mengapa akselerator 2D terus-menerus berakselerasi hanya dalam bentuk persegi ... Jawaban sederhana untuk pertanyaan ini adalah karena segala sesuatu yang lain terlalu rumit untuk perangkat keras sederhana. Tapi di sini saya akan berdebat. Setidaknya satu ekstensi sederhana namun sangat fungsional dari abstraksi dasar ini dapat diusulkan, berikut ini.
Saya sudah lama tidak menulis surat kepada Habr. Karena sepanjang waktu saya ingin melakukannya dengan sempurna ... Saya menderita penyakit seperti itu. Habr sendiri, sementara itu, telah secara signifikan menurunkan standar, dan saya masih tidak menulis dan tidak menulis. Karenanya, artikel hari ini lahir tanpa persiapan dari sekedar perbincangan dengan seorang teman. Namun, ada teman yang ingin Anda ajak bicara secara mendalam dan menyeluruh.
Biarlah, mungkin, kembalinya saya ke keteraturan. Kalau plus atau minusnya gampang dibaca, dengan tergesa-gesa dilukis, tapi minimal cukup untuk klarifikasi, narasinya tidak dibebani dengan detail, tapi tetap dengan aksen konseptual, dan seperti lampu, seperti dulu, akan sampai ke pembaca mahal.
Dengan kata lain, hari ini saya mencari kompromi antara kualitas konten dan waktu yang dapat saya curahkan untuk itu. Harapan untuk pengertian.
Jadi, mari kita mulaiβ¦
Pertimbangkan untuk sampel fungsi umum menyalin area persegi panjang yang berubah-ubah. Kita melihat bahwa ini hanyalah loop ganda di atas garis dan di atas elemen garis:
Perhatikan bahwa blok kode ini biasanya diulangi secara sepele dalam kombinasi x4 arah traversal dari kedua loop untuk menerapkan Refleksi:
Kombinasi x2 lainnya diberikan oleh permutasi urutan oleh dst [x] [y] yang mencerminkan sepanjang sumbu y = x.
Sepanjang jalan, 8 opsi untuk pantulan ini adalah semua kemungkinan rotasi dalam kelipatan 90gr dengan semua pantulan cerminnya dari kiri ke kanan.
Dan sekarang mari kita lihat bagaimana bahkan dengan sedikit tambahan elemen dasar ini dapat sangat dimodifikasi.
Mungkin itu tidak pernah terpikir oleh siapa pun, tetapi mengapa ubin tidak bisa, misalnya, paralelepiped? Ke depan, saya akan mengatakan bahwa ekstensi ini membawa overhead minimal, karena untuk menerapkan ini, Anda hanya perlu menambahkan beberapa kenaikan per baris:
Sebagai hasil dari kombinasi dengan permutasi x / y, kita mendapatkan parallelepiped dengan sepasang sisi yang selalu berorientasi sepanjang satu ortogonal, dan dua lainnya akan berada pada sudut ... Apa yang diberikan hal sepele yang diterima dengan murah ini kepada kita? Pertama, kemampuan untuk menggunakan tiga proyeksi tetap:
Jika kenaikan dibuat bukan konstanta, tetapi bilangan pecahan, sudut pergeseran bisa menjadi bebas. Yang dapat digunakan dengan sempurna baik untuk efek ubin yang bergoyang di penggulung samping:
Dan untuk membangun dinding dalam ruang proyeksi isometrik:
Dan ingat bahwa berbicara pecahan tidak selalu berarti dukungan mengambang! Betapa seorang programmer manja modern kadang-kadang mulai melupakannya. float adalah pecahan dengan floating point, tapi di sini itu sama sekali tidak perlu. Faktanya, setiap prosesor dengan register ganda, di mana bagian atas pasangan dapat dibaca sebagai nilai terpisah, memiliki "dukungan" untuk titik tetap pecahan (titik tetap). Selain itu, dalam kasus ini, TIDAK ada satu pun instruksi tambahan yang akan ditambahkan. (Nah, kecuali bahwa kemiringannya akan diatur dalam ketukan 256) Jadi semuanya gratis, ambil guys!
Langkah serupa lainnya yang harus diminta oleh pembaca yang penuh perhatian secara induktif adalah pengulangan fungsi ini ke batas kedua dari pencacahan loop dalam. Bagaimanapun, kita dapat memisahkan kenaikan akhir secara terpisah. Dan kemudian, dalam kasus umum, kita akan dapat menggambar trapesium yang terletak dengan alas pada salah satu ortogonal (sebagai kasus khusus segitiga):
Dan apa yang mereka serahkan kepada kita? Anda akan berpikir, tetapi Anda akan segera menebak bahwa hanya dalam dua panggilan gambar seperti itu, Anda hanya memberi tekstur pada bidang dari segi enam berorientasi ortogonal atau belah ketupat yang berorientasi diagonal dari kumpulan ubin yang disiapkan untuk ini. Ngomong-ngomong, kasus ubin, yang cukup umum di industri game.
Pada hari-hari J2ME
J2ME , . , ,
Akan sangat bagus untuk memiliki dukungan perangkat keras untuk mereka pada akselerator:
Selebihnya yang dijelaskan lebih merupakan fungsionalitas bonus, sejak itu Anda dapat menerapkannya dengan lebih baik dengan sengaja. Namun, jika kita berbicara, antara lain, hanya tentang mengisi primitif hanya dengan warna (atau pola datar), untuk beberapa tambahan sederhana ke ruang permainan yang ada ...
Pasangan draw call yang sama dapat membentuk segitiga apa pun yang tidak terbatas pada detailnya (itu hanya dipotong menjadi dua oleh garis ortogonal di tengah Intinya, ini sangat mirip dengan algoritme gambar klasiknya) Dan dari sini sudah mungkin untuk membangun konstruksi dalam perspektif. Omong-omong, dari trapesium itu sendiri, misalnya, proyeksi 3D DOOM1 yang dipasang secara vertikal dari bentuk diperoleh secara elementer dengan murah:
Jika mau, Anda bisa mencoba melukis dengan isian, bahkan sesuatu yang lebih atau kurang besar-voxel. Bergantung pada derajat kebebasan proyeksi, menghabiskan lebih banyak atau lebih sedikit panggilan imbang. Dua proyeksi perspektif pertama di bawah ini ditetapkan tetapi masing-masing memiliki 4 tampilan simetris - dengan total 8 sudut tampilan. Yang ketiga adalah kasus umum dan hanya diperbaiki secara vertikal. Berputar di sekitar sumbu vertikal, ini akan bergantian antara yang pertama dan yang kedua:
Lebih baik membagi gambar menjadi trapezium, jika mungkin, menjadi potongan-potongan yang lebih memanjang di sepanjang ortogonal potongan, karena fungsionalitas panggilan tambahan, meskipun tidak mahal, dikaitkan dengan iterasi hanya siklus luar, yang diinginkan agar jumlahnya lebih sedikit. Faktanya, ini benar bahkan untuk menggambar algoritma persegi panjang dasar - menggambar horizontal lebih efisien daripada menggambar vertikal.
Dimungkinkan untuk melakukan tekstur perspektif pada fungsionalitas bonus dalam panggilan ini, tetapi itu membutuhkan implementasi penskalaan pecahan dan dikaitkan dengan pengenalan koefisien divergensi tambahan untuk src, dan koefisien desimasi, yang, terlebih lagi, perlu dihitung dalam dinamika dalam 3D agak miring, yang tidak disarankan untuk ini arsitektur sederhana.
Nah, mengakhiri balas dendam sebelum Habr untuk kepentingan saya sendiri, saya masih tidak bisa tidak menjelaskan secara singkat dari mana semua keajaiban koefisien kenaikan ini berasal secara aljabar. Rumus garis lurus y = kx + b yang diajarkan di sekolah mengirim halo ke sini dua kali sekaligus. Semua koefisien berguna di tempatnya:
Mengapa saya belum menemukan akselerator perangkat keras 2D dengan implementasi ubin seperti itu, saya hanya bisa menebak:
- Konsep Tile adalah pola yang tetap kaku dalam praktiknya sehingga tidak ada yang mengira mereka bisa melakukan lebih banyak ... mendapatkan lebih banyak.
- Entah tidak ada yang mau menghabiskan bahkan beberapa siklus pada fungsi seperti itu, karena mereka tidak menganalisis konsekuensi yang tersebar luas yang dinyatakan, atau pengembang waktu itu dengan game sederhana tidak membuat permintaan untuk mereka. Namun demikian, ada mode7 (algoritma cheat untuk mengimplementasikan tekstur perspektif, melalui keluaran potongan sprite persegi panjang pada perangkat keras dengan dukungan untuk penskalaan pecahan)
- Atau saya belum cukup dewasa, dan saya harus melanjutkan ...