在现有的图形应用程序上绘制DirectX/OpenGL图形

4
首先,如果这个问题已经被解决了,我想提前道歉,因为我可能使用了不规则的搜索词。
我想在一个使用DirectX绘制自己图形(游戏)的应用程序中绘制2D图形。我将通过将DLL注入到应用程序中来实现这一点(这部分我没有问题,我可以做到),并且绘制我的图像。但是我对DirectX / OpenGL不太熟悉,有一些基本问题要问。
1)为了在该窗口上绘制图形,我是否需要从进程内存获取预先存在的上下文,某种绘图场景的句柄?
2)如果应用程序使用DirectX,我能否在其上使用OpenGL图形?
请让我知道如何处理这个问题。任何细节将不胜感激:-) 提前谢谢。
2个回答

3
您注入 DLL 的方法是正确的,像 FRAPS 这样的程序也使用相同的方法。我无法告诉您关于 Direct3D 的方法,但对于 OpenGL,您需要执行以下操作:
首先,必须挂钩到 `opengl32.dll` 的函数 `wglMakeCurrent`、`glFinish` 和 `wglSwapBuffers` ,以便您的 DLL 注意到何时选择了用于绘图的 OpenGL 上下文。将它们的调用传递给操作系统。当调用 `wglMakeCurrent` 时,使用函数 `GetPixelFormat` 查找窗口是否为双缓冲。还要使用 `glGet...` OpenGL 调用查找你正在处理的 OpenGL 上下文的版本。如果您有一个传统的 OpenGL 上下文,您必须使用不同的方法来绘制叠加层,而对于现代的 OpenGL-3 或更高版本核心上下文,则必须使用其他方法。
对于双缓冲窗口,请使用您的 Hook 在 `wglSwapBuffers` 上执行进一步的 OpenGL 绘制操作。OpenGL 只是在画布上绘制点、线和三角形等笔刷。然后传递 `wglSawpBuffers` 调用,以使所有内容可见。
对于单缓冲上下文,而不是 `wglSwapBuffers`,要挂钩的函数是 `glFinish`。
使用 OpenGL 绘制 2D 图像只需禁用深度缓冲并使用正交投影矩阵即可。您可以随时更改 OpenGL 状态,只需确保在离开钩子之前将所有内容还原为其原始状态。

1

“1)为了在该窗口上绘制图形,我需要从进程内存中获取一个预先存在的上下文,一种绘画场景的句柄吗?”

是的,您需要确保您的钩子捕获重要的上下文创建函数。 例如,在d3d中的所有CreateDevice变体都对您很有兴趣。

您没有提到您使用的DirectX版本,但这些版本之间存在一些差异。 例如,在DirectX 9中,您主要感兴趣的功能有: 1. 创建/返回IDirect3DSwapChain9对象 2. 创建/返回IDirect3DDevice9,IDirect3DDevice9Ex对象

在DirectX的新版本中,它们的代码被分成了(大多数)Device、DeviceContext和DXGI。 如果您正在进行“特定任务”,请分享您正在处理的DirectX版本。

除了捕获所有必需的对象以允许您自己进行渲染之外,您还想捕获所有演示事件(GL中的“SwapBuffers”,DX中的“Present”), 因为这是您想要添加覆盖的时间。

看起来你正在尝试在DX应用程序上渲染叠加层,我要警告你制作一个真正通用的解决方案(适用于所有游戏)并不容易,这主要是因为需要支持不同的DX版本以及创建众多的方式。

如果你只关注特定的游戏/应用程序,那当然就容易得多了。

"2. 如果应用程序使用DirectX,我能够在其上使用OpenGL图形吗?"

首先,是可以的。你需要搜索的术语是OpenGL DirectX互操作性(简称Interop)。

以下是一个示例: https://sites.google.com/site/snippetsanddriblits/OpenglDxInterop 我不知道他们使用的扩展是否仅适用于nVidia设备,请自行确认。

还有一件事情,你需要一个非常好的动机才能这样做,通常我会选择使用DX进行钩子和渲染。 我认为不同DX版本之间的内部Interop是更好的选择。 对于自己的渲染代码,我个人可能会选择DirectX9。 当然,如果你只需要支持单个DirectX版本,则不需要Interop。

奖励: 如果您需要生成C++类的完整包装器、快速而简单的dll包装器或者一般的全局函数钩子,可以使用我创建的这个库: http://code.google.com/p/hookit/ 它远未经过充分测试,只是我在两天内编写的东西,但我发现它非常有用。

请注意,在您的情况下,我建议使用VTable hooking,您可能需要将函数偏移量硬编码到表中,但这不太可能改变。

祝你好运 :)


我正在针对DirectX9进行开发,对于hooking等方面没有问题,我有自己创建的引擎,并且我正在针对特定游戏进行开发。我认为现在我最缺乏的是关于DirectX9的快速入门课程。我感觉现在我是自己的限制,因为我已经从这两个回复中得到了我需要的答案。 你是否有任何DirectX9链接可以帮助我快速入门绘制我的覆盖层? - Dimitris Preketes
1
代码示例网站是一个不错的网站 http://www.codesampler.com/dx9src.htmDX SDK也提供了一些示例,但它们通常包含大量无关的代码。像gamedev.net这样的网站充满了面向初学者/高级用户的论坛。能够完全独立编写高级图形代码通常需要多年的经验,但这确实很有回报!如果您更具体地说明您想在游戏之上做什么类型的图形,请告诉我,也许我可以提供更多帮助。 - ZeDuS
基本上我不想做任何太高级的东西。我只想在屏幕中央显示一个静态图像几秒钟,有可能在其上动态添加文本。 - Dimitris Preketes
静态图像显示在中央,有可能在其上动态添加文本。在DXSDK中有一个名为“Text3D”的示例(也适用于2D文本),它展示了一种只使用字体渲染文本的可能方法。 - ZeDuS
另外,我相信我已经完全回答了你的两个原始问题。如果你也这么认为,可以自由地接受这个答案 ;) - ZeDuS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接