Сделайте снимок экрана полноэкранного приложения DirectX

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

устройство-> GetFrontBufferData (0, поверхность); D3DXSaveSurfaceToFile ("имя файла", D3DXIFF_BMP, поверхность, ПУСТОЙ УКАЗАТЕЛЬ, ПУСТОЙ УКАЗАТЕЛЬ);

Там какой-либо путь состоит в том, чтобы добраться, снимок экрана другого полноэкранного приложения DirectX, когда Аэро включен?

14
задан CMircea 25 December 2009 в 22:50
поделиться

5 ответов

Посмотрите на Detours.

Используя Detours, вы можете вызывать такие инструменты, как Direct3DCreate9, IDirect3D9::CreateDevice и IDirect3D9::Present, в котором вы выполняете операции, необходимые для установки, а затем делаете перехват кадра.

.
22
ответ дан 1 December 2019 в 06:59
поделиться

Это фрагмент кода, который я только что использовал в качестве теста, похоже, он работает.

ширина и высота - это размер ЭКРАНА в оконном режиме, а не окон. Так что для меня они установлены на 1280 x 1024, а не на размер окна, которое я визуализирую.

Вам также нужно заменить mEngine-> getDevice () каким-либо способом получения вашего IDirect3DDevice9. Я просто вставил этот код в случайное приложение d3d, которое мне нужно было упростить для тестирования. Но я могу подтвердить, что он захватывает как вывод этого приложения, так и другого приложения d3d, запущенного в то же время.

О, я предположил, что это D3D9, как вы не сказали, я не уверен насчет d3d10 или 11

IDirect3DSurface9* surface;
mEngine->getDevice()->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8,     D3DPOOL_SCRATCH, &surface, NULL);
mEngine->getDevice()->GetFrontBufferData(0, surface);
D3DXSaveSurfaceToFile("c:\\tmp\\output.jpg", D3DXIFF_JPG, surface, NULL, NULL);
surface->Release();
3
ответ дан 1 December 2019 в 06:59
поделиться

Существует программа с открытым исходным кодом, например fraps: taksi , но выглядит устаревшей

2
ответ дан 1 December 2019 в 06:59
поделиться

Здесь обсуждается, как работает Fraps. Это не просто.

http://www.woodmann.com/forum/archive/index.php/t-11023.html

Любой трюк, который пытается прочитать фронтовой буфер с другого устройства DirectX, я подозреваю, может работать только изредка, благодаря удаче неинициализированной памяти.

.
2
ответ дан 1 December 2019 в 06:59
поделиться

Вот пример на C# по подключению объектов IDirect3DDevice9 через инъекцию DLL и подключение функций с помощью EasyHook (как Microsoft Detours). Это похоже на то, как работает FRAPS.

Это позволяет вам захватывать экран в оконном / полноэкранном режиме и использовать задний буфер, что намного быстрее, чем пытаться получить данные из переднего буфера.

Для определения методов объекта IDirect3DDevice9 во время выполнения используется небольшая вспомогательная DLL на C++.

Обновление: для DirectX 10/11 смотрите Захват экрана и наложения для D3D 9, 10 и 11

8
ответ дан 1 December 2019 в 06:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: