覆盖3D全屏应用程序

我想在第三方全屏Windows应用程序的顶部显示一些自定义graphics。

你玩过任何Steam游戏吗? 它有一个可执行的GameOverlayUI.exe,可以让你从游戏中访问Steam窗口。 (GUI元素看起来是自定义的,我不知道这是否是必需的,但是在桌面上它们看起来和游戏完全一样)。它甚至可以使游戏graphics变暗的背景。

我想知道如何去写这样的应用程序。

我也想知道解决scheme的范围有多广泛。 你可以使用所有的OpenGL应用程序的一种方法? 对于所有Direct3D减去DirectDraw应用程序? 对于所有全屏Windows应用程序?

我正在寻找更多的“现代”和通用的解决scheme – 覆盖命令提示符或320×240索引的颜色应用程序不是一个问题。

编辑:一些澄清:全屏应用程序不是我的。 它可以是任何东西。 最有可能的,这将是一个3D游戏。 我想在屏幕的右下angular显示数字时钟,在游戏graphics的顶部。 如果可能,我想避免诸如注入代码或debugging过程等技巧。

那么,这是另一个例子。 Xfire是一个聊天程序,将其界面覆盖到游戏中,以便您可以在玩游戏时接收消息。 他们这样做的方式是在进程内存级别编辑d3d / opengl DLL,如注入程序集跳转。 我知道这是因为他们的方法导致我的国防部崩溃,我真的看到他们注入到d3d9.dll奇怪的汇编代码。

所以这里是Xfire如何做到这一点:

  1. 瞄准游戏的过程
  2. searchd3d.dll / opengl.dll的进程内存
  3. 在进程中注入一个包含自定义接口逻辑的DLL
  4. 通过在程序存储器中find的d3d / opengl函数中手动写入程序集跳转,将接口的函数连接到程序stream程

没有其他可行的方法,因为你需要劫持属于那个游戏的graphics设备。 我敢打赌,Steam和Xfire一样。 所以是的,除非有人创造了一个有用的图书馆去做你需要做的所有事情,否则没有简单的办法做到这一点。

你也问过在你的覆盖下调暗游戏graphics。 这只是一个简单的DrawPrimitive调用来在屏幕上绘制一个填充的透明矩形。

这里用完整的代码创build了一个Gist

这是一个非常深奥的艺术,有几种方法可以做到这一点。 我更喜欢所谓的Direct3D包装 。 我已经做了这么多年了,但是我曾经做过一次游戏。 我可能已经遗漏了一些细节,但我只是希望说明这个想法。

所有Direct3D9游戏都需要在屏幕渲染并准备绘制之后调用IDirect3DDevice9 :: EndScene 。 所以在理论上,我们可以把自定义的代码放在EndScene里面,这样就可以在游戏中绘制我们想要的东西。 我们通过创build一个类似于IDirect3DDevice9的类来实现这一点,但是它实际上只是一个将所有函数调用转换为真实类的包装器。 所以现在,在我们的自定义类中, EndScene的包装函数看起来像这样:

 HRESULT IDirect3DDevice9::EndScene() { // draw overlays here realDevice.EndScene(); } 

然后我们把它编译成一个名为d3d9.dll的DLL,并把它放到游戏可执行文件的目录中。 真正的d3d9.dll应该位于/ system32文件夹中,但游戏首先在当前目录中查找,然后加载我们的。 一旦游戏加载,它使用我们的DLL来创build我们的包装类的一个实例。 现在每调用一次EndScene ,我们的代码就会被执行,将我们想要的东西绘制到屏幕上。

我认为你可以尝试与OpenGL相同的原则。 但为了防止篡改,我认为一些现代游戏试图阻止这一点。

therers一个自由软件项目的名字是taksi 链接文本 。 我不知道这个应用程序如何覆盖过程,因为我正在检查代码,但检查我认为这是一个很好的项目

我一直在想这个。 对于OpenGL,我将钩住WGL的SwapBuffers,在游戏后绘制我的东西,然后自己交换缓冲区。

我已经使用DirectX和WPF视口(同样的东西,实际上)覆盖,使用覆盖绘制一些不错的2D GDI +的东西在3D可视化之上。

我通过在“实际”可视化之上使用面板进行pipe理,将颜色设置为透明,除了要覆盖的位之外。 工作得很好,但是通过点击,拖动和其他事件,通过“绘图”层将其传递给3D控件是一件痛苦的事情。