У меня есть приложение wxWidgets, в котором есть несколько дочерних окон. Я использую свой собственный класс холста GL, а не wx. Окна разделяют контекст OpenGL. Я не думаю, что факт wxwidgets действительно имеет значение здесь.
Окно opengl - это дети окон, которые являются братьями и сестрами друг друга, содержащиеся в элементе управления вкладкой. Вид интерфейса интерфейса MDI, но это не окно MDI. Каждый из них может быть индивидуально изменен. Все работает прекрасно, если только Aero не включен и DWM активен.
Изменение размера любого окна (даже не opengl) приводит к тому, что все окна opengl иногда мерцают со старым представлением хранилища, в котором содержится всякий мусор на экране в тот момент, который не является opengl. Это ТОЛЬКО случается с включенным Aero.
Я почти уверен, что это DWM, на самом деле не имеющее содержимого opengl на его основе для поддержки поверхности рисования, а окно не перекрашивается в нужный момент.
Я пробовал так много вещей, чтобы обойти это, у меня есть решение, но оно не очень красивое и включает в себя чтение фреймбуфера с glReadPixels в DIB, а затем смешение его с краской DC в моей программе onPaint. Этот обходной способ разрешен только в том случае, если DWM активен, но я бы предпочел не делать этого вообще, так как он немного ухудшает производительность (но не так уж плохо на работоспособной системе - сцены относительно простые 3D-графики). Также не рекомендуется смешивать GDI и opengl, но этот подход работает, на удивление. Я могу жить с этим пока, но мне бы этого не хотелось. Я все еще должен сделать это в WM_PRINT, если я хочу сделать снимок экрана дочернего окна в любом случае, я не вижу способа обойти это.
Кто-нибудь знает о лучшем решении этого вопроса?
Прежде чем кто-нибудь спросит, я определенно сделаю следующее:
- Класс Window имеет CS_OWNDC
- WM_ERASEBACKGROUND ничего не делает и возвращает TRUE.
- Двойная буферизация включена.
- В Windows есть стили оформления WS_CLIPSIBLINGS и WS_CLIPCHILDREN.
- В моем обработчике событий resize я сразу перерисовываю окно.
Я пробовал:
- Настройка PFD_SUPPORT_COMPOSITION в дескрипторе формата пикселей.
- Не использовать wxPaintDC в обработчике краски и вызове :: ValidateRect (hwnd, NULL).
- Обработка WM_NCPAINT и исключение клиентской области
- Отключение NC-краски через API DWM
- Исключение области клиента в событии рисования
- Вызов glFlush и/или glFinish до и после замены буфера.
- Нарушение окна при каждом событии рисования (как тест!) - все еще мерцает!
- Не использовать общий контекст GL.
- Отключение двойной буферизации.
- Запись в GL_FRONT_AND_BACK
Отключение DWM не является опцией.
И насколько мне известно, это даже проблема, если вы используете Direct3D вместо OpenGL, хотя я не тестировал это, поскольку он представляет собой большую работу.