Накладывание на 3D полноэкранном приложении

Ответ от DigitalRoss не распознает аббревиатуры, встроенные в CamelCase. Например, он разделит «MyHTMLTricks» на «My H T M L Tricks» вместо «My HTML Tricks».

Вот еще одна опция, основанная на функции AsSpaced() в PmWiki , которая отлично справляется со своими задачами:

"MyHTMLTricks" \
.gsub(/([[:lower:]\\d])([[:upper:]])/, '\1 \2') \
.gsub(/([^-\\d])(\\d[-\\d]*( |$))/,'\1 \2') \
.gsub(/([[:upper:]])([[:upper:]][[:lower:]\\d])/, '\1 \2')

=> "My HTML Tricks"

Другая вещь, которая мне нравится При таком подходе строка остается строкой, а не превращается в массив. Если вам действительно нужен массив, просто добавьте разделение в конце.

"MyHTMLTricks" \
.gsub(/([[:lower:]\\d])([[:upper:]])/, '\1 \2') \
.gsub(/([^-\\d])(\\d[-\\d]*( |$))/,'\1 \2') \
.gsub(/([[:upper:]])([[:upper:]][[:lower:]\\d])/, '\1 \2') \
.split

=> ["My", "HTML", "Tricks"]

Для справки, вот оригинальный код PHP от PmWiki.

function AsSpaced($text) {
    $text = preg_replace("/([[:lower:]\\d])([[:upper:]])/", '$1 $2', $text);
    $text = preg_replace('/([^-\\d])(\\d[-\\d]*( |$))/', '$1 $2', $text);
    return preg_replace("/([[:upper:]])([[:upper:]][[:lower:]\\d])/", '$1 $2', $text);
}

42
задан Lodle 5 December 2010 в 07:35
поделиться

5 ответов

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

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

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

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

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

23
ответ дан 26 November 2019 в 23:58
поделиться

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

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

-1
ответ дан 26 November 2019 в 23:58
поделиться

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

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

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

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

   realDevice.EndScene();
}

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

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

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

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

   realDevice.EndScene();
}

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

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

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

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

   realDevice.EndScene();
}

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

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

наша функция-оболочка для EndScene выглядит так:

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

   realDevice.EndScene();
}

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

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

наша функция-оболочка для EndScene выглядит так:

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

   realDevice.EndScene();
}

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

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

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

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

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

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

21
ответ дан 26 November 2019 в 23:58
поделиться

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

0
ответ дан 26 November 2019 в 23:58
поделиться

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

.
2
ответ дан 26 November 2019 в 23:58
поделиться
Другие вопросы по тегам:

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