FB2D - Kerangka 2D untuk Linux Frame Buffer (Rust)

Jadi saya memutuskan untuk menceritakan tentang perpustakaan yang saya tulis baru-baru ini. Mungkin seseorang akan berguna.
Ini adalah kerangka kerja Rust 2D untuk rendering langsung di Linux Frame Buffer / dev / fb0.


Tugasnya adalah untuk menampilkan adegan 2D sederhana di layar / TV di Raspberry Pi. Raspberry Pi berjalan di bawah kendali Linux yang dikompilasi dengan YoctoProject custom headless. Manajer Jendela tidak ada, begitu pula OpenGL. Hanya Frame Buffer yang tersisa.


Dalam kasus Frame Buffer, setiap piksel harus diproses. Karena saya terutama menulis untuk GoLang untuk Raspberry Pi, saya memutuskan untuk menulis perpustakaan di Go. Saya segera menyadari bahwa Go tidak cocok untuk kinerja saya. Dia tidak bisa melakukan operasi besar-besaran dengan memori dalam waktu yang wajar.


Lalu saya perhatikan Rust, yang melakukan tes serupa jauh lebih cepat.


Jadi, perpustakaan dikembangkan di Rust. Karena ini adalah proyek pertama saya di Rust, jangan banyak-banyak, tetapi komentar dipersilahkan.


Seperti di perpustakaan 2D mana pun, ada tiga entitas utama: adegan, simpul, dan sprite.
Adegan adalah wadah untuk objek visual. Node adalah objek virtual yang diberkahi dengan properti tertentu, seperti lokasi, ukuran, dll. Node dapat disarangkan.
Setiap node berisi objek visual, yang disebut sprite. Sprite datang dalam beberapa bentuk. Sprite seperti RectSprite, TextureSprite, TextSprite sekarang didukung.


RectSprite - persegi panjang dengan warna tertentu. RectSprite tanpa warna biasanya digunakan untuk mengelompokkan node anak lainnya. RectSprite cocok dengan tag XML < box >


TextureSprite - objek untuk merender gambar. Hanya PNG (RGBA) yang saat ini didukung. TextureSprite cocok dengan tag XML < image >


TechSprite - objek untuk merender satu baris teks dalam font dan ukuran yang dipilih. Ada dukungan otomatis untuk RTL. TechSprite terkait dengan tag < text > XML


Selain atribut lokasi dan ukuran, setiap node memiliki atribut gravitasi dan jangkar. Ini membantu untuk secara akurat memposisikan objek di dalam objek lain. Semua atribut yang terkait dengan ukuran dan lokasi ditetapkan sebagai persentase dari simpul induk. Pendekatan ini memungkinkan Anda mencapai penskalaan terbaik pada layar dengan ukuran dan proporsi berbeda.


Dimungkinkan untuk membuat adegan, baik secara terprogram, atau membuat file xml yang menggambarkan adegan tersebut.


  1. Cara perangkat lunak untuk membuat dan menjalankan suatu adegan.


    let mut fb = fb2d::screen_writer_for_framebuffer("/dev/fb0")?; fb2d::set_graphics_mode(); let mut scene = fb2d::scene::Scene::new(); let background_sprite = RectSprite::new(); let background_node = Node::new_rect_node(FLOAT_RECT_FULL, background_sprite); let sprite1 = RectSprite::new(); let mut node1 = Node::new_rect_node( FloatRect { pos: FLOAT_POS_ZERO, size: FLOAT_SIZE_HALF, }, sprite1, ); node1.anchor_point = ANCHOR_POINT_TOP_LEFT; let sprite2 = TextureSprite::new_for_texture("image.png"); let mut node2 = Node::new_texture_node( FloatRect { pos: FLOAT_POS_ZERO, size: FloatSize { width: 0.7, height: 0.7, }, }, sprite2, ); node2.anchor_point = ANCHOR_POINT_CENTER; let mut sprite3 = TextSprite::new(); sprite3.text = String::from("Hello, World !!!"); sprite3.gravity = GRAVITY_CENTER; sprite3.height = 0.2; let node3 = Node::new_text_node( FloatRect { pos: FLOAT_POS_ZERO, size: FLOAT_SIZE_FULL, }, sprite3, ); scene.add_node(node2, node1.key); scene.add_node(node1, background_node.key); scene.add_node(node3, background_node.key); scene.set_root_node(background_node); scene.writer = Some(Box::new(fb)); scene.run(); 

  2. Membuat adegan menggunakan file XML.

 <scene color="#ffa500"> <box pos="0" size="95% 95%" anchor-point="0.5 0" color="#F0C0C0C0"> <text pos="0 -40%" size="100% 10%" anchor-point="0.5 0" height="100%" text="ืฉืœื•ื Hello " font="Times New Roman.ttf" color="red"/> </box> <box pos="0%" size="25% 25%" anchor-point="0 1" color="olive" alpha="0.5"> <image pos="0" size="100% 100%" anchor-point="0 1" image="image1.png" /> </box> </scene> 

Adegan dibuat dengan menunjuk ke direktori atau file zip yang mengandung scene.xml. File gambar dan font yang tergantung harus berada di direktori atau file zip ini.


  match fb2d::scene::Scene::new_from_bundle("assets/scene1") { Ok(mut scene) => { let mut fb = fb2d::screen_writer_for_framebuffer("/dev/fb0")?; fb2d::set_graphics_mode(); scene.writer = Some(Box::new(fb)); scene.run(); } Err(e) => eprintln!("Error: {:?}", e), } 

Contoh gambar yang dihasilkan.
Dimungkinkan untuk merender bingkai dalam file PNG untuk debugging.



Repositori GitHub.


Setiap bantuan (Kontribusi) dihargai. Ada banyak pekerjaan untuk mengoptimalkan rendering, dan menambahkan fitur baru seperti animasi.

Source: https://habr.com/ru/post/id421707/


All Articles