Вопрос

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

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

Мне интересно, как можно было бы написать такое приложение.

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

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

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

   realDevice.EndScene();
}

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top