API grafik tingkat rendah lintas platform

11

Saat membuat abstraksi sistem lebih baik memiliki platform API yang berbeda disembunyikan oleh antarmuka umum di tingkat terendah yang masuk akal.

Memperhatikan API grafik asli modern (tanpa pipeline fungsi tetap) yang berbeda: OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM

Jika seseorang membuat API grafik tingkat rendah tanpa kewarganegaraan untuk duduk di atas semuanya, apa cara terbaik untuk membuatnya setipis dan secepat mungkin?

NocturnDragon
sumber
Persyaratan untuk API menjadi kewarganegaraan menarik. OpenGL, misalnya, adalah stateful, dan saya pikir API tanpa kewarganegaraan yang membungkusnya hanya akan masuk akal jika levelnya jauh lebih tinggi, sehingga tidak, misalnya, harus mendorong dan mengeluarkan matriks yang sama untuk setiap permukaan itu ditampilkan.
SpoonMeiser
Menghindari perubahan status yang tidak berguna masih dapat diterapkan pada tingkat yang lebih tinggi, seperti dengan menyortir panggilan render berdasarkan statusnya sebelum mengirimkannya ke perangkat. Dan dengan mengatur negara hanya jika berbeda dari yang sekarang.
NocturnDragon
Itu bukan stateless sekalipun. Mungkin saya salah, tetapi apa yang saya pikirkan ketika saya memikirkan stateless, adalah API di mana setiap panggilan tidak bergantung pada panggilan sebelumnya sama sekali. Itu berarti bahwa setiap informasi yang biasanya disimpan dalam keadaan di suatu tempat harus diteruskan dalam setiap panggilan yang memerlukan informasi itu. Untuk OpenGL, misalnya, ini akan menjadi matrik pada opsi stack, lighting, z-buffering dan normalisasi.
SpoonMeiser
Ya, untuk setiap panggilan undian yang Anda perlukan, data mesh, blending state, tekstur untuk mengikat, status pengambilan sampel dll. Optimalisasi dapat dilakukan nanti, tanpa mengubah API ke sana. Atau mungkin saya salah membaca komentar Anda ..
NocturnDragon

Jawaban:

6

Tingkat terendah yang masuk akal dari sudut pandang saya adalah sesuatu yang berbicara tentang sumber daya yang terlibat dalam rendering - vb / ib, membuat permukaan, tekstur, shader, blok negara, dll.

Masalahnya di sini adalah bahwa beberapa dari ini harus dalam format yang berbeda, tergantung pada API - di situlah agak rumit. Cara termudah untuk mengatasinya adalah dengan pra-proses sumber daya statis untuk masing-masing API. Untuk yang dinamis, gunakan hanya shader untuk menghasilkannya - yang membuatnya cukup mudah untuk tetap dalam format asli.

Yang Anda lakukan di level yang lebih tinggi adalah mengatur jalur pipa dengan sumber daya terlampir dan menyerahkannya ke GPU. Anda akan menemukan bahwa tidak semuanya dapat disarikan dengan baik dengan cara itu, terutama jika Anda memanfaatkan trik khusus perangkat keras. Tapi ini awal yang baik.

(Sidenote: jika Anda memperlakukan trik platform khusus sebagai jenis sumber daya khusus, Anda dapat mendorong keseluruhan konsep ini cukup jauh.)

Jadi, Anda akan menciptakan dua hal: Manajer sumber daya perangkat keras, ditambah toolkit untuk menyiapkan DAG sumber daya ini.

Rachel Blum
sumber
Saya tidak pernah berpikir tentang memperlakukan hal-hal spesifik platform sebagai sumber daya. Kedengarannya ide yang sangat bagus! Terima kasih.
NocturnDragon
10

Dengan cakupan luas API yang ingin Anda bahas, pendekatan pembungkus yang tipikal cenderung tidak efisien dan rentan terhadap kesulitan dalam memetakan konsep-konsep API di beberapa API lain yang mungkin atau mungkin tidak mendukung fungsi-fungsi tertentu hingga tingkat yang berbeda-beda.

Akibatnya, pendekatan yang paling masuk akal adalah membuat API fitur-sentris . Meskipun pendekatan ini mencegah pengguna API dari menggunakan semua fungsionalitas yang tersedia, pendekatan ini sangat menyederhanakan implementasi setiap backend, dan memungkinkan optimasi spesifik backend yang tidak mungkin dilakukan.

Ini juga sangat menyederhanakan pengelolaan fungsionalitas yang tidak didukung untuk pengguna API; mereka tidak lagi harus memeriksa apakah fungsi X ada, dan menentukan fitur mana yang terpengaruh, tetapi sebaliknya hanya perlu menanyakan fitur itu sendiri untuk melihat apakah didukung dengan konfigurasi saat ini. Bahkan jika Anda mendukung mode sebagian atau terbatas untuk fitur, konteks yang disediakan membuatnya lebih mudah untuk dikelola.

Dalam hal membuat renderer tanpa kewarganegaraan (juga dikenal sebagai submission ), biasanya kunci 64bit digunakan untuk mengemas dan mengirimkan perintah untuk rendering. Dari titik itu ada banyak fleksibilitas dalam hal bagaimana menjalankan perintah dan informasi apa yang harus disampaikan tergantung pada fitur dan kemampuan apa yang ingin Anda dukung.

Jason Kozak
sumber
Ini sebenarnya Ide yang bagus. Dan itu adalah bagian dari desain yang saya coba buat, tetapi yang ada dalam pikiran saya adalah untuk mengimplementasikan fitur ini di atas API tingkat rendah yang umum. Tetapi mungkin bahwa untuk beberapa fitur Anda masih perlu jauh ke dalam API asli untuk beberapa kasus yang lebih khusus.
NocturnDragon
Bagian dari idenya adalah untuk menghindari pembangunan API tingkat rendah yang umum, dan harus berurusan dengan pembungkus dengan pendekatan penyebut yang paling umum. Dengan menggerakkan tingkat abstraksi ke atas, Anda memang membatasi set fitur, tetapi Anda juga mendapatkan kemampuan untuk mengeksploitasi setiap platform. Untuk menangani kebutuhan sesekali untuk akses yang lebih dalam, saya lebih suka memberikan header yang memperlihatkan header platform dan beberapa pembantu internal; mungkin memecah versi ke versi, tetapi ada di sana jika Anda membutuhkannya.
Jason Kozak
1

Untuk mulai dengan, setiap API melakukan hal-hal yang berbeda sehingga harus pergi tanpa mengatakan bahwa membungkus semua API di atas akan sulit. Yang mengatakan, kadang-kadang perlu untuk melakukannya: pada titik tertentu permainan hanya perlu dijalankan pada lebih dari satu platform terlepas dari seberapa sulit untuk melakukannya.

Saya pikir cara terbaik untuk melakukan ini adalah menemukan fungsionalitas yang dapat diimplementasikan pada semua API yang mendasarinya dan abstrak itu dan hanya itu. Jika Anda mengembangkan game multi platform, Anda tidak akan menerapkan setiap fungsi yang tidak jelas yang didukung oleh setiap API, Anda hanya akan mengimplementasikan apa yang Anda butuhkan. Ini juga membantu menjaga API tetap kecil dan cepat.

Untuk menghindari kekacauan dari setiap implementasi API yang berbeda yang dimasukkan ke dalam output, kompilasi harus dilakukan dengan file header netral platform dan file kode platform spesifik. Kemudian, file kode khusus untuk platform target akan menjadi satu-satunya yang dikompilasi menjaga API kecil.

Sean James
sumber
-4

Anda mungkin ingin memeriksa perpustakaan SDL atau Allegro . Keduanya adalah pustaka permainan tingkat rendah, sangat portabel, yang memiliki cara untuk menghubungkannya dalam konteks OpenGL sehingga Anda dapat membuat grafik Anda di sana. SDL terkenal karena ia menonaktifkan Loki Games untuk memindahkan beberapa game populer dari tahun 2000 ke Linux, dan Allegro memiliki banyak waktu untuk berjalan dan memiliki komunitas pengembang game amatir yang hebat.

chiguire
sumber
4
Ini tidak benar-benar menjawab pertanyaan, belum lagi bahwa sangat mungkin untuk membungkus OpenGL dan DirectX (lihat Ogre3D, Irrlicht, dll.).
Jason Kozak
Pertimbangkan gim yang telah Anda mainkan. Berapa banyak dari mereka yang memiliki opsi untuk menggunakan DirectX atau OpenGL? Itulah berapa banyak yang membuat pembungkus untuk kedua perpustakaan untuk dapat mendukung keduanya. Anda memiliki imajinasi yang terbatas. :-P
Ricket
Saya mengakui bahwa ada beberapa permainan yang memungkinkan Anda memilih apakah Anda ingin membuat gambar dengan OpenGL atau DirectX, tetapi pertanyaannya adalah tentang lintas-platform API, jadi saya pikir jawabannya memadai, saya akan mengedit paragraf pertama, meskipun.
chiguire
1
pertanyaannya adalah tentang API tingkat rendah tanpa platform lintas platform. SDL dan Allegro tidak ada hubungannya dengan itu.
NocturnDragon
@NocturnDragon - judul pertanyaan agak menyesatkan. Pada pandangan pertama saya mengharapkan pertanyaan tentang pilihan API yang tersedia, dan saya menganggap penjawab ini juga melakukannya.
a_m0d