FB2D - 2D Framework für Linux Frame Buffer (Rust)

Also habe ich beschlossen, über die Bibliothek zu erzählen, die ich kürzlich geschrieben habe. Vielleicht wird jemand nützlich sein.
Dies ist ein Rust 2D-Framework zum direkten Rendern in Linux Frame Buffer / dev / fb0.


Die Aufgabe bestand darin, einfache 2D-Szenen auf dem Bildschirm / Fernseher des Raspberry Pi anzuzeigen. Der Raspberry Pi läuft unter der Kontrolle des mit YoctoProject kompilierten benutzerdefinierten Headless Linux. Fenstermanager fehlen ebenso wie OpenGL. Es bleibt nur der Frame Buffer übrig.


Im Fall von Frame Buffer muss jedes Pixel verarbeitet werden. Da ich hauptsächlich für GoLang für Raspberry Pi schreibe, habe ich beschlossen, eine Bibliothek auf Go zu schreiben. Mir wurde schnell klar, dass Go für meine Leistung nicht geeignet war. Er konnte in angemessener Zeit keine massiven Operationen mit Gedächtnis durchführen.


Dann bemerkte ich Rust, der ähnliche Tests viel schneller durchführte.


Die Bibliothek wurde also auf Rust entwickelt. Da dies mein erstes Projekt in Rust ist, treten Sie nicht viel, aber Kommentare sind willkommen.


Wie in jeder 2D-Bibliothek gibt es drei Hauptelemente: Szenen, Knoten und Sprites.
Eine Szene ist ein Container für visuelle Objekte. Ein Knoten ist ein virtuelles Objekt, das mit bestimmten Eigenschaften wie Standort, Größe usw. ausgestattet ist. Knoten können verschachtelt werden.
Jeder Knoten enthält ein visuelles Objekt, das sogenannte Sprite. Sprites gibt es in verschiedenen Formen. Sprites wie RectSprite, TextureSprite, TextSprite werden jetzt unterstützt.


RectSprite - ein Rechteck einer bestimmten Farbe. Farbloses RectSprite wird normalerweise zum Gruppieren anderer untergeordneter Knoten verwendet. RectSprite stimmt mit dem XML-Tag < box > überein


TextureSprite - ein Objekt zum Rendern eines Bildes. Derzeit wird nur PNG (RGBA) unterstützt. TextureSprite entspricht dem XML-Tag < Bild >


TechSprite - ein Objekt zum Rendern einer Textzeile in der ausgewählten Schriftart und Größe. Es gibt automatische Unterstützung für RTL. TechSprite entspricht dem XML-Tag < text >


Zusätzlich zu den Standort- und Größenattributen verfügt jeder Knoten über Schwerkraft- und Ankerattribute. Dies hilft, das Objekt genau in einem anderen Objekt zu positionieren. Alle Attribute in Bezug auf Größe und Position werden als Prozentsatz des übergeordneten Knotens festgelegt. Mit diesem Ansatz können Sie die beste Skalierung auf Bildschirmen unterschiedlicher Größe und Proportionen erzielen.


Es ist möglich, eine Szene entweder programmgesteuert oder eine XML-Datei zu erstellen, die die Szene beschreibt.


  1. Eine Software-Methode zum Erstellen und Ausführen einer Szene.


    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. Erstellen einer Szene mithilfe einer XML-Datei.

 <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> 

Eine Szene wird erstellt, indem auf ein Verzeichnis oder eine Zip-Datei verwiesen wird, die scene.xml enthält. Abhängige Bild- und Schriftdateien müssen sich in diesem Verzeichnis oder in dieser Zip-Datei befinden.


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

Ein Beispiel für das resultierende Bild.
Es ist möglich, einen Frame zum Debuggen in einer PNG-Datei zu rendern.



GitHub-Repository.


Jede Hilfe (Beitrag) wird geschätzt. Es gibt viel Arbeit, um das Rendering zu optimieren und neue Funktionen wie Animationen hinzuzufügen.

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


All Articles