Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос ImGui DX9 Hook — Проблемы с рендерингом и системным курсором

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
505
Реакции
12
Народ, кто плотно сидит на реверсе классики под DX9, подскажите по базе. Пытаюсь поднять ImGui в одном проекте через классический хук EndScene, но столкнулся с парой неприятных моментов, которые портят весь визуал.

Суть проблемы:
  1. Рендер ImGui окон ведет себя неадекватно — они отрисовываются как будто внутри игровых окон или под ними, ломая нормальный Z-order.
  2. В игре реализована кастомная система мыши. Она не использует стандартный Windows курсор, из-за чего ImGui перекрывает его или вообще неадекватно обрабатывает позицию.

Техническая часть:
Для реализации использую Detours. Хукаю EndScene (индекс 42 в VTable) и Reset (индекс 16). Для инициализации девайса и получения HWND закинул хук на CreateWindowExA.

xzUFkPP.png


Код:
Expand Collapse Copy
#ifndef MDirectx9_H
#define MDirectx9_H
 #include <d3d9.h>
#include <windows.h>
 #include "imgui.h"
 extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND, UINT, WPARAM, LPARAM);
typedef HRESULT(_stdcall* EndScene)(IDirect3DDevice9Ex*);
typedef HRESULT(_stdcall* Reset)(IDirect3DDevice9Ex*, D3DPRESENT_PARAMETERS*);
typedef HWND(WINAPI* CreateWindowExA_t)(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
 class MDirectx9 {
public:
    static MDirectx9& gInst() {
        static MDirectx9 instance;
        return instance;
    }
     MDirectx9(MDirectx9 const&) = delete;
    void operator=(MDirectx9 const&) = delete;
     void MDirectx9DX();
    void UnMDirectx9DX();
 private:
    MDirectx9();
    ~MDirectx9();
     CreateWindowExA_t oCreateWindowExA;
    WNDPROC OWndProc;
    EndScene oEndScene;
    Reset oReset;
     void GetD3D9Device(HWND hWnd);
    void UnMDirectx9Window();
    static HWND WINAPI MDirectx9CreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
    static LRESULT WINAPI MDirectx9WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    static HRESULT APIENTRY MDirectx9EndScene(IDirect3DDevice9Ex* D3D9Device);
    static HRESULT APIENTRY MDirectx9Reset(IDirect3DDevice9Ex* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters);
    void StartImGui(IDirect3DDevice9Ex* pDevice);
};
 #endif

Код:
Expand Collapse Copy
#include "MDirectx9.h"
#include <imgui_impl_dx9.h>
#include <imgui_impl_win32.h>
#include "detours.h"

void MDirectx9::GetD3D9Device(HWND hWnd) {
    IDirect3D9Ex* pD3D9Ex = nullptr;
    IDirect3DDevice9Ex* pDevice = nullptr;
    D3DPRESENT_PARAMETERS d3dpp = {};
    Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D9Ex);
    // ... создание девайса и получение VTable
    void** pVTable = *reinterpret_cast<void***>(pDevice);
    oEndScene = (EndScene)pVTable[42];
    oReset = (Reset)pVTable[16];

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)oEndScene, MDirectx9EndScene);
    DetourAttach(&(PVOID&)oReset, MDirectx9Reset);
    DetourTransactionCommit();
}

Грешу на то, что игра переопределяет стейты рендера прямо перед моим кодом или использует специфический Z-Buffer. Плюс по мышке — как лучше прокинуть инпут в ImGui, если игра клала на стандартные оконные сообщения и рисует свой курсор поверх всего?

Кто сталкивался с похожим поведением рендера в DX9?
 
Назад
Сверху Снизу