首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >imgui不使用D3D9钩子进行呈现。

imgui不使用D3D9钩子进行呈现。
EN

Stack Overflow用户
提问于 2022-07-16 22:02:45
回答 1查看 390关注 0票数 0

好的,基本上,我正在尝试将DLL注入到游戏中,用于外部菜单进行调试,并且我的钩子工作得非常好,我可以在屏幕上呈现一个普通的正方形,但是当我试图渲染imgui时,一些游戏DirectX就会死掉,而其他一些游戏根本就不会呈现。这个问题没有任何意义,因为我已经尝试了所有的东西,我已经切换了库,尝试了不同的编译设置,并且刚刚开始做一些随机的操作,但是仍然没有用,我使用的挂钩库是min钩子(我正在使用kiero,但是尝试找出切换到手动获取D3D设备的问题)。

正如我前面说的,我的钩子工作得很好,我可以在屏幕上没有问题地呈现一个正方形,但是我不能呈现imgui (是的,我检查了它是imgui的DX9版本),代码:

代码语言:javascript
运行
复制
long __stdcall EndSceneHook(IDirect3DDevice9* pDevice) // Our hooked endscene
{
    D3DRECT BarRect = { 100, 100, 200, 200 };
    pDevice->Clear(1, &BarRect, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 255, 0), 0.0f, 0);

    if (!EndSceneInit) {
        ImGui::CreateContext();
        ImGuiIO& io = ImGui::GetIO();
        ImGui_ImplWin32_Init(TrackmaniaWindow);
        ImGui_ImplDX9_Init(pDevice);
        
        EndSceneInit = true;
        return OldEndScene(pDevice);
    }
    ImGui_ImplDX9_NewFrame();
    ImGui_ImplWin32_NewFrame();

    ImGui::NewFrame();

    ImGui::ShowDemoWindow();

    ImGui::EndFrame();
    ImGui::Render();

    ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());

    return OldEndScene(pDevice); // Call original ensdcene so the game can draw
}

如果你想说我忘了重新设置钩子,但游戏几乎从不调用它,所以我可能做错了,代码:

代码语言:javascript
运行
复制
long __stdcall ResetHook(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS Parameters) {

    /* Delete imgui to avoid errors */
    ImGui_ImplDX9_Shutdown();
    ImGui_ImplWin32_Shutdown();
    ImGui::DestroyContext();

    /* Check if its actually being called */
    if (!ResetInit) {
        std::cout << "Reset called correctly" << std::endl;
        ResetInit = true;
    }

    /* Return old function */
    return OldReset(pDevice, Parameters);
}

以防万一,我确实搞砸了其中一个函数的挂钩过程,我还将包括我用来实际挂钩它们的代码。

代码语言:javascript
运行
复制
if (MH_CreateHook(vTable[42], EndSceneHook, (void**)&OldEndScene) != MH_OK)
        ThrowError(MinHook_Hook_Creation_Failed);

if (MH_CreateHook(vTable[16],OldReset,(void**)&OldReset)!=MH_OK)
        ThrowError(MinHook_Hook_Creation_Failed);

MH_EnableHook(MH_ALL_HOOKS);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-17 00:52:17

好的,所以我已经解决了这个问题,但是万一其他人需要帮助,我已经找到了一些修复方法来解释为什么会崩溃/不呈现。

首先是EnumWindow(),如果您正在使用EnumWindows()获取目标进程HWND,那么这很可能是您的一个或全部问题,对于内部欺骗,在游戏加载时使用GetForegroundWindow(),或者您可以使用FindWindow(0,"Window Name") (用于外部和内部游戏都需要加载)。

代码语言:javascript
运行
复制
void MainThread(){
    HWND ProcessWindow = 0;
    WaitForProcessToLoad(GameHandle); // This is just an example of waiting for the game to load
    ProcessWindow = GetForegroundWindow(); // We got the HWND
    
    // or
    ProcessWindow = FindWindow(0,"Thing.exe");
}

为了从第二个可能的问题开始,确保您的挂钩函数的替换函数实际上是传递正确的参数(这是如果您的钩子立即崩溃),并确保您正在返回原始函数。

确保您的WndProc函数工作正常(如果您不知道如何运行,那么谷歌DX9挂钩教程并复制+粘贴那里的代码)。

最后一个修复是如何将imgui呈现到屏幕上,如果imgui在第一个补丁之后没有呈现,那么很可能是因为您没有调用所需的函数,这是一个正确生成imgui呈现的示例。

代码语言:javascript
运行
复制
long __stdcall EndSceneHook(IDirect3DDevice9* pDevice) // Our hooked endscene
{
    if (!EndSceneInit) {
        ImGui::CreateContext();
        ImGuiIO& io = ImGui::GetIO();

        ImGui::StyleColorsDark();
        ImGui_ImplWin32_Init(Window);
        ImGui_ImplDX9_Init(pDevice);
        
        EndSceneInit = true;
        return OldEndScene(pDevice);
    }

    ImGui_ImplDX9_NewFrame();
    ImGui_ImplWin32_NewFrame();

    ImGui::NewFrame();

    ImGui::ShowDemoWindow();

    ImGui::EndFrame();
    ImGui::Render();

    ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());

    return OldEndScene(pDevice); // Call original ensdcene so the game can draw
}

如果这些修正都不起作用,那么谷歌错误或者youtube DX9链接教程

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73007919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档