تطبيق Qt MDI مع OpenGL:كيفية الحصول على لقطة شاشة صالحة؟
-
20-09-2019 - |
سؤال
انا لدي MDI التطبيق مكتوب في كيو تي.بعض النوافذ الفرعية تشمل QGLWidget
ق، أي سياقات OpenGL.أبرزها استخدام OpenGL vertex وتظليل الأجزاء لتصور بياناتها.
أحتاج إلى التقاط لقطة شاشة للنافذة الرئيسية للتطبيق برمجيًا، بما في ذلك بالطبع جميع النوافذ الفرعية التي تكون مرئية.يبدو الأمر سهلاً في البداية ("لقد تم طرح هذا السؤال عدة مرات بالتأكيد، لذلك دعونا نبحث عنه في جوجل!")، ولكن بعد نظرة فاحصة يبدو أن الأمر أصبح صعبًا بعض الشيء...
الآن إليك ما جربته حتى الآن:
QPixmap::grabWidget
لا يعمل مع النوافذ الفرعية التي تستخدم برامج التظليل، على ما يبدو لأن سياق إعادة التوجيه لا يبدو أنه يدعم ملحقات OpenGL الضرورية.(يتحقق رمز العرض من أن السياق المرتبط يدعم الامتدادات المطلوبة، ويرفض الاستمرار إذا لم يكن كذلك.)QPixmap::grabWindow
يترك جميع سياقات OpenGL فارغة بصمت - حتى تلك التي تستخدم الأوليات الأساسية فقط.QGLWidget::grabFrameBuffer
يعمل، ولكنه يلتقط فقط سياق OpenGL للنافذة الفرعية المحددة، بينما أرغب في الحصول على التطبيق بالكامل (أساسًا ماAlt+PrtScr
يفعل في ويندوز).
لقد حاولت أيضًا القيام بالرقم 2 أولاً ثم التكرار رقم 3 لجميع النوافذ الفرعية، فقط قم بنسخ نتيجة رقم 3 إلى الموقع الصحيح للصورة من رقم 2.لقد نجح هذا بشكل جيد للغاية، حتى قمت بتداخل بعض النوافذ الفرعية - وفي هذه الحالة تقوم الصور من رقم 3 بالكتابة فوق إطارات النوافذ الفرعية، وما إلى ذلك.لذلك ربما يتطلب هذا الأسلوب المزيد من التعليمات البرمجية للتعامل مع جميع حالات الزاوية السيئة ...
بعض الخلفية الإضافية:بمجرد حصولي على لقطة الشاشة، سأقوم بوضع العديد منها في تسلسل لإنشاء مقطع فيديو - ربما باستخدام ffmpeg.وهذا يجعل هذا السؤال نوعًا من الاستمرارية لـ (الجزء الأول من) سؤالي السابق;كل ما في الأمر هو أن التطبيق قد تطور من برنامج OpenGL مستقل ذي سياق واحد إلى شيء يستخدم Qt للنوافذ الشاملة وعناصر واجهة المستخدم، ويدمج الرسومات في النوافذ الفرعية.
على الرغم من أنني أفضّل بالطبع حلاً لطيفًا عبر الأنظمة الأساسية من نوع Qt-ish، إلا أنني على استعداد للتفكير في اللجوء إلى اختراق خاص بنظام التشغيل Windows أيضًا.(وهذا ينبغي أن يكون ممكنا، كما أستطيع أن أرى Alt+PrtScr
القيام بالشيء الصحيح إلى حد كبير.)
لذا، أي اقتراحات؟
المحلول
اختراق للغاية، ولكنه يلتقط سطح المكتب (دون إخفاء نافذتك) كما هو الحال في هذا البرنامج التعليمي واقتصاص كل شيء ما عدا نافذتك؟
بشكل عام، لست متأكدًا حتى من أن مواصفات OpenGL تتطلب وضع الإخراج في المخزن المؤقت الأمامي:يمكن للتنفيذ فقط استخدام تراكبات الفيديو (أو خدع تمرير VGA من Voodoo2-esque) للإخراج.
نصائح أخرى
الشيء الوحيد الذي يمكنني التفكير فيه بشكل غير مباشر هو تنفيذ الكود الكاذب التالي:
for each window
grab the window into its own pixmap
grab the GL portions and paste into the windows
order the window pixmaps by depth of the window (deepest first)
initialize a common pixmap
for each window pixmap
paint the window pixmap into the common pixmap at the appropriate location.
هل هذا له أي فائدة؟؟
توضح أمثلة Grabber كيفية استرداد محتويات مخزن إطارات OpenGL