在现有的graphics应用程序上绘制DirectX / OpenGLgraphics

首先,如果这个问题已经得到解答,让我直接道歉,因为我可能只是在不规则的search条件下search它。

我正在使用DirectX绘制自己的graphics(游戏)的应用程序中绘制2Dgraphics。 我将通过在应用程序中注入一个DLL(我没有任何疑问,我可以做到这一点)并绘制我的graphics。 但是对于DirectX / OpenGL并不擅长,我有几个基本的问题需要问。

1)为了在窗口上绘制graphics,我需要从stream程内存中获取一个预先存在的上下文,对绘图场景进行某种处理?

2)如果应用程序使用DirectX,我可以使用OpenGLgraphics吗?

请让我知道如何我可以做到这一点。 任何细节将不胜感激:-)预先感谢您。

“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版本之间的内部互操作是更好的选择。 我个人可能会使用DirectX9为您自己的渲染代码。 当然,如果你只需要支持一个DirectX版本,就不需要互操作。

奖金:如果你需要生成完整的C ++类的包装,一个快速的肮脏的dll包装,或只是一般的全局函数钩子,请随意使用我创建的这个库: http : //code.google.com/p / hookit /这远远没有经过充分测试的工具,只是我砍了2天,但我发现它超级有用。

请注意,在你的情况下,我建议只使用VTable挂钩,你可能必须硬编码到表中的函数偏移量,但这不太可能改变。

祝你好运 :)

注入DLL的方法确实是正确的方法。 像FRAPS这样的程序使用相同的方法。 我不能告诉你有关Direct3D的方法,但是对于OpenGL,你可以做以下事情:

首先,您必须挂钩opengl32.dll函数wglMakeCurrentglFinishwglSwapBuffers ,以便您的DLL在选择OpenGL上下文时进行绘制。 将他们的呼叫传递给操作系统。 当wglMakeCurrent ,使用GetPixelFormat函数来确定窗口是否被双缓冲。 同样使用glGet… OpenGL调用来找出你正在处理的OpenGL上下文的版本。 如果你有一个传统的OpenGL上下文,你必须使用不同的方法来绘制你的覆盖,而不是现代的OpenGL-3或更新的核心上下文。

如果是双缓冲窗口,请使用wglSwapBuffers上的Hook执行更多的OpenGL绘图操作。 OpenGL只是画笔和画笔(以点,线和三角形的形式)画在画布上。 然后通过wglSawpBuffers调用使所有内容都可见。

在单个缓冲上下文而不是wglSwapBuffers的情况下, wglSwapBuffers的函数是glFinish

使用OpenGL绘制2D就像禁用深度缓冲和使用正交投影矩阵一样简单。 您可以随时更改OpenGL状态。 只要确保在离开钩子之前将所有东西恢复到原始状态。