Рисуем поверх приостановленного полноэкранного приложения Direct3D - PullRequest
0 голосов
/ 14 февраля 2012

В настоящее время я могу подключиться к приложению Direct3D и рисовать пользовательские элементы на его поверхности. Однако я хотел бы приостановить это приложение, а затем нарисовать что-нибудь еще.

Возможно ли это сделать хотя бы отдаленно? Как создание другого моего собственного окна Direct3D поверх этого приложения?

Я нацеливаюсь только на Windows 7, но приложение, которое я хочу нарисовать, использует только DirectX 9.

Проблема в том, что у меня очень мало опыта работы с DirectX в целом.

Ответы [ 2 ]

1 голос
/ 14 февраля 2012

В некотором роде.

Вы работаете с двумя различными элементами, один из которых довольно большой, но не очень сложный: перехват D3D.Другое («приостанавливающее» приложение) просто в этом, но вы не совсем хотите, что вы хотите.

Чтобы перехватить D3D, самым простым способом вам нужно перехватить вызов CreateDirect3D9 и верните свой IDirect3D9, который позже создаст и вернет ваш IDirect3DDevice9.Это даст вам полный контроль над процессом рендеринга приложения.

Чтобы «приостановить» его, вам нужно дождаться нужного триггера, а затем в своем IDirect3DDevice9::Present вызвать собственный цикл обработки событий.Это, во всех отношениях, приостановит выполнение кода исходного приложения , но не самого процесса (что позволит обработать ваш код и цикл обработки событий).Это будет иметь некоторые ограничения, и вы, возможно, не сможете использовать события окна / Windows (просто), но это даст вам полный контроль и эффективно приостановит работу исходного приложения.

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

Вам необходимо выполнить наложение, каким бы оно ни было, во время цикла или ловушки IDirect3DDevice9::Present, а затем при необходимости вызвать метод Present реального устройства.Если вы хотите запустить несколько кадров вашего оверлея, то несколько раз наберите реальный Present, прежде чем вернуться из своего Present.Твик по мере необходимости.Рендеринг здесь выполняется в основном нормально (ознакомьтесь с общими уроками по D3D), но есть одна главная загвоздка: состояние устройства неизвестно и может быть несовместимо, но должно быть «нетронутым» по возвращении.Это делается просто путем кэширования IDirect3DStateBlock9 , созданного на устройстве сразу после его создания.В своем хуке Present создайте еще один блок состояния с состоянием на входе, восстановите блок чистого состояния, запустите код, а затем восстановите блок состояния входа.Вы можете работать с любыми состояниями, с нуля, без ущерба для состояния устройства (я использую это на практике, отлично работает).

Если вы хотите привести довольно обширные примеры того, как это работает, я быПредлагаем проверить проект Voodoo Shader , который имеет полные D3D8 и 9 хуков, включая все необходимое для оверлеев [/ бесстыдное продвижение собственного проекта].Не стесняйтесь повторно использовать любую концепцию или комментировать дальнейшие вопросы;это, конечно, не все детали, которые могут быть вам полезны.

0 голосов
/ 14 февраля 2012

Это очень сложная вещь, которую нужно выполнить, так как это очень большой взлом.Единственные люди, которые видят, что делают такие вещи, - это Steam, TeamSpeak, Xfire, Fraps и несколько хардкорных разработчиков.

В Интернете есть наборы, которые показывают, что вы должны внедрить DLL в пространство памяти.целевого приложения для достижения такого подвига, и такие методы, как прокси DLL.

прокси DLL: http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453

Инъекция: http://www.progamercity.net/d3d/372-c-directx9-0-hooking-via-detours.html

Удачи, этозаймет у вас некоторое время.

...