用PerfHUD来调试商业游戏

来源:互联网 发布:k means聚类算法电商 编辑:程序博客网 时间:2024/06/05 17:44

来源:http://blog.csdn.net/RAINini/archive/2008/10/28/3162112.aspx

 

         PerfHUD是NV一个非常好用的工具,可以用于查看游戏的运行效率,找出瓶颈,也可以用于分析游戏渲染流程,看每个DPC的渲染操作,包括渲染状态,所用的shader等,非常强大。

         PerfHUD正常的用途是用于调试自己写的程序,但是有时候看到别的游戏一些好的效果,也想了解是怎么实现的,这时,PerfHUD也可以派上用场。

         要使用PerfHUD,就要对自己的D3D程序进行修改,在CreateDevice时,Adapter这个参数不要选用D3DADAPTER_DEFAULT,而是枚举所有的Adapter,选中Description中带有“PerfHUD”字符串的那个Adapter,一般来说,对于单显卡的机器,通常都是第二个Adapter,我没有多显卡,所以不知道多显卡情况下是不是往后顺移。

         同时,DeviceType不要选D3DDEVTYPE_HAL,而要选D3DDEVTYPE_REF。

         通过这样来创建Device的程序,才能用PerfHUD来挂接并分析,更详细的创建过程,查看PerfHUD的帮助文档吧。

         由上可以看出,对于别人的程序,Device都不是自己创建的,似乎不能用PerfHUD来分析了,但经过对要分析的程序做一些手脚后,也是可以的,以下拿《魔兽世界》来举例。

         首先,打开VC(我用的2005,2003大同小异,VC6没试过),确保Options里的这个选项是选中的,

 

 

 

         只有选中它了,才能用函数名称来作为断点断住DLL里的函数。

         然后用VC来把要分析的游戏的exe执行起来,点击VC的File->Open ->Project,在弹出的对话框中选中要分析的exe文件,如下图:

 

 

 

         把文件加进来后,在Solution下可以看到该文件,右键选Debug->Step into new instance,启动程序,然后下一个函数断点,点击菜单中的Debug->New Breakpoint->Break at function,在弹出的对话框中写入Direct3DCreate9,如下图:

 

 

 

         点OK后,就下好断点了,如果一个程序用的D3D,那么应该会在这个断点断住,要靠它来获取IDirect3D9这个interface的指针。

         做完以上步骤后,按F5让程序继续运行,应该会断在刚才那个函数断点,如下图:

 

 

 

         这时按Shift+F11,退出这个函数体,如果创建成功,应该就获取到了IDirect3D9,因为这个函数的返回值就是IDirect3D9的指针,只需看eax这个寄存器的值,就能找到这个指针,因为eax是存放函数返回值。

         在watch窗口里打入eax,当前eax的值是0x0016CFC0。

         打开一个memory窗口,把0x0016CFC0这个值敲进去,然后点在memory窗口下点右键,用4-byte Integer来查看内存,把0x0016CFC0这块内存的前4个字节的值拷贝下来,我机器上显示的值是4b641a98,为什么要拷贝这个值呢,因为一个带虚拟函数的类的指针所指向的地址,最开头的4个字节就是虚函数表的指针,通过它能找到各个虚函数的函数地址。

         在memory窗口里把这个值加上h后敲进去,同样用4-byte Integer来查看,得到就是IDirect3D9这个接口的各个函数的入口地址,真正要找的就是CreateDevice这个函数的地址,这时,打开你装的D3D SDK的d3d.h,搜索IDirect3D9这个接口的声明,应该会找到如下代码:

 

复制代码