Наложение на полноэкранное приложение 3D


Я хочу отобразить некоторые пользовательские графики поверх 3-го полноэкранного приложения Windows.

Вы играли в какие-нибудь игры Steam? Он имеет исполняемый файл, GameOverlayUI.exe, который позволяет получить доступ к Steam windows из игры. (Элементы графического интерфейса выглядят нарисованными на заказ, я не знаю, является ли это необходимостью; но внутри игры они выглядят точно так же, как и на рабочем столе.) Он даже заходит так далеко, чтобы "приглушить" игровую графику в фоновом режиме.

Мне интересно, как можно было бы пойти о написании такого заявления.

Мне также интересно, насколько широк будет диапазон решений. Можете ли вы использовать один метод для всех приложений OpenGL? Для всех приложений Direct3D минус DirectDraw? Для всех полноэкранных приложений Windows?

Я ищу более "современные" и универсальные решения-наложение командной строки или индексированного цветового приложения 320x240 не является проблемой.

Edit: некоторое уточнение: полноэкранное приложение не мое. Это может быть что угодно. Скорее всего, это будет 3D-игра. Я хочу отобразить, скажем, цифровые часы в правом нижнем углу экрана, поверх игровой графики. Я хотел бы избежать таких трюков, как введение кода или отладка процесса, если это возможно.

5 37

5 ответов:

Ну, вот еще один пример. Xfire-это чат-программа, которая накладывает свой интерфейс на игры, чтобы вы могли получать сообщения во время игры. Они делают это путем редактирования библиотеки DLL d3d/opengl на уровне памяти процесса, например, вводя скачки сборки. Я знаю это, потому что их метод вызывал сбой моего мода, и я действительно видел странный ассемблерный код, который они вводили в d3d9.файл DLL.

Итак, вот как Xfire делает это:

  1. цель процесса игра
  2. Найдите в памяти процесса d3d. dll / opengl.dll
  3. внедрить в процесс библиотеку DLL, содержащую логику пользовательского интерфейса
  4. подключите функции интерфейса к потоку программы, вручную записав переходы сборки в функции d3d / opengl, найденные в памяти процесса

Нет другого мыслимого способа, так как вам нужно захватить графическое устройство, которое принадлежит этой игре. Я готов поспорить, что Steam делает это так же, как Xfire. Так что да, нелегкий путь. чтобы сделать это, если кто-то не создал полезную библиотеку, чтобы сделать все, что вам нужно сделать на низком уровне.

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

Создал Gist с полным кодом здесь

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

Все игры Direct3D9 должны вызывать IDirect3DDevice9::EndScene после того, как экран будет отрисован и готов к рисованию. Так что в теории мы можно поместить пользовательский код внутрь EndScene, который рисует то, что мы хотим по игре. Мы делаем это, создавая класс, который выглядит как IDirect3DDevice9 для игры, но на самом деле это просто оболочка, которая перенаправляет все вызовы функций в реальный класс. Итак, теперь, в нашем пользовательском классе, наша функция-оболочка для EndScene выглядит следующим образом:

HRESULT IDirect3DDevice9::EndScene()
{
   // draw overlays here

   realDevice.EndScene();
}

Затем мы скомпилируем его в библиотеку DLL под названием d3d9.dll, и поместите его в каталог исполняемого файла игры. Реальные файлов d3d9.dll должна быть в папке / system32, но сначала игра смотрит в текущий каталог, а вместо него загружает наш. Как только игра загружается, она использует нашу DLL для создания экземпляра нашего класса-оболочки. И теперь каждый раз, когда вызывается EndScene, наш код выполняется, чтобы нарисовать то, что мы хотим на экране.

Я думаю, что вы можете попробовать тот же принцип с OpenGL. Но чтобы предотвратить подделку, я думаю, что некоторые современные игры пытаются предотвратить это.

Есть проект свободного программного обеспечения его название это такси Текст ссылки. я не уверен, как это приложение переопределяет процесс, потому что я изучаю код, но checkit я думаю, что это хороший проект

Я думал об этом. Для OpenGL я подключал SwapBuffers WGL обходными путями, вытаскивая свои вещи после игры, а затем сам менял буферы.

Я сделал оверлеи с обоими видовыми экранами DirectX и WPF (то же самое, на самом деле), используя оверлей, чтобы нарисовать некоторые хорошие 2D GDI+ вещи поверх 3D визуализации.

Мне удалось использовать панель поверх" реальной " визуализации, установив цвет прозрачным, за исключением битов, которые я хотел наложить. Работал довольно хорошо, но это было немного больно, передавая щелчок, перетаскивание и другие события через слой "рисование" к 3D-элементу управления.