FB2D - إطار ثنائي الأبعاد لمخزن إطار الإطار (الصدأ)

لذلك قررت أن أخبر عن المكتبة التي كتبتها مؤخرًا. ربما شخص ما سيكون في متناول اليدين.
هذا هو إطار Rust 2D للعرض مباشرة في Linux Frame Buffer / dev / fb0.


كانت المهمة هي عرض مشاهد ثنائية الأبعاد بسيطة على الشاشة / التلفزيون على Raspberry Pi. يعمل Raspberry Pi تحت سيطرة المترجمة مع YoctoProject المخصص لينكس بدون رأس. مديرو النوافذ مفقودون ، وكذلك OpenGL. يبقى الإطار المؤقت فقط.


في حالة المخزن المؤقت للإطار ، يجب معالجة كل بكسل. نظرًا لأنني أكتب أساسًا لـ GoLang لـ Raspberry Pi ، فقد قررت كتابة مكتبة على Go. أدركت بسرعة أن Go لم يكن مناسبًا لأدائي. لم يستطع القيام بعمليات ضخمة مع الذاكرة في وقت معقول.


ثم لاحظت الصدأ ، الذي أجرى اختبارات مماثلة بشكل أسرع بكثير.


لذلك ، تم تطوير المكتبة على Rust. نظرًا لأن هذا هو أول مشروع لي في Rust ، فلا تنطلق كثيرًا ، ولكن التعليقات مرحب بها.


كما هو الحال في أي مكتبة ثنائية الأبعاد ، هناك ثلاث كيانات رئيسية: المشاهد والعقد والعفاريت.
المشهد عبارة عن حاوية للأشياء المرئية. العقدة هي كائن افتراضي يتمتع بخصائص معينة ، مثل الموقع والحجم وما إلى ذلك. يمكن أن تتداخل العقد.
تحتوي كل عقدة على كائن مرئي ، ما يسمى العفريت. تأتي العفاريت في عدة أشكال. الرموز المتحركة مثل RectSprite و TextureSprite و TextSprite مدعومة الآن.


RectSprite - مستطيل بلون معين. عادةً ما يتم استخدام RectSprite عديم اللون لتجميع العقد الفرعية الأخرى. يتطابق RectSprite مع علامة XML < box >


TextureSprite - كائن لعرض الصورة. يتم دعم PNG (RGBA) فقط حاليًا. يتطابق TextureSprite مع علامة XML < image >


TechSprite - كائن لتقديم سطر واحد من النص في الخط والحجم المحددين . هناك دعم تلقائي لـ RTL. يتوافق TechSprite مع علامة XML < text >


بالإضافة إلى سمات الموقع والحجم ، لكل عقدة خصائص الجاذبية والمرساة. هذا يساعد على وضع الكائن بدقة داخل كائن آخر. يتم تعيين جميع السمات المتعلقة بالحجم والموقع كنسبة مئوية من العقدة الرئيسية. يتيح لك هذا النهج تحقيق أفضل قياس على الشاشات ذات الأحجام والنسب المختلفة.


من الممكن إنشاء مشهد إما برمجياً أو إنشاء ملف 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 { 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. إنشاء مشهد باستخدام ملف 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> اللون = <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> 

يتم إنشاء مشهد بالإشارة إلى دليل أو ملف مضغوط يحتوي على 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), } 

مثال على الصورة الناتجة.
من الممكن تقديم إطار في ملف PNG لتصحيح الأخطاء.



مستودع جيثب.


أي مساعدة (مساهمة) هي محل تقدير. هناك الكثير من العمل لتحسين العرض وإضافة ميزات جديدة مثل الرسوم المتحركة.

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


All Articles