Получение скриншота дочернего окна, в котором работает OpenGL (Windows) - PullRequest
3 голосов
/ 27 января 2010

У меня главное окно с детьми. Мне нужно сделать скриншоты программно, чтобы обрезать и нарисовать их в моем главном окне. Я делаю это так:

HDC hDC = GetWindowDC(hWnd);
HDC memDC = CreateCompatibleDC(hDC);
HBITMAP memBM = CreateCompatibleBitmap(hDC, Width, Height);
HBITMAP OldBM = (HBITMAP)::SelectObject(memDC, memBM );
BitBlt(memDC, 0, 0, Width, Height , hDC, BEGINX, BEGINY, SRCCOPY);
int Bpp = GetDeviceCaps(hDC,BITSPIXEL);
int size = Bpp/8 * ( Width * Height );
BYTE *lpBits = new BYTE[size];
GetBitmapBits(memBM, size, lpBits);

Но это не захватывает секцию OpenGL дочерних окон, вместо этого он просто рисует чистый белый цвет в области, где должен быть визуальный OGL.

Ответы [ 4 ]

0 голосов
/ 07 августа 2013

OpenGL может рендериться в многоуровневый контекст; попробовать

BitBlt(memDC, 0, 0, Width, Height , hDC, BEGINX, BEGINY, SRCCOPY | CAPTUREBLT);

вместо.

0 голосов
/ 27 января 2010

Возможно, NQR, но вы можете визуализировать свою сцену в растровое изображение и вставить ее в пустое пространство.

0 голосов
/ 07 августа 2013

Я предполагаю, что вы находитесь на выигрышной платформе.

Я думаю, вы можете отобразить в растровое изображение, даже если у вас нет исходного кода для дочернего окна.

  1. Сначала получите правильную ручку к дочернему окну
    • правильный поиск по дескриптору очень сложен, потому что почти все в win - это окно (так что есть сотни дескрипторов ...)
  2. создание растрового изображения
  3. изменить дескриптор рендеринга / контекст устройства в скриншоте окна на ваше растровое изображение.
    • не все окна могут это сделать !!!
  4. перекрасить силой
    • минимизировать / восстановить выигрыш или что-то еще
  5. сохраните ваше новое растровое изображение
  6. восстановить контексты рендеринга / устройства вашего скриншота окна.

Остерегайтесь, это не очень стабильный процесс (OpenGL может создавать конфликты при изменении дескрипторов контекста), а в некоторых случаях вы даже не можете изменить дескрипторы на контексты

Более безопасным является скриншот рабочего стола.

TCanvas *scr=new TCanvas();
scr->Handle=GetDC(GetDesktopWindow());
// copy scr to your bitmap (do not forget to resize bitmap)

Предупреждение: не получайте / не создавайте / не освобождайте контексты и не выигрывайте дескрипторы слишком часто, потому что это немного глючит (иногда функции winapi перестают возвращать правильные значения обработчика), лучший способ - получить дескриптор один раз и надеяться, что никто не закроет окно ... для вашего child выигрывает, вы точно знаете, когда нужно получить новый обработчик) Это верно и для функции IsWindow ().

Для получения дополнительной информации посмотрите:

0 голосов
/ 27 января 2010

Я помню, что у меня были похожие проблемы несколько лет назад, когда я пытался снять видео с экрана и просто получить черную область, где было видео. Обошли его в то время, уменьшив настройку аппаратного ускорения в драйвере видео (в XP: щелкните правой кнопкой мыши рабочий стол> свойства> настройки> дополнительные> устранение неполадок).

Что касается решения на основе кода, вы можете сослаться на следующие предыдущие сообщения:

Пустые скриншоты в Vista и Win7 при игре

Сохранение скриншота окна с использованием C #, WPF и DWM

...