【问题标题】:OpenGL/DirectX Hook - Similar to FRAPSOpenGL/DirectX Hook - 类似于 FRAPS
【发布时间】:2012-08-02 09:29:23
【问题描述】:

是否可以像 FRAPS 一样检测哪些应用程序正在使用 OpenGL 或 DirectX? (可能使用某种形式的钩子)?我可能不需要实际绘制到窗口,我只需要知道哪些进程正在执行某种形式的 3D 渲染。

(编辑:) 如果您不熟悉它,FRAPS 是一个可用于在 3D 应用程序上绘制“每秒帧数”计数器的程序。 FRAPS 会自行查找所有正在运行的 3D 应用程序,而无需您指定进程名称。

外部游戏绘制的“每秒帧数”计数器示例:

【问题讨论】:

  • 我的猜测是,您正在寻找的功能隐藏在 Microsoft 的 Windows API 中。我会在那里寻找解决方案。
  • 你可以看看taksi.sourceforge.net。它是 FRAPS 的开源替代品。最重要的是您可以查看资源并找到您需要的内容。
  • 请注意,并非所有使用 DirectX/Direct3d 的应用程序都在进行 3D 渲染。我们使用 D3D 来渲染 H.264 视频。
  • 我认为这对 dx 有帮助 ...Hooking DirectX EndScene from an injected DLL
  • @Deanna +1 感谢 Deanna 的警告,还有其他需要注意的地方。

标签: c# c++ winapi opengl directx


【解决方案1】:

据我了解,FRAPS 使用相对蛮力的方法来确定在哪里开店。该进程从 SetWindowsHookEx 开始,以请求操作系统将 FRAPS 挂钩 DLL 加载到它可以 [和未来进程] 的每个正在运行的进程中。 DLL 的神奇之处在于使用 GetModuleHandleA 运行一组程序测试,以观察它所附加的进程是否已加载任何 OpenGL/DirectX 模块。如果所有调用都返回 NULL,则钩子会尝试将自己从进程中删除。

另一方面,如果进程加载了它们,它会简单地通过移除保护并注入 JMP 挂钩来从该库中挂钩相应的渲染函数。 wglSwapBuffers 通常是 OpenGL 中唯一相关的。当进程调用此函数时,它最终调用 FRAPS 模块,然后 FRAPS 将后台缓冲区捕获到其队列中以编码为 AVI 并呈现其少量指示。然后它处理对 wglSwapBuffers 的原始请求并将执行返回给程序。

至于在 C# 中查询...查看 EasyHook (http://easyhook.codeplex.com/),看看它是否不适合您。我个人对这个 API 没有经验。

【讨论】:

    【解决方案2】:

    您应该查看How to overlay graphics on Windows games? 和链接文章http://www.ring3circus.com/gameprogramming/case-study-fraps/

    第二个链接有一些概念代码应该做实际的钩子部分。它还更详细地说明了我想复制和粘贴到这个答案中的方式和原因。

    【讨论】:

      【解决方案3】:

      可能最简单的方法是检查 OpenGL 和 DirectX 核心库的存在,也可能是添加驱动程序 OGL dll 的好主意(例如 nvogl),这可以通过 EnumProcesses & EnumProcessModulesEx,使用 p/invoke,这至少会为您提供一组可能使用 OGL 或 DX 的起始进程。

      当然,有些应用程序会同时加载这两个 API 并只使用一个,或者只是有条件地使用 GFX API 之一(尽管后者仅使用专用工具等发生),为此,IMO,最好的检查方法是执行某种形式的注入 或像调试器一样附加到进程,然后挂钩Present 用于DX 或wglSwapBuffers 用于OGL。

      您可能会通过枚举 GDI 句柄并寻找 DXGI 或 OGL 渲染上下文来摆脱不使用钩子的问题,我不知道这有多可行。

      【讨论】:

      • 来自 MSDN:“如果这个函数是从运行在 WOW64 上的 32 位应用程序调用的,它只能枚举 32 位进程的模块。如果该进程是 64 位进程,此函数失败,最后一个错误代码是 ERROR_PARTIAL_COPY (299)。”这不是问题,但我需要一些适用于 32/64 位的东西。如果进程是 64 位呢?这是否意味着如果我将应用程序编译为 64 位,它应该适用于 32/64 位?或者只是如果您是 32 位,则无法枚举 64 位应用程序?
      • @David:有 32 位和 64 位版本可用(EnumProcessModulesEx),但是您需要一个 64 位应用程序才能同时获得 32 位和 64 位进程(请参阅备注),并且您仍然需要为 32 位操作系统构建 32 位版本。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多