FB2D - Marco 2D para Linux Frame Buffer (Rust)

Así que decidí contar sobre la biblioteca que escribí recientemente. Quizás alguien sea útil.
Este es un marco Rust 2D para renderizar directamente en Linux Frame Buffer / dev / fb0.


La tarea consistía en mostrar escenas 2D simples en la pantalla / TV en la Raspberry Pi. El Raspberry Pi se ejecuta bajo el control del Linux sin cabeza personalizado compilado con YoctoProject. Faltan administradores de ventanas, al igual que OpenGL. Solo queda el Frame Buffer.


En el caso de Frame Buffer, cada píxel debe ser procesado. Como escribo principalmente para GoLang para Raspberry Pi, decidí escribir una biblioteca en Go. Rápidamente me di cuenta de que Go no era adecuado para mi rendimiento. No podía realizar operaciones masivas con memoria en un tiempo razonable.


Entonces noté Rust, que realizó pruebas similares mucho más rápido.


Entonces, la biblioteca está desarrollada en Rust. Como este es mi primer proyecto en Rust, no pateo mucho, pero los comentarios son bienvenidos.


Como en cualquier biblioteca 2D, hay tres entidades principales: escenas, nodos y sprites.
Una escena es un contenedor para objetos visuales. Un nodo es un objeto virtual dotado de ciertas propiedades, como ubicación, tamaño, etc. Los nodos pueden estar anidados.
Cada nodo contiene un objeto visual, el llamado sprite. Los sprites vienen en varias formas. Ahora se admiten sprites como RectSprite, TextureSprite, TextSprite.


RectSprite : un rectángulo de cierto color. RectSprite incoloro se usa generalmente para agrupar otros nodos secundarios. RectSprite coincide con la etiqueta XML < box >


TextureSprite : un objeto para representar una imagen. Actualmente solo se admite PNG (RGBA). TextureSprite coincide con la etiqueta XML < imagen >


TechSprite : un objeto para representar una línea de texto en la fuente y el tamaño seleccionados. Hay soporte automático para RTL. TechSprite corresponde a la etiqueta XML < texto >


Además de los atributos de ubicación y tamaño, cada nodo tiene atributos de gravedad y anclaje. Esto ayuda a colocar con precisión el objeto dentro de otro objeto. Todos los atributos relacionados con el tamaño y la ubicación se configuran como un porcentaje del nodo principal. Este enfoque le permite lograr la mejor escala en pantallas de diferentes tamaños y proporciones.


Es posible crear una escena, ya sea mediante programación o creando un archivo xml que describa la escena.


  1. Una forma de software para crear y ejecutar una escena.


    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. Crear una escena usando un archivo 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> 

Una escena se crea apuntando a un directorio o archivo zip que contiene scene.xml. Los archivos de imágenes y fuentes dependientes deben ubicarse en este directorio o archivo zip.


  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), } 

Un ejemplo de la imagen resultante.
Es posible renderizar un marco en un archivo PNG para la depuración.



Repositorio de GitHub.


Cualquier ayuda (Contribución) es apreciada. Hay mucho trabajo para optimizar el renderizado y agregar nuevas características como la animación.

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


All Articles