Tangkapan layar video game

8

Saya ingin "mengaitkan" ke dalam gim yang sedang berjalan, kata Mario Bros, dan menangkap setiap frame yang diberikan ... menyimpan frame itu ke file gambar. Contoh bagus dari hal serupa adalah FRAPS. --Catatan: Saya tidak ingin menangkap seluruh layar / desktop. Saya ingin menangkap jendela yang ditargetkan.

Saya sudah melihat OBS (Open Broadcasting Software) tetapi tidak terlalu cepat. Jangan salah paham, ini perangkat lunak yang hebat, tapi sayangnya tidak ada / dokumentasi buruk, membuat proyek besar yang ditulis dalam c dan c ++ hampir tidak dapat diakses oleh seorang programmer baru ke c ++.

Saya juga sudah melihat GamingAnywhere , tapi sayangnya, saya tidak bisa menjalankannya, ada sedikit / tidak ada dokumentasi, hanya berjalan di VS2010 dan berantakan (dengan penamaan variabel yang buruk). Namun, ini adalah proyek penelitian sehingga dapat dimengerti tidak berdokumen dan berantakan.

Saya tahu ini dapat dilakukan dengan OpenGL, GDI dan dengan Direct3D, tetapi saya tidak dapat menemukan beberapa contoh yang bagus di internet.

Saya membaca bahwa glReadlPixels (menggunakan OpenGL) dapat digunakan dan saya telah membaca dokumentasinya , tetapi posting tersebut tidak menyebutkan apa-apa tentang menghubungkan ke permainan / aplikasi yang sedang berjalan.

Pertanyaan:

  1. Bisakah saya menghubungkan grafik dengan game yang dikembangkan dengan OpenGL, menggunakan, katakanlah, Direct3D? Apakah perpustakaan yang digunakan untuk mengaitkan harus sama dengan yang digunakan oleh permainan?

  2. Bagaimana cara saya menghubungkan ke dalam frame yang diberikan game sehingga saya bisa menampilkan frame tersebut ke file gambar atau ke file video? (Hanya beberapa tautan atau penjelasan singkat tentang apa yang perlu saya lakukan akan sangat bagus)

  3. BackBuffer - Saya membaca bahwa sangat cepat mengakses BackBuffer untuk mengambil frame. Apakah ada yang punya contoh untuk saya tentang bagaimana melakukan ini dengan perpustakaan terbaru? Saya telah menemukan bahwa sebagian besar contoh sudah ketinggalan zaman.

  4. Untuk tujuan saya, apakah ada yang jelas "ini lebih cepat dari itu"? Maksud saya adalah, apakah, katakanlah, OpenGL, lebih cepat untuk tujuan saya?

Jika seseorang mengetahui tentang proyek open-source (yang pada dasarnya melakukan apa yang saya butuhkan) yang dikembangkan secara aktif dan didokumentasikan dengan baik, saya ingin mengetahuinya.

pookie
sumber
Sekarang ini tampaknya hanya Mac, yang mungkin tidak bekerja untuk Anda dengan Direct3D, tetapi Syphon Suntikan yang menggunakan OBS pada Mac dapat menangkap jendela permainan yang menggunakan OpenGL jauh lebih cepat daripada pengambilan video standar. Syphon "memungkinkan aplikasi untuk berbagi bingkai - video dengan kecepatan bingkai penuh atau gambar diam - satu sama lain secara realtime" untuk mengutip situs web.
Gliderman
@Gliderman Terima kasih, saya akan memeriksanya!
pookie

Jawaban:

7

Dimungkinkan untuk melakukan apa yang Anda gambarkan, tetapi saya khawatir itu bukan proses yang sepele. Sebenarnya, ini akan sangat terkait dengan Sistem Operasi yang Anda targetkan dan mungkin juga membutuhkan penyesuaian khusus untuk game / aplikasi yang diberikan.

Saya akan mulai melihat teknik injeksi DLL , yang seharusnya memungkinkan, misalnya, mencegat panggilan ke Direct3D (Windows) atau OpenGL API, yang kemudian dapat Anda gunakan untuk menyalin de framebuffers aplikasi. Pencarian Internet cepat menemukan ini dan ini dengan penjelasan terperinci.

Saya pernah menulis interseptor OpenGL skala kecil pada MacOS dengan menyuntikkan modul custom shared, tapi itu dalam keadaan yang sangat terkontrol dan membuat banyak asumsi, seperti memiliki hak akses root dalam sistem, jadi untuk alat produksi, itu akan menjadi jauh lebih rumit. Anda dapat menemukan proyek lain yang sangat menarik di sini tentang mencegat D3D API untuk menginstal bot AI otomatis di Starcraft, yang harus menyentuh konsep yang sangat mirip dengan apa yang Anda cari.

Setelah Anda berhasil mencegat API rendering yang mendasarinya, Anda mungkin dapat mengaitkan kode Anda ke setiap SwapBufferspanggilan atau yang setara untuk hanya menyalin framebuffer sebelumnya sebelum swap, lalu menyimpannya (di sinilah sesuatu seperti glReadPixelsakan ikut bermain).

Menyalin dan menyimpan framebuffer secara efisien juga menantang. Cara mudah adalah dengan hanya membuang setiap frame sebagai gambar RGB yang tidak terkompresi, tetapi kemudian Anda akan berakhir dengan ratusan gigabyte data hanya untuk beberapa menit gameplay, jadi kecuali Anda memiliki array HDD yang bagus di sudut meja ;)Anda, Anda harus melihat ke dalam mengompresi frame entah bagaimana.

Kelemahan dari mengompresi frame sekarang adalah bahwa hal itu membutuhkan banyak pemrosesan, jadi pendekatan naif mungkin mengubah aplikasi yang dulu interaktif yang Anda coba rekam menjadi slide-show interaktif :(. Jadi pada tahap ini Anda harus mulai berpikir tentang optimasi.

Tidak tahu ada proyek di luar sana menyediakan perpustakaan untuk menangkap frame efisien untuk game, tapi ini pasti akan menjadi sesuatu yang menyenangkan untuk dimiliki! Saya pikir satu hal yang mungkin menahan proyek seperti itu adalah, seperti yang saya sebutkan di awal, bahwa ini adalah hal yang sangat tergantung pada sistem, sehingga kasus penggunaan kemungkinan besar akan terbatas pada platform atau OS tunggal.

Glampert
sumber
Terima kasih atas jawabannya. Saya pikir pada akhirnya, saya akan bukannya menyimpan gambar, mengalirkannya ke mesin jarak jauh, jadi menyalin frameebuffer mungkin cara yang harus dilakukan. Anda tampaknya memiliki sedikit pengalaman yang adil dengan hal ini. Apakah Anda dapat memperluas pertanyaan yang saya ajukan? Terima kasih untuk bantuannya!
pookie
1
@pookie Hei! Tentu, saya bisa mengembangkan ini. Apakah ada sesuatu yang khusus Anda ingin saya komentari? Untuk pertanyaan Anda, saya pikir 1 & 2 dapat dilakukan dengan kait DLL, jadi pastikan untuk membaca tautan yang saya sertakan (khususnya yang tentang starcraft). 3 & 4 akan spesifik untuk API, tetapi pada OpenGL, Anda bisa mulai dengan glReadPixels dan bekerja dari sana jika Anda merasa terlalu lambat. Pengalaman saya adalah dari merekam frame dari game saya sendiri ditambah beberapa peretasan DLL yang dilakukan di masa lalu, tapi saya tidak pernah menggabungkan keduanya dalam upaya merekam frame dari aplikasi pihak ketiga;)
glampert
Terima kasih! Saya telah memeriksa tautannya - injeksi jendela DLL dan tautan starcraft (cukup mengagumkan) tampaknya menjadi titik awal yang baik. Saya akan melihat deapre ke glReadPixels juga. Menurut Anda, mana yang menurut Anda lebih mudah untuk dikerjakan dan mana yang Anda temukan lebih cepat: DirectX atau OpenGL?
pookie
@pookie, jika Anda memiliki pengalaman pemrograman, saya pikir Direct3D akan jauh lebih mudah digunakan, perpustakaan dirancang lebih baik. OpenGL memiliki terlalu "tepi kasar" menurut saya (ini berasal dari seseorang yang menggunakan OpenGL lebih dari D3D). D3D adalah Windows saja, jadi itu mungkin negatif untuk Anda, tidak tahu. Dari segi kinerja, saya rasa tidak akan ada banyak perbedaan yang Anda gunakan. Saran terbaik yang mungkin bisa saya berikan kepada Anda adalah: cari tahu dulu bagaimana cara membuatnya bekerja, kemudian khawatir tentang optimasi.
Glampert
1
Ah, ok, jika Anda terbiasa dengan pemrograman OOP, maka D3D pasti akan lebih mudah. OpenGL semuanya prosedural dan menggunakan banyak negara global, itulah yang saya maksud dengan kasar. Semoga beruntung untuk Anda!
Glampert