2012-05-16 26 views
23

Mam aplikację wxWidgets, która ma wiele okien otwieranych przez dzieci. Używam mojej własnej klasy GL, a nie wx. Okna udostępniają swój kontekst OpenGL. Nie sądzę, że fakt, że to wxwidgets jest tutaj naprawdę istotny.Migotanie OpenGL/uszkodzone przy zmianie rozmiaru okna i aktywnym DWM

Okna typu OpenGL są potomkami okien, które są rodzeństwem nawzajem, zawartymi w kontrolce zakładki. Rodzaj interfejsu w stylu MDI, ale nie jest to okno MDI. Każda z nich może być indywidualnie zmieniana. Wszystkie utwory są piękne, o ile nie włączono Aero i aktywny jest DWM.

Zmiana rozmiaru dowolnego okna (nawet OpenGL nich) powoduje, że wszystkie okna OpenGL migotanie sporadycznie z czerstwego widokiem backing-sklepu, który zawiera cokolwiek śmieci jest na ekranie w tym momencie nie jest OpenGL. TYLKO dzieje się to przy włączonej opcji Aero.

Jestem prawie pewny, że jest to DWM, który nie ma zawartości opengl na swoim zapleczu powierzchni rysunku, a okno nie jest odświeżane we właściwym momencie.

Próbowałem tak wiele rzeczy, aby to obejść, mam rozwiązanie, ale nie jest to zbyt miłe i polega na odczytywaniu bufora ramki z glReadPixels do DIB, a następnie blaknięciu go do farby DC w mojej procedurze onPaint. To obejście jest włączone tylko wtedy, gdy funkcja DWM jest aktywna, ale wolałbym tego nie robić, ponieważ nieznacznie szkodzi wydajności (ale niezbyt dobrze działa na sprawnym systemie - sceny są stosunkowo prostymi wykresami 3D). Również mieszanie GDI i OpenGL nie jest zalecane, ale to podejście zadziwia, zadziwiająco. Mogę teraz z tym żyć, ale wolałbym nie. Nadal muszę to zrobić w WM_PRINT, jeśli chcę zrobić zrzut ekranu okna potomnego, nie widzę sposobu na obejście tego.

Czy ktoś wie o lepszym rozwiązaniu tego problemu?

Zanim ktoś pyta Zdecydowanie należy wykonać następujące czynności:

  • klasa Okno ma CS_OWNDC
  • WM_ERASEBACKGROUND nic nie robi i zwraca TRUE.
  • Podwójne buforowanie jest włączone.
  • Okna mają style okien WS_CLIPSIBLINGS i WS_CLIPCHILDREN.
  • W moim programie obsługi zdarzeń zmiany rozmiaru natychmiast odmalowuję okno.

Próbowałem:

  • Ustawianie PFD_SUPPORT_COMPOSITION w deskryptorze format pikseli.
  • Nie używa się wxPaintDC w uchwycie do malowania i zamiast tego wywołuje :: ValidateRect (hwnd, NULL).
  • Handling WM_NCPAINT wyłączeniem obszaru roboczego
  • Wyłączenie NC farby przez DWM API
  • Wyłączając obszaru roboczego w przypadku farb
  • Wywołanie glFlush i/lub glFinish przed i po zamianie buforowego.
  • Unieważnienie okna przy każdym zdarzeniu lakierniczym (jako test!) - nadal migocze !
  • Nie używanie współużytkowanego kontekstu GL.
  • Wyłączanie podwójnego buforowania.
  • Pisząc do GL_FRONT_AND_BACK

Wyłączenie DWM nie jest rozwiązaniem.

I o ile mi wiadomo, jest to nawet problem, jeśli używasz Direct3D zamiast OpenGL, chociaż nie testowałem tego, ponieważ reprezentuje on wiele pracy.

+0

mam podobne problemy z aplikacji MFC MDI i OpenGL, w której kontrole MFC czasami zostawić wyciągnąć artefakty w oknie GL. Dzieje się tak tylko wtedy, gdy włączona jest funkcja Aero. Podobnie nie znalazłem satysfakcjonującego rozwiązania. – mcmcc

+0

Blitting do okna z treścią opengl odczytaną z glReadPixels wydaje się go rozwiązywać, ale musi być lepsza metoda. – Pete

Odpowiedz

0

Hmm, może wpadłeś na ten sam problem: jeśli używasz "nowego" MFC , utworzysz i użyjesz Tabs i Window Spliter.

Splitter ma pewną logikę (zgaduję, że gdzieś wokół przezroczystego okna i rysuje linie XOR dla podziału), które powoduje to zachowanie. Usuń splitter, aby potwierdzić, że to rozwiązało problem z numerem . Jeśli potrzebujesz funkcji podziału - włóż inny rozdzielacz.

Również zakładki umożliwiają dokowanie i ponowne dzielenie okien z tym samym problemem - usuń/zamień.

Powodzenia Igor

+0

Nie jest to aplikacja wxWidgets, czy odpowiadasz na komentarz mcmcc? Myślę, że ostatecznym problemem jest to, że DWM jest kompozycją w innym wątku. – Pete

+0

Rozwiązałem ten sam problem, zastępując wszystkie moje wywołania OpenGL w metodzie Paint. Nie mam dostępu do mojego kodu do poniedziałku, więc nie mogę podać więcej szczegółów teraz ... przynajmniej używam VCL, ale ponieważ jest to ten sam problem, to może być to samo rozwiązanie! – Maypeur

2

To longshot, ale Właśnie rozwiązane dokładnie ten sam problem sam.

Część dłuższa jest dostępna, ponieważ wykonujemy rysowanie przez właściciela obrysu pola grupy bez napisów, które otacza nasze okno OpenGL (tzn. Tworzy ładne małe obramowanie), a to może nie opisywać Twojego przypadku.

Co okazało spowodowane problemem było to:

Byliśmy przy użyciu RoundRect() połączenia (z HOLLOW_BRUSH), aby narysować zarys polu grupy. Zmiana na wywołania funkcji MoveToEx() i LineTo(), aby upewnić się, że linie są rysowane i nic nie zostanie zrobione w polu grupy, uniemożliwiając GDI nieoczekiwane odświeżenie całej zawartości formantu. Możliwe, że istnieje różnica w logice unieważniania (lub w jakiś sposób mieliśmy błąd w ładowaniu zamierzonego pustego pędzla). Nadal badamy.

-Noel