Приложение Qt MDI с OpenGL: как получить действительный скриншот? - PullRequest
5 голосов
/ 27 августа 2009

У меня есть приложение MDI , написанное на Qt. Некоторые из подокон включают QGLWidget s, то есть контексты OpenGL. Наиболее выдающиеся из них используют вершинные и фрагментные шейдеры OpenGL для визуализации своих данных.

Мне нужно программно сделать снимок экрана главного окна приложения, включая, конечно, все подокна, которые оказываются видимыми. Поначалу звучит легко («определенно спрашивали много раз, так что давайте просто погуглим!»), Но после более пристального взгляда, кажется, становится немного сложнее ...

Теперь вот что я попробовал:

  1. QPixmap::grabWidget не работает для подокон, в которых используются шейдерные программы, по-видимому, поскольку контекст перенаправления не поддерживает необходимые расширения OpenGL. (Код рендеринга проверяет, что связанный контекст поддерживает требуемые расширения, и отказывается продолжать, если нет.)
  2. QPixmap::grabWindow молча оставляет все контексты OpenGL пустыми - даже те, которые используют только основные примитивы.
  3. QGLWidget::grabFrameBuffer работает, но захватывает только контекст OpenGL определенного подокна, в то время как я хотел бы получить все приложение (в основном то, что Alt+PrtScr делает в Windows).

Я также попытался выполнить сначала # 2, а затем повторить # 3 для всех подокнов, просто скопировав результат # 3 в правильное место изображения из # 2. Это работало очень хорошо, пока я не наложил некоторые подокна - в этом случае изображения из # 3 перезаписывают кадры подокна и т. Д. Так что этот подход, вероятно, потребовал бы гораздо больше кода для обработки всех неприятных угловых случаев ...

Некоторый дополнительный фон: как только я получу скриншот, я собираюсь поместить несколько из них в последовательность для создания видео - вероятно, используя ffmpeg . Это делает этот вопрос своего рода продолжением (первая часть) моего предыдущего вопроса ; просто приложение превратилось из автономной OpenGL-программы с одним контекстом в нечто, использующее Qt для общей работы с окнами и виджетами пользовательского интерфейса, и внедряет графику в подокна.

Хотя я, конечно, предпочел бы хорошее кроссплатформенное решение Qt-ish, я готов рассмотреть возможность использования хака, специфичного для Windows. (Это должно быть возможно, как я вижу, Alt+PrtScr делает очень правильные вещи.)

Итак, есть предложения?

Ответы [ 3 ]

2 голосов
/ 28 августа 2009

Очень хакерский, но работает ли захват рабочего стола (без скрытия окна), как в этом уроке , и обрезка всего, кроме вашего окна?

В целом, я даже не уверен, что спецификация OpenGL требует, чтобы выходные данные помещались в передний буфер: реализация могла бы просто использовать наложения видео (или Voodoo2-esque VGA-сквозные махинации) для вывода.

1 голос
/ 28 августа 2009

Единственное, о чем я могу подумать, это сделать следующий псевдокод:

 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 голосов
/ 28 августа 2009
...