В некотором роде.
Вы работаете с двумя различными элементами, один из которых довольно большой, но не очень сложный: перехват D3D.Другое («приостанавливающее» приложение) просто в этом, но вы не совсем хотите, что вы хотите.
Чтобы перехватить D3D, самым простым способом вам нужно перехватить вызов CreateDirect3D9
и верните свой IDirect3D9
, который позже создаст и вернет ваш IDirect3DDevice9
.Это даст вам полный контроль над процессом рендеринга приложения.
Чтобы «приостановить» его, вам нужно дождаться нужного триггера, а затем в своем IDirect3DDevice9::Present
вызвать собственный цикл обработки событий.Это, во всех отношениях, приостановит выполнение кода исходного приложения , но не самого процесса (что позволит обработать ваш код и цикл обработки событий).Это будет иметь некоторые ограничения, и вы, возможно, не сможете использовать события окна / Windows (просто), но это даст вам полный контроль и эффективно приостановит работу исходного приложения.
Обратите внимание, однако, что выдолжен перехватывать и перенаправлять выполнение в каждом потоке , который вы хотите "приостановить", он специфичен только для одного потока, и вы не хотите, чтобы физика или искусственный интеллект прерывались, пока рендер и пользовательский интерфейс приостановлены.
Вам необходимо выполнить наложение, каким бы оно ни было, во время цикла или ловушки IDirect3DDevice9::Present
, а затем при необходимости вызвать метод Present
реального устройства.Если вы хотите запустить несколько кадров вашего оверлея, то несколько раз наберите реальный Present
, прежде чем вернуться из своего Present
.Твик по мере необходимости.Рендеринг здесь выполняется в основном нормально (ознакомьтесь с общими уроками по D3D), но есть одна главная загвоздка: состояние устройства неизвестно и может быть несовместимо, но должно быть «нетронутым» по возвращении.Это делается просто путем кэширования IDirect3DStateBlock9
, созданного на устройстве сразу после его создания.В своем хуке Present
создайте еще один блок состояния с состоянием на входе, восстановите блок чистого состояния, запустите код, а затем восстановите блок состояния входа.Вы можете работать с любыми состояниями, с нуля, без ущерба для состояния устройства (я использую это на практике, отлично работает).
Если вы хотите привести довольно обширные примеры того, как это работает, я быПредлагаем проверить проект Voodoo Shader , который имеет полные D3D8 и 9 хуков, включая все необходимое для оверлеев [/ бесстыдное продвижение собственного проекта].Не стесняйтесь повторно использовать любую концепцию или комментировать дальнейшие вопросы;это, конечно, не все детали, которые могут быть вам полезны.