Хабрахабр

[Из песочницы] FB2D — 2D framework for Linux Frame Buffer (Rust)

Возможно кому-то и пригодится.
Это 2D framework на языке Rust для рендеринга непосредственно в Linux Frame Buffer /dev/fb0. Вот решил поведать о библиотеке, которую написал недавно.

Raspberry Pi работает под управление собранного при помощи YoctoProject custom headless Linux. Задача была — на Raspberry Pi выводить на экран / телевизор простые 2D сцены. Остается только Frame Buffer. Window Managers отсутствуют, так же, как и OpenGL.

Так как я для Raspberry Pi пишу в основном на GoLang, то решил написать библиотеку на Go. В случае с Frame Buffer обрабатывать приходится каждый пиксель. Массивные операции с памятью он не смог выполнить за разумное время. Очень быстро понял что Go не подходит мне по производительности.

Тогда я обратил внимание на Rust, который выполнял похожие тесты намного быстрее.

Так как, это мой первый проект на Rust, сильно не пинайте, но комментарии приветствуется. Итак, библиотека разработана на Rust.

Нод — это виртуальный объект, наделенный определенными свойствами, такими как местоположение, размер и т.д. Как в любой 2D библиотеке, здесь есть три главные сущности: сцены, ноды и спрайты.
Сцена — это контейнер для визуальных объектов. Спрайты бывают нескольких видов. Ноды могут быть вложенными.
Каждый нод содержит визуальный объект, так называемый спрайт. Сейчас поддерживаются спрайты типа RectSprite, TextureSprite, TextSprite.

RectSprite без цвета обычно используется для группировки других дочерних нодов. RectSprite — прямоугольник определенного цвета. RectSprite соответствует XML тегу <box>

На данный момент поддерживается только PNG (RGBA). TextureSprite — объект для рендеринга картинки. TextureSprite соответствует XML тегу <image>

Есть автоматическая поддержка RTL. ТехтSprite — объект для рендеринга одной строки текста выбранным шрифтом и размером. ТехтSprite соответствует XML тегу <text>

Это помогает точно расположить объект внутри другого объекта. В дополнении к атрибутам местоположения и размера каждый нод имеет атрибуты gravity и anchor. Такой подход позволяет достичь наилучшего масштабирования на экранах разного размера и пропорций. Все атрибуты связанные с размером и местоположением задаются в процентах относительно родительского нода.

Создать сцену возможно, как программным способом, так и создать описывающий сцену xml файл.

  1. Программный способ создания и запуска сцены.

    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 , 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. Создание сцены при помощи 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>

Зависимые файлы картинок и шрифтов должны находится в этом каталоге или zip файле. Сцена создается указанием на каталог или zip файл, содержащий scene.xml.

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

GitHub репозиторий.

Есть много работы по оптимизации рендеринга, и добавлению новых возможностей, таких как анимация. Любая помощь (Contribution) приветствуется.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»