• 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

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


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

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

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

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

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


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

Войти

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


Войти сейчас

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

    • Автор: Mars M
      Как можно узнать размер видеопамяти под WIN?
      В инете находятся решения через реестр, с помощью DX и другие, но все сообщения старые.
      Может есть какой способ узнать средствами FMX?
       
    • Автор: hryasch
      Добрый день. Существует одна проблема, с которой уже несколько недель не могу справиться. Есть старый код под WinAPI, его нужно переделать под Android через firemonkey. И главная проблема - есть код, который из собственного формата делает HBITMAP из WinAPI. Фактически это структура, где последнее поле - указатели на биты. Это переделать легко, создав собственную копию такой структуры. Но теперь мне нужно перевести ее в TBitmap, и я не очень понимаю как это сделать.
       
    • Автор: Pax Beach
      Привожу пример готового FMX приложения, которое рисует на форме с помощью интерфейса IDirect3DDevice9.
      В примере реализован вызов анонимного метода Present() интерфейса IDirect3DDevice9, имея ссылку на интерфейс и порядковый номер метода.
      Данная реализация пригодится при установке ловушек (Hooks).
       
      Вкратце, суть реализации такая:
      Объявляю процедурный тип нужного метода
      type   TPresent9 = function(pSourceRect, pDestRect: PRect; hDestWindowOverride: HWND; pDirtyRegion: PRgnData): HResult of object; stdcall; Объявляю переменную этого типа
      var   PPresent: TPresent9; begin   ...   IntRefToMethPtr(d3d9Dev, PPresent, 17);   PPresent(nil, nil, DParametrs.D3DPP.hDeviceWindow, nil); Реализую процедуру получения метода интерфейса по номеру
      procedure IntRefToMethPtr(const IntRef; var MethPtr; MethNo: Integer); type   TVtable  = array [0 .. 999] of Pointer;   PVtable  = ^TVtable;   PPVtable = ^PVtable; begin   // QI=0, AddRef=1, Release=2, etc   TMethod(MethPtr).Code := PPVtable(IntRef)^^[MethNo];   TMethod(MethPtr).Data := Pointer(IntRef); end; А теперь получаем метод интерфейса по его порядковому номеру и вызываем его
        IntRefToMethPtr(d3d9Dev, PPresent, 17);   PPresent(nil, nil, DParametrs.D3DPP.hDeviceWindow, nil); Благодарю за оценку этого решения на StackOverflow.
       
      Скачать пример: D3DDemo.zip
    • Автор: msp888
      Если Wi-Fi на телефоне работает в режиме клиента (подключается к внешней точке доступа), то как с ним работать понятно.
      Если же Wi-Fi на телефоне (ОС Android) работает в режиме персональной точки доступа, то как из программы получить свой ip-адрес и другие параметры сети.
      Кто знает, помогите, желательно исходный код на Delphi.
    • Автор: msp888
      Если Wi-Fi на телефоне работает в режиме клиента (подключается к внешней точке доступа), то как с ним работать понятно.
      Если же Wi-Fi на телефоне (ОС Android) работает в режиме персональной точки доступа, то как из программы получить свой ip-адрес и другие параметры сети.
      Кто знает, помогите, желательно исходный код на Delphi.
       
    • Автор: chaplin.u@gmail.com
      Как определить язык системы в Win10 ?
    • Автор: Вадим Смоленский
      В Object Inspector подгружаю ImageList к TTabControl, иду в отдельные TTabItem, выбираю номера для ImageIndex. Иконки выводятся прижатыми к левому краю. Как выровнять их по центру? Текста не предусматриваю, будут только иконки.
    • Автор: Вадим Смоленский
      Если главное окно приложения для Windows выполнено как MDI и занимает почти весь экран, то пункты главного меню концентрируются слева, оставляя справа длинную пустую полосу. Этого пространства жалко, его можно было бы использовать с пользой - как, собственно, и сделано в интерфейсе RAD Studio: после пункта меню Help идет вертикальная полоска из точек, а дальше иконки, боксы поиска и прочее хозяйство. Как это можно сделать?
  • Сейчас на странице   0 пользователей

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