利用D3D抓取显存数据

本文介绍了Microsoft D3DSDK用于3D建模和GPU运算的特性,详细阐述了D3D渲染的基本流程,并针对渲染后的数据转存提供了两种不同的方法:直接显示和GPU到CPU的拷贝。特别是对于后者,提出了一种更为高效的解决方案。

https://blog.youkuaiyun.com/u011046042/article/details/54427775

microsoft 提供的D3D SDK是用来进行3D建模和利用GPU运算的一组接口的集合,

D3D SDK至少有两个优点:

1、提供了一种3D建模的构架,程序员可以很容易的用这种构架来建模自己的3D模型

2、提供了一种GPU和CPU并行运算的解决方案,,为提供应用程序的性能提供了一种思路

D3D 渲染的基本流程:

----------------------------------------------------------------

1. D3D setting states//设置渲染环境
 
2. g_pd3dDevice->beginscene();
 
3. D3D 管线渲染
 
4. g_pd3dDevice->EndScene();

----------------------------------------------------------------

至此,D3D的渲染过程已经结束,渲染处理的最终数据被存于D3D surface(这是在GPU中开辟的存储区域), 下面可以根据具体的需求来对该surface进行后处理:

1 直接显示:g_pd3dDevice->present();

2 转存到本地磁盘,即GPU to CPU的copy.

这里给出比较常见的一种处理方法:

 
  1. g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackbuffer);

  2.  
  3. pBackbuffer->LockRect(&Source,NULL,0);

  4.  
  5. copy(Dest,Source);

  6.  
  7. pBackbuffer->UnLock();

这种方法缺点很严重,就是由于IPtrD3dsurface lock的内存是位于显卡中,这样在做copy(Dest,Source)的时候,非常缓慢,基本无法实现实时转存的要求。

 

这个方法本人试过了差不多一张1080P的需要使用50ms以上,这个速度超级慢

那microsoft有没有提供更好的解决方案呢?

这个微软利用了另外的方式做的

代码如下:

-----------------------------------------------------------------------------------------

  1. g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackbuffer);

  2. g_pd3dDevice->CreateOffscreenPlainSurface(d3dpp.BackBufferWidth,d3dpp.BackBufferHeight,d3dpp.BackBufferFormat,D3DPOOL_SYSMEM,&g_p2DSurface,NULL);

  3. g_pd3dDevice->GetRenderTargetData(pBackbuffer, g_p2DSurface);

  4. g_p2DSurface->LockRect(&Source,NULL,0);

  5. copy(Dest,Source);

  6. g_p2DSurface->UnLock();

-----------------------------------------------------------------------------------------

GamingAnyWhere用的就是上面的方式。

根据C:\gkoudai\口袋贵金属.exe软件,在GkoudaiDataCollector.py编写使用DirectX钩子技术(D3D11的hook)来自动获口袋贵金属.exe进程和窗口句柄为00050412(Intermediate D3D Window)中的的卖价、买价格和交易量的代码并实时显示在程序面板上的优化以下方案:口袋贵金属.exe 行情数据采集方案(DirectX Hook 实现) 核心思路:通过注入 DLL 挂钩目标进程的 D3D 渲染管线(优先 D3D9,兼容主流桌面应用),拦截绘制调用后解析显存/绘制数据中的行情字段,实时回显到面板。 一、开发环境 - 语言:Python 3.8+(主面板)+ C++ 17(D3D Hook DLL,Python 无法直接实现底层挂钩) - 依赖: - Python: pywin32 (进程/窗口操作)、 PyQt5 (实时面板)、 ctypes (调用 DLL) - C++:DirectX SDK(D3D11 库)、MinHook(挂钩框架)、Detours(备选挂钩库) 二、核心实现步骤(分模块) 1. Python 主程序(GkoudaiDataCollector.py) 负责进程注入、窗口句柄绑定、数据接收和面板显示: 2. C++ D3D Hook DLL(核心逻辑) 负责注入进程、挂钩 D3D 绘制函数(如  EndScene )、解析行情数据: 三、关键说明 1. D3D 版本适配:优先 D3D9(口袋贵金属这类桌面软件常用),若检测到 D3D10/11,需替换对应接口(如  ID3D11DeviceContext::Present )。 2. 数据解析优化:示例中用正则解析显存文本,实际需用 Spy++ 抓取行情控件的坐标/文本格式,或通过 D3D 绘制对象遍历(更精准)。 3. 注入安全:需关闭目标软件的反作弊(若有),否则注入可能被拦截;建议以管理员权限运行采集程序。 4. 稳定性:Hook 可能导致目标软件崩溃,需添加异常捕获和资源释放逻辑。 四、编译与运行步骤 1. 编译 C++ DLL:用 Visual Studio 配置 DirectX SDK 和 MinHook,编译为 32/64 位 DLL(匹配目标软件架构)。 2. 放置 DLL 与 Python 脚本同目录,运行  GkoudaiDataCollector.py (需管理员权限)。 3. 确保口袋贵金属.exe 已启动,且窗口句柄为  0x00050412 (若句柄变化,需在 Python 中添加窗口查找逻辑)。
最新发布
11-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值