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

Also beschloss ich, über die Bibliothek zu berichten, die ich kürzlich geschrieben habe. Vielleicht wird jemand nützlich sein.
Dies ist ein Rust 2D-Framework für das direkte Rendern in den Linux-Frame-Puffer / dev / fb0.


Die Aufgabe bestand darin, einfache 2D-Szenen auf einem Raspberry Pi anzuzeigen. Raspberry Pi wird unter Kontrolle mit YoctoProject Custom Headless Linux erstellt. Window-Manager fehlen, genau wie OpenGL. Nur der Rahmenpuffer bleibt übrig.


Im Falle eines Frame-Puffers muss jedes Pixel verarbeitet werden. Da ich hauptsächlich für GoLang für Raspberry Pi schreibe, entschied ich mich, eine Bibliothek auf Go zu schreiben. Ich habe schnell gemerkt, dass Go in Sachen Leistung nicht zu mir passt. Er konnte keine massiven Speicheroperationen in angemessener Zeit durchführen.


Dann fiel mir Rust auf, der ähnliche Tests viel schneller durchführte.


So ist die Bibliothek auf Rust entwickelt. Da dies mein erstes Projekt zu 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 ausgestattet ist, z. B. Ort, Größe usw. Knoten können verschachtelt sein.
Jeder Knoten enthält ein visuelles Objekt, das sogenannte Sprite. Sprites gibt es in verschiedenen Formen. Jetzt werden Sprites wie RectSprite, TextureSprite und TextSprite unterstützt.


RectSprite ist ein Rechteck einer bestimmten Farbe. RectSprite ohne Farbe wird normalerweise verwendet, um andere untergeordnete Knoten zu gruppieren. RectSprite entspricht dem XML-Tag < box >


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


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


Neben den Orts- und Größenattributen verfügt jeder Knoten über Schwerkraft- und Ankerattribute. Dies hilft, das Objekt innerhalb eines anderen Objekts genau zu positionieren. Alle Attribute, die der Größe und dem Ort zugeordnet sind, werden als Prozentsatz relativ zum übergeordneten Knoten festgelegt. Dieser Ansatz ermöglicht die beste Skalierung auf Bildschirmen unterschiedlicher Größe und Proportionen.


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


  1. Programmatische Möglichkeit zum Erstellen und Ausführen der Szene.


    letmut fb = fb2d::screen_writer_for_framebuffer("/dev/fb0")?;
    fb2d::set_graphics_mode();
    letmut 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();
    letmut 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");
    letmut 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;
    letmut 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. Eine Szene mit einer XML-Datei erstellen.

<scenecolor="#ffa500"><boxpos="0"size="95% 95%"anchor-point="0.5 0"color="#F0C0C0C0"><textpos="0 -40%"size="100% 10%"anchor-point="0.5 0"height="100%"text="שלום Hello Привет"font="Times New Roman.ttf"color="red"/></box><boxpos="0%"size="25% 25%"anchor-point="0 1"color="olive"alpha="0.5"><imagepos="0"size="100% 100%"anchor-point="0 1"image="image1.png" /></box></scene>

Die Szene wird erstellt, indem auf ein Verzeichnis oder eine ZIP-Datei verwiesen wird, die die scene.xml enthält. Abhängige Dateien mit Bildern und Schriftarten sollten sich in diesem Verzeichnis oder in dieser ZIP-Datei befinden.


match fb2d::scene::Scene::new_from_bundle("assets/scene1") {
        Ok(mut scene) => {
            letmut 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 in einer PNG-Datei für das Debugging wiederzugeben.



GitHub-Repository


Jede Hilfe (Beitrag) ist willkommen. Es gibt viel Arbeit, um das Rendern zu optimieren und neue Funktionen hinzuzufügen, wie z. B. Animationen.


Jetzt auch beliebt: