2009-08-27 14 views
5

Mam aplikację MDI napisaną w Qt. Niektóre z okien podwodnych obejmują: QGLWidget s, tj. Konteksty OpenGL. Najważniejsze z nich używają werteksów i cieniowania OpenGL do wizualizacji swoich danych.Aplikacja Qt MDI z OpenGL: jak pobrać prawidłowy zrzut ekranu?

Potrzebuję programowo przechwycić zrzut ekranu głównego okna aplikacji, w tym oczywiście wszystkie widoczne okna boczne. Na pierwszy rzut oka jest to łatwe ("zadaje się wiele pytań, więc po prostu google!"), Ale po bliższym przyjrzeniu wydaje się być nieco skomplikowane ...

Oto, co próbowałem do tej pory :

  1. QPixmap::grabWidget nie działa dla subwindows używających programów cieniujących, najwyraźniej dlatego, że kontekst przekierowanie nie wydaje się wspierać niezbędnych rozszerzeń OpenGL. (Kod renderujący sprawdza, czy powiązany kontekst obsługuje wymagane rozszerzenia, i odmawia kontynuacji, jeśli nie).
  2. QPixmap::grabWindow po cichu pozostawia puste wszystkie konteksty OpenGL - nawet te, które używają tylko podstawowych elementów podstawowych.
  3. QGLWidget::grabFrameBuffer działa, ale przechwytuje tylko kontekst OpenGL konkretnego okna podrzędnego, natomiast chciałbym pobrać całą aplikację (zasadniczo to, co robi Alt+PrtScr w Windows).

Próbowałem także wykonać pierwsze # 2, a następnie powtórzenie # 3 dla wszystkich okien okiennych, po prostu skopiowanie wyniku # 3 do właściwej lokalizacji obrazu z # 2. To działało bardzo dobrze, dopóki nie nakładałem na siebie kilku podwinięć - w takim przypadku obrazy z # 3 nadpisują ramki okien itp. Tak więc to podejście prawdopodobnie wymagałoby znacznie więcej kodu, aby obsłużyć wszystkie nieprzyjemne przypadki narożników ...

Dodatkowe tło: gdy otrzymam zrzut ekranu, zamierzam umieścić kilka z nich w kolejności, aby utworzyć film - prawdopodobnie za pomocą ffmpeg. Czyni to pytanie rodzajem kontynuacji (pierwszej części) my previous question; Po prostu aplikacja ewoluowała od pojedynczego kontekstowego, autonomicznego programu OpenGL do czegoś, co używa Qt do ogólnego wyglądu okien i widżetów interfejsu użytkownika, i osadza grafikę w oknach.

Podczas gdy ja wolałbym oczywiście dobre, wieloplatformowe rozwiązanie Qt, jestem skłonny rozważyć użycie hack'a specyficznego dla systemu Windows. (Które powinny być możliwe, jak widzę, Alt+PrtScr robi bardzo dobrze.)

Jakieś sugestie?

Odpowiedz

2

Bardzo hackish, ale czy przechwytywanie pulpitu (bez ukrywania okna), jak w this tutorial i przycinanie wszystko oprócz okna pracy?

Mówiąc ogólniej, nie jestem nawet pewien, czy specyfikacja OpenGL wymaga umieszczenia danych wyjściowych w buforze frontowym: implementacja może po prostu wykorzystywać nakładki wideo (lub Voodoo2-esque przejścia przez VGA) dla wyjścia.

+0

To robi * * Praca! Dlaczego nie mogłem o tym pomyśleć? ...Jedyną wadą, którą widzę, jest to, że jest to nieco wolniejsze w porównaniu z chwytaniem tylko interesującego okna. To może okazać się trafne, ponieważ faktycznie próbuję pobrać film. Ale i tak akceptuję odpowiedź, ponieważ robi dokładnie to, o co prosiłem - dziękuję bardzo! – Reunanen

1

Jedyne co mogę myśleć off-hand jest zrobić następujące psuedocode:

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. 
+0

Zgadzam się, że to powinno zadziałać, dlatego +1. Ale przynajmniej na razie zamierzam wziąć leniwą ścieżkę :) – Reunanen