• 0
Pax Beach

Снимок экрана в полноэкранном приложении DirectX

Вопрос

Мне нужно сделать снимок экрана из своего приложения в приложении DirectX (в игре).

По-быстрому накидал приложение, исходники здесь: MakeScreenshot-Forum.zip

screen.jpg.ee04f8b3fb65b38a05dcabf7a6ad22ef.jpg

1. по нажатию единственной кнопки будет выполнена серия из 16 снимков экрана. Если запущен Скайп, то фотографироваться будет содержимое его окна.

2. По нажатии CTRL+ALT+F9 будет сделан единичный снимок

3. Label внизу показывает сколько миллисекунд затрачено на вывод снимка

4. В комментах так же вы найдете, как работать со снимками через буфер обмена.

 

Работа выполняется через GetDC(NULL);

Windows 10 x64. Снимки делаются. И DirectX тоже нормально фотографируется.

НО! только в оконных приложениях.

Если приложение DirectX полноэкранное, то на всех снимках одна и та же картинка с первого снимка.
То есть изменение буфера экрана в приложении ни как не отражается на снимках.

 

Что нужно? Необходимо делать снимки конкретного приложения через интерфейс DirectX, а точнее, я так понимаю, через DirectShow. Тогда не будет разницы в окне оно или на полный экран.

Помогите плиз, знающие люди, с решением этой задачи.

Гарантирую вам от сообщества большой почет, от меня огромный респект, если это принесет доход, то еще и очень приятный бонус.

 

Ссылки теме:

1. DIRECTX FOR DELPHI

2. unofficial version of DelphiX

3. DirectX для начинающих

4. MinHook - The Minimalistic x86/x64 API Hooking Library

5. Various methods for capturing the screen

6. Вывод графики на рабочий стол Windows с использованием оверлеев DirectX

7. Project JEDI

8. Реализация перехвата вызовов API — исчерпывающе про внедрение DLL, если разобраться, + это на Delphi

UPD:

9. Серия видео уроков Пишем D3D-хук — все понятно, только в Delphi перенести нужно.

UPD 2:

Научился рисовать в Direct3D и ловить интерфейс IDirect3DDevice9. Теперь делаю DLL ловушку для реализации снимков.

 

Изменено пользователем Pax Beach

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

13 ответов на этот вопрос

  • 0
7 минут назад, Rusland сказал:

Поиск — это искусство.

Спасибо тебе огромное! Не понимаю, как я мог его не найти.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Приведенный класс не корректно работает в полноэкранном режиме.

К тому же в режиме DirectX не верно определяется видеоадаптер.

Разбираюсь с этим пока.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Может из этого граббера можно получить какую-то полезную информацию

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
23 минуты назад, Rusland сказал:

Может из этого граббера можно получить какую-то полезную информацию

компилится?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Компилится, но не понял как он должен грабить видео

Изменено пользователем Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
1 минуту назад, Rusland сказал:

Компилится, но не понял как он должен грабить видео

Это граббер с утройств, написер с камеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
4 минуты назад, Rusland сказал:

тогда ой )

В этом видимо есть какой-то потенциал, если научиться получить DX контекст в качестве устройства для метода ICreateDevEnum

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Собственно где я это нашел,  и обсуждалось что нужно переделать эти исходники, чтобы делать снимок с DirectX

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
3 минуты назад, Rusland сказал:

Собственно где я это нашел,  и обсуждалось что нужно переделать эти исходники, чтобы делать снимок с DirectX

давай уже ссылку, может там люди что-нить еще рассказывают )

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

ссылку не найду... но там старая тема и ничего интересно кроме этих исходников

Хотя вот нашел. Может тебе на Си писать dll? Есть же решения.

Еще чего-то про оверлеи, не знаю полезно ли оно.

А может можно эмулировать нажатие Printscreen и брать из буфера обмена?

Изменено пользователем Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Никакие оверлеи, и уж тем более всяческие эмуляции нажатий, или посылки сообщений окну не позволят устойчиво снимать скрин direct-x приложения (полноэкранного). Директ работает не так, как GDI, а посему в определенный момент в памяти ничего не будет, там, откуда вы пытаетесь получить инфу. ЕДинственный метод - хучить вызовы и свою dll в процесс, как впрочем и делает большинство граберов, которые позволяют подобное (это если выражаться очень условно). Посему, если это не бот - решение именно такое. Вышеописанный класс работает НА direct-x но С экранной памятью - в полноэкранном режиме это бессмысленно

 

Вот, для общего развития C# – SCREEN CAPTURE WITH DIRECT3D 9 API HOOKS

Там шарп, но для понимания сути пойдет. Да и на крайний случай, можно либо переписать, либо засунуть в dll шарп-код а потом дергать оттуда нужное. 

 

P.S. к слову, если внизу цифры верные (для одного скрина), то это п... очень медленно. И на 10-ке, ну и на 8-ке со скрипом лучше использовать Desktop Duplication API. Скорость работы такая же, как и у GDI, но при этом чертовски маленькая нагрузка на систему.

Изменено пользователем Gingercat

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: Вадим Смоленский
      Этот вопрос сложился из двух, которые я здесь уже задавал, но ответов не получил. Первый касался странного поведения TWebBrowser. Второй - ненужного мелькания в виде белого квадрата при вызове TPopup и TPopupMenu. Теперь оказалось, что эти проблемы связаны. Мне удалось их воспроизвести в маленьком демонстрационном проекте (Windows), который прилагаю в виде зипа и скриншота.

      Кнопка Hide/Show прячет и снова показывает TWebBrowser. Но если хоть один раз (когда TWebBrowser виден) вызвать TPopupMenu или TPopup, это перестает работать - TWebBrowser отказывается прятаться. Характерно еще то, что в момент вызова TPopupMenu или TPopup в левом верхнем углу формы на долю секунды появляется непрошенный белый квадрат, и на эту же долю секунды TWebBrowser пропадает.
      Если минимизировать форму в трей и снова открыть (при условии, что TWebBrowser при этом как бы не виден, т.е. после нечетного числа щелчков по кнопке), то функциональность восстанавливается. Иными словами, проблема в отрисовке. Своими силами справиться не смог. Буду признателен за дельный совет. Побороть белый квадрат тоже очень хотелось бы, с ним некрасиво.
      TWebBrowserProblem.zip
    • Автор: Rustam Bikeev
      Суть проблемы следующая: после перехода с одной вкладки на другую в tabcontrol страница не отображается, фактически она переключается но на экране отображается предыдущая вкладка с которой был переход, ровно до той поры пока на что нибудь не клацнешь, нужно либо нажать на кнопку в тулбаре либо открыть multiview. После того как я первый раз с этим столкнулся я так и делал программно открывал и закрывал multiview, но не могу же я так делать постоянно, нужно решить проблему. Для подробности напишу, что есть основной tabcontrol в котором вкладки открываются из multiview, во вкладках есть вложенные tabcontrol-ы, со своими страницами в основном по 2 страницы. 
      Зря я начал делать приложения в делфи... чем дальше в лес тем больше дров.
    • Автор: Alex7wrt
      Добрый день
      Как заставить TMediaPlayer воспроизводить MPG файлы под Windows? MP4 воспроизводит, а mpg не хочет. Установлены кодеки KLite.
      Добавление строки 
      TMediaCodecManager.RegisterMediaCodecClass('.mpg', 'MPEG Video', TMediaType.Video, TWindowsMediaCodec); не помогает. 
    • Автор: x11
      Нет ли у FMX готовой функции для открытия веб-ссылок из приложения?
      А то приходится городить огород с лисапетами и кучей IFDEF.
      В итоге что у меня получилось.
      Для удобства разнес все по разным модулям.
      Модуль для Windiws
      unit uUtilsWindows; interface {$IFDEF MSWINDOWS} uses ShellApi, Variants, Windows, FMX.Types, FMX.Platform.Win; procedure WindowsOpenUrl(const sUrl: string; WindowHandle: TWindowHandle); {$ENDIF} implementation {$IFDEF MSWINDOWS} procedure WindowsOpenUrl(const sUrl: string; WindowHandle: TWindowHandle); begin ShellExecute(FmxHandleToHWND(WindowHandle), 'open', PChar(VarToStr(sURL)), nil, nil, SW_NORMAL); end; {$ENDIF} end.  
      Модуль для Android
      unit uUtilsAndroid; interface {$IFDEF ANDROID} uses FMX.Helpers.Android, Androidapi.JNI.Net, Androidapi.JNI.GraphicsContentViewText, AndroidApi.Helpers; procedure AndroidOpenUrl(const sUrl: string); {$ENDIF} implementation {$IFDEF ANDROID} procedure AndroidOpenUrl(const sUrl: string); Var Uri: Jnet_Uri; OpenLinkIntent: JIntent; begin Uri := StrToJURI(sUrl); OpenLinkIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, Uri);// будем что-то смотреть OpenLinkIntent.addCategory(TJIntent.JavaClass.CATEGORY_BROWSABLE);// смотреть в браузере OpenLinkIntent.setData(Uri);// смотреть эту ссылку SharedActivity.startActivity(OpenLinkIntent);// открываем end; {$ENDIF} end.  
      теперь в основной форме:
      uses ..., ...{$IFDEF ANDROID}, vkbdhelper, uUtilsAndroid{$ENDIF} {$IFDEF MSWINDOWS}, uUtilsWindows {$ENDIF}; ... ... ... procedure TfmEditObject.actOpenUrlExecute(Sender: TObject); begin {$IFDEF ANDROID}AndroidOpenUrl(edMapsCoordUrl.Text);{$ENDIF} {$IFDEF MSWINDOWS}WindowsOpenUrl(edMapsCoordUrl.Text, Self.Handle);{$ENDIF} end;  
      А если добавлять ещё одну платформу, то ещё один модуль понадобится.
      Может есть более правильный вариант, так сказать, дизайна исходного кода?
       
    • Автор: SerhioUser
      Добрый день.
      Как в FMX при перерисовке объекта включить/отключить привязку к вертикальной синхронизации (v-sync) развертки экрана? Есть ли такая возможность в FMX? (В OpenGL и DirectX - есть)
      Например если делаем видео-плеер, то чтобы не было артефактов синхронизация нужна, а если хотим узнать реальный fps - синхронизацию выключаем.
    • Автор: Pax Beach
       
      Библиотека для работы с изображениями находится здесь.
       
      Готовится описание.
       
    • Автор: Вадим Смоленский
      Работаю в Berlin, делаю приложение под Windows. При каждом вызове метода Popup для TPopupMenu, а также при создании и выводе на экран компонента TPopup, в левом верхнем углу формы на долю секунды появляется белый прямоугольник 50х50 пикселей. Нельзя ли как-нибудь это явление подавить?

    • Автор: Макс Войтенко
      var Keyboard: IFMXVirtualKeyboardService; begin if TPlatformServices.Current.SupportsPlatformService( IFMXVirtualKeyboardService, IInterface( Keyboard ) ) then if TVirtualKeyboardState.Visible in Keyboard.GetVirtualKeyBoardState then ShowMessage( 'клавиатура открыта' ) else ShowMessage( 'клавиатура скрыта' ); end; ТАК Я на шел для делфи. Но мне нужно для C++
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу