Окно OpenGL очищено без сообщения WM_PAINT

У меня есть приложение с тремя окнами MDI, все из которых показывают содержимое OpenGL. На XP все нормально работает. Но в Vista / Win7 дочерние окна mdi не обновляются должным образом.

После запуска все окна отображают свое содержимое правильно. Но когда я меняю фокус с одного окна mdi на другое, эти два окна очищаются (т.е. они показывают только белый цвет, без содержимого). Я понятия не имею, почему окна очищаются, они не получают никаких сообщений WM_ *, когда это происходит, и, конечно же, не получают сообщения WM_PAINT.

При изменении размера этих окон я правильно получаю сообщение WM_PAINT (после WM_SIZE) и перерисовываю содержимое, но затем окно также очищается, что приводит к странному мерцанию при изменении размера. После остановки изменения размера окно остается чистым (белым) до тех пор, пока я не принудительно обновлю его вручную.

Это происходит независимо от того, включен или выключен Aero.

Есть идеи, почему это происходит?


person Stefan    schedule 17.11.2009    source источник


Ответы (1)


Я удивлен, что он работает на XP. По моему (ограниченному) опыту работы с OpenGL, WM_PAINT - не всегда лучшее место для перерисовки сцен OpenGL. Скорее всего, содержимое стирается на уровне драйвера. Вы можете проверить это, посмотрев, что происходит, когда одно из ваших окон MDI охватывает два монитора, подключенных к двум разным видеокартам.

Попробуйте следующее:

  1. Повторно инициализируйте контексты OpenGL после появления WM_SIZE.
  2. Рисуйте по запросу, а не в WM_PAINT. В обработчике WM_PAINT ничего не делайте. Используйте таймер или другой механизм, чтобы периодически запускать обновления ваших дисплеев.
  3. Мерцание обычно вызывается помехами через WM_ERASEBKGND. Если вы еще этого не сделали, перехватите WM_ERASEBKGND и ничего не делайте в регионах, где вы показываете содержимое OpenGL.
  4. Используйте стиль окна CS_OWNDC в любых окнах, на которых размещается содержимое OpenGL, чтобы HDC не изменялся для каждого сообщения / вызова во время жизни ваших окон MDI.

Другие, более редкие причины помех, которые могут возникнуть (поскольку вы используете окна MDI)

  1. WM_NCPAINT и другие связанные сообщения о рисовании, не относящиеся к клиенту - вы можете обойти их, переместив содержимое OpenGL в дочернее окно без рамки внутри окон MDI.
  2. Неверные / несовместимые функции по умолчанию для OpenGL на вашей видеокарте, которые явно требуют наложения или неявно их используют (частая причина проблем в перекрывающихся контекстах). К сожалению, диагностировать это за пределами моих знаний, но некоторые тесты могут пролить здесь дополнительный свет.
person meklarian    schedule 17.11.2009
comment
Спасибо за все подсказки. Я попробую их, как только вернусь в офис. - person Stefan; 17.11.2009
comment
нп. Кроме того, вы можете получить лучшие ответы от людей, которые имеют более глубокий опыт работы с OpenGL, разместив фрагмент кода инициализации вашего контекста. - person meklarian; 17.11.2009
comment
Если вы не используете игровой цикл, рисуйте в ответ на WM_PAINT. Если вы рисуете все, вы можете переопределить WM_ERASEBKGND и ничего не делать там, чтобы избежать мерцания. В вашем конкретном случае должна быть какая-то другая проблема, например, не сбрасывание команд OpenGL. - person gast128; 19.08.2016