2012-05-03 13 views
5

W mojej aplikacji wykonać kopie zawartości danego QGLWidget dla dwóch celów:Jak wziąć wiarygodne QGLWidget migawkę

  • Nie przerysowanie scenę przez cały czas, gdy tylko an zmiany nakładki, przy użyciu pamięci podręcznej pixmapę zamiast
  • Lat użytkownik robi zrzuty ekranu poszczególnych działek (scena 3D)

Pierwsza rzecz, którą wypróbowałem to grabFrameBuffer(). Używanie tej funkcji jest naturalne, jak w przypadku pierwszej aplikacji, co jest aktualnie widoczne w widgecie, to dokładnie to, co chcę buforować. PROBLEM: W przypadku niektórych sprzętów (np. Grafiki zintegrowanej z procesorem Intel, Mac OS X z grafiką GeForce) uzyskany obraz nie zawiera aktualnej zawartości ekranu, ale zawartość wcześniej. Jeśli więc scena byłaby narysowana dwa razy, na ekranie zobaczysz drugi rysunek, na obrazie zobaczysz pierwszy rysunek (który powinien być treścią bufora wstecznego?).

Druga rzecz, którą wypróbowałem to renderToPixmap(). To powoduje, że używasz paintGL(), ale nie używasz paint(). Mam wszystkie moje rzeczy w paint(), ponieważ używam funkcji malowania Qt i tylko mały kawałek kodu używa natywnego GL (beginNativePainting(), endNativePainting()).

Próbowałem również standardowej migawki QWidget (QPixmap :: fromWidget() lub jak to się nazywa), ale tam framebuffer GL jest czarny.

Jakieś pomysły, jak rozwiązać problem i uzyskać wiarygodny obraz aktualnie narysowanej sceny?

Odpowiedz

2

Jak wziąć niezawodne QGLWidget migawkę

Render bieżącej sceny do bufora ramki, należy zapisać dane z bufora ramki do pliku. Lub złap aktualny bufor zwrotny po glFlush. Coś jeszcze może zawierać artefakty lub niekompletną scenę.

+0

Skończyło się na pracy z FBO. – ypnos

1

Wynik QGLWidget::grabFrameBuffer(), podobnie jak w przypadku wszystkich innych wywołań OpenGL, zależy od sterownika wideo. Qt jedynie przekazuje twoje wezwanie do sterownika i chwyta obraz, który zwraca, ale zawartość obrazu nie znajduje się pod kontrolą Qt. Oprócz upewnienia się, że zainstalowałeś najnowszy sterownik swojej karty graficznej, niewiele możesz zrobić, z wyjątkiem zgłoszenia błędu producentowi karty wideo i pomodl się.

0

Używam paintGL(); i glFlush(); przed użyciem grabFrameBuffer(). PaintGL pomaga narysować bieżącą ramkę ponownie, zanim przejdzie do bufora ramki, który tworzy dokładną kopię tego, co aktualnie pokazuje.

2

Wygląda na to, że QGLWidget :: grabFrameBuffer() wewnętrznie wywołuje glReadPixels() z OpenGL. W konfiguracjach z podwójnym buforem tryb początkowy odczytuje bufor tylny (GL_BACK), przełącza się z wywołaniem OpenGL glReadBuffer (GL_FRONT) do bufora przedniego przed użyciem QGLWidget :: grabFrameBuffer() wyświetlającego obraz na ekranie.