Direct3D9 EndScene 挂钩渲染
我正在使用 vTable 挂钩挂钩 Directx9 游戏。到目前为止,我已经能够成功挂钩“Present”和“EndScene”(当然还有 CreateDevice 和 Direct3dCreate9),但是 - 这是一个问题 - 一旦我尝试实际绘制任何内容(例如,文本) ),我的 Present 钩子不再被击中。 (这可能是内置的安全例程......我不完全确定)。
例如...以下代码有效
HRESULT APIENTRY hook_EndScene(IDirect3DDevice9* pInterface){
pInterface->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
return orig_EndScene(pInterface);
}
导致屏幕永久显示白色。 但是,尝试渲染文本(在 CreateDevice 挂钩中创建的字体,使用返回的 IDirect3DDevice9 指针 - 我已确保使用 __asm Pushad 和 popad 来恢复寄存器)或精灵,导致 EndScene 挂钩根本不再被命中。
我想知道是否需要任何特殊代码来确保 EndScene 挂钩工作...以及为什么我可以清除屏幕,但一旦我希望向其呈现额外的内容...挂钩就不再工作(不再命中断点)。文本确实渲染成功...一瞬间,然后被 Bink 视频替换...在这种情况下挂钩不再起作用。
我完全一无所知...并且希望为一些更有经验的 DirectX 编码人员提供一些帮助。谢谢。
编辑这是我的 CreateDevice Hook 以防万一,
HRESULT APIENTRY hook_CreateDevice(IDirect3D9* pInterface, UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface){
HRESULT ret = orig_CreateDevice(pInterface, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
__asm pushad
IDirect3DDevice9* d3ddev = *ppReturnedDeviceInterface;
D3DXCreateFont(d3ddev, 30, 0, FW_NORMAL,1, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE, "Arial", &lpfont);
//We have located the d3ddevice pointer. Now we can hook it!
DWORD* vTable = (DWORD*)*((DWORD*)d3ddev);
HookVTableFunc(vTable, (void*)&hook_EndScene, (void*)&orig_EndScene, 42);
__asm popad
return ret;
}
并且 EndScene 钩子不起作用(完全破坏钩子):
LPD3DXFONT lpfont;
HRESULT APIENTRY hook_EndScene(IDirect3DDevice9* pInterface){
static RECT textbox; SetRect(&textbox, 0, 0, 640, 480);
lpfont->DrawTextA(NULL, "Testing", 22, &textbox, 0, D3DCOLOR_ARGB(0,255,255,255));
return orig_EndScene(pInterface);
}
I am hooking a Directx9 Game using vTable hooks. So far, I have been able to successfully hook both "Present" and "EndScene" (and of course, CreateDevice and Direct3dCreate9), however - and here is the catch - as soon as I attempt to actually draw anything (for example, text), my Present hook is no longer being hit. (This may be a built in security routine... I'm not totally sure).
For example... The following code works
HRESULT APIENTRY hook_EndScene(IDirect3DDevice9* pInterface){
pInterface->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
return orig_EndScene(pInterface);
}
Resulting in the screen permanently displaying a white color.
However, attempting to render text (font created in the CreateDevice hook, using the returned IDirect3DDevice9 pointer - I have made sure to use __asm pushad and popad to restore registers), or a sprite, results in the EndScene hook no longer being hit at all.
I am wondering if there is any special code required to ensure the EndScene hook works... And why I can clear the screen, but as soon as I wish to render extra content to it... the hook no longer works (No longer hits breakpoints). The text DOES render successfully... for a split second, before being replaced by a Bink video... the hook no longer working in this case.
I am completely clueless... and would appreciate some help for some more experienced DirectX coders. Thanks.
EDIT Here is my CreateDevice Hook just in case
HRESULT APIENTRY hook_CreateDevice(IDirect3D9* pInterface, UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface){
HRESULT ret = orig_CreateDevice(pInterface, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
__asm pushad
IDirect3DDevice9* d3ddev = *ppReturnedDeviceInterface;
D3DXCreateFont(d3ddev, 30, 0, FW_NORMAL,1, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE, "Arial", &lpfont);
//We have located the d3ddevice pointer. Now we can hook it!
DWORD* vTable = (DWORD*)*((DWORD*)d3ddev);
HookVTableFunc(vTable, (void*)&hook_EndScene, (void*)&orig_EndScene, 42);
__asm popad
return ret;
}
And the EndScene hook that does not work (breaks the hook entirely):
LPD3DXFONT lpfont;
HRESULT APIENTRY hook_EndScene(IDirect3DDevice9* pInterface){
static RECT textbox; SetRect(&textbox, 0, 0, 640, 480);
lpfont->DrawTextA(NULL, "Testing", 22, &textbox, 0, D3DCOLOR_ARGB(0,255,255,255));
return orig_EndScene(pInterface);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它对我有用,我认为问题是你把 alpha 设置为 0?
我的挂钩代码生成这些变量
函数指针类型
指向原始函数的函数指针
指向替换函数的函数指针
相对于 EndScene 的 VTable
使用这些命名方案,其余的函数也可以由宏自动生成。
实际示例/挂钩(适用于 32 和 64 位):
我为此工作创建了一些辅助函数/宏:
It works for me, I think the problem is you left the alpha on 0?.
My hooking code generates these variables
Function Pointer Type
Function Pointer to orginal Function
Function Pointer to replacement Function
VTable relative of EndScene
Using these naming scheme the rest of the functions can also be generated automatically by the macros.
The actual sample/hook (works for 32 and 64 bits):
I created some helper functions/macros for this job: