图形编程丨图形绘制基础imgui篇—D3D9 HOOK 创建内部Imgui窗口
作者:小阿栗
Imgui又称为Dear ImGui,它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将Imgui的源码直接加到项目中使用,也可以编译成dll, Imgui使用DX或者OpenGL进行界面渲染,Imgui主要用于游戏行业。
这里我们需要用到两个工具Detours-master(微软的hook库)和imgui-master,主要讲D3D9HOOK。
我们先来创建一个DLL项目。步骤如下:
1.选择新建项目
2.选择Windows桌面->动态链接库(DLL)->D3D9HOOK,点击确定
3.删除framework.h、pch.h以及pch.cpp文件。添加一个dllmain.h头文件
4.dllmain.cpp中要包含头文件添加#include <Windows.h>
5. 配置
5.1 选择属性
5.2 修改运行库以及Spectre缓解,选择应用
5.3 配置include路径,点击“宏”,搜索DX,根据地址找到文件位置,将 $(DXSDK_DIR)include填入,应用
5.4 搜索DX,将$(DXSDK_DIR)Lib填入,搜索$(platformTarget),将$(DXSDK_DIR)lib\$(platformTarget)填入,应用
(图片注释:配置好会自动匹配x86/x64不需要再改)
5.5 新增d3d9.lib,d3dx9.lib这两个依赖项,应用
6. 配置好环境后,编译HOOK库(编译x86和x64两个版本)
X86:找到Visual Studio2017,打开“x86 Native Tools Prompt for VS 2017”,然后cd到路径里nmake进行编译
X64:找到Visual Studio2017,打开“适用于VS 2017的 x64 本机工具命令提示”,然后cd到路径里nmake进行编译
7.打开项目文件夹
8.新建一个目录Detours,将lib.x86、lib.x64和include复制过来(将lib.去掉方便后续识别)
9.新建筛选器,命名Detours
10.在Detours中添加现有项,选定两个头文件detours.h和detver.h
11.配置lib库
11.1选择属性
11.2 编辑包含目录,宏-包含目录-$(ProjectDir)Detours\include,应用
11.3编辑附加库目录,宏-附加库目录-$(ProjectDir)Detours\Lib\$(platformTarget),应用
11.4 编辑附加依赖项,添加detours.lib,应用
11.5 不使用预编译头
12.配置imgui
12.1在D3D9HOOK目录下,新建imgui文件夹,将imgui-master中backends里imgui_impl_dx9.cpp、imgui_impl_dx9.h和imgui_impl_win32.cpp、imgui_impl_win32.h;及主目录下所有.cpp和.h都复制到imgui文件夹中
12.2新建筛选器,命名imgui
12.3在imgui中添加现有项,选定目录下所有文件
12.4.dllmain.h中包含导进来的所有头文件
13.主线程imgui窗口的实现
typedef HRESULT (WINAPI * FuncReset)(IDirect3DDevice9 *pIDirect3DDevice9,D3DPRESENT_PARAMETERS *pPresentationParameters);
typedef HRESULT (WINAPI * FuncEndScene)(IDirect3DDevice9 *pIDirect3DDevice9);
typedef LRESULT(WINAPI * FuncWndProc)(const HWND, UINT, WPARAM, LPARAM);
HWND g_hWnd = NULL;
IDirect3D9 * g_IDirect3D9;
D3DPRESENT_PARAMETERS g_d3dpp;
IDirect3DDevice9* g_pIDirect3DDevice9;
FuncReset OldReset;
FuncEndScene OldEndScene;
FuncWndProc OldWndProc;
DWORD * dwDeviceVirtualTable = NULL;
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI GrkWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, message, wParam, lParam))
{
return TRUE;
}
return CallWindowProc(OldWndProc, hWnd, message, wParam, lParam);
}
VOID StartHook(PVOID * OldFunctionAddr, PVOID NewFunctionAddr)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(OldFunctionAddr, NewFunctionAddr);
DetourTransactionCommit();
}
VOID UnHook(PVOID * OldFunctionAddr, PVOID NewFunctionAddr)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(OldFunctionAddr, NewFunctionAddr);
DetourTransactionCommit();
}
HRESULT WINAPI GrkReset(IDirect3DDevice9 *pIDirect3DDevice9, D3DPRESENT_PARAMETERS *d3dpp)
{
UnHook((PVOID*)(&OldReset), GrkReset);
ImGui_ImplDX9_InvalidateDeviceObjects();
HRESULT bRet = pIDirect3DDevice9->Reset(d3dpp);
ImGui_ImplDX9_CreateDeviceObjects();
StartHook((PVOID*)(&OldReset), GrkReset);
return bRet;
}
HRESULT WINAPI GrkEndScene(IDirect3DDevice9 *pIDirect3DDevice9)
{
UnHook((PVOID*)(&OldEndScene), GrkEndScene);
static bool bFlag = TRUE;
if (bFlag)
{
bFlag = FALSE;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO & io = ImGui::GetIO();
io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
io.WantSaveIniSettings = false;
io.IniFilename = NULL;
ImGui::StyleColorsClassic();
ImFontConfig imfConfig;
imfConfig.FontDataOwnedByAtlas = false;
ImGui_ImplWin32_Init(g_hWnd);
ImGui_ImplDX9_Init(pIDirect3DDevice9);
OldWndProc = (WNDPROC)SetWindowLongPtr(g_hWnd, GWL_WNDPROC, (LONG_PTR)GrkWndProc);
}
HRESULT hRet = pIDirect3DDevice9->EndScene();
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(300, 300));
ImGui::Begin("GrkTools");
ImGui::End();
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
StartHook((PVOID*)(&OldEndScene), GrkEndScene);
return hRet;
}
DWORD WindowThreadCallBack(LPVOID lpBuffer)
{
g_hWnd = FindWindowA("Direct3DWindowClass", NULL);
g_IDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION);
memset(&g_d3dpp, 0, sizeof(g_d3dpp));
g_d3dpp.Windowed = TRUE;
g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
g_d3dpp.EnableAutoDepthStencil = TRUE;
g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
HRESULT hRet = g_IDirect3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_d3dpp, &g_pIDirect3DDevice9);
dwDeviceVirtualTable = (DWORD *)*(DWORD *)g_pIDirect3DDevice9;
OldReset = (FuncReset)dwDeviceVirtualTable[16];
OldEndScene = (FuncEndScene)dwDeviceVirtualTable[42];
StartHook((PVOID*)(&OldReset), GrkReset);
StartHook((PVOID*)(&OldEndScene), GrkEndScene);
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)WindowThreadCallBack, NULL, NULL, NULL);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
14.测试
14.1打开文件夹,把动态链接库D3D9HOOK.dll粘贴到桌面上
14.2打开pick,启动代码注入器,将动态链接库D3D9HOOK.dll进行注入
测试成功:在pick左上角出现窗口<span
这样,就手动创建了一个基础的imgui的框架<span
图形编程丨图形绘制基础imgui篇—D3D9 HOOK 创建内部Imgui窗口相关推荐
- android图形编程,Android图形编程基础
Color //方法1 int color1 = Color.BLUE; //方法2 int color2 = Color.argb(177, 255,255,255); //方法3:在xm l里面定 ...
- linux图形编程,linux图形界面编程基本知识
以前看过这篇文章,不过当时没有博客,现在又一次看到了,记下来: http://hi.baidu.com/skychen1900/blog/item/9c7b94350a5fae1290ef39fb.h ...
- 基础总结篇之八:创建及调用自己的ContentProvider
鍥而捨之,朽木不折:鍥而不捨,金石可鏤.戰國.荀子<勸學篇> 若不能坚持到底,即使是朽木也不能折断:只要坚持不停地用刀刻,就算是金属玉石也可以雕出花饰.用今天的话来说就是:再容易的事情,没 ...
- 开发日记-20190528 关键词 读书笔记《鸟哥的Linux私房菜-基础学习篇》.desktop创建
前言 为你的 Linux 应用创建 .desktop 文件 | Linux 中国 ubuntu下安装AndroidStudio Android 布局平铺展开效果的属性动画 Android开发自动生成的 ...
- java jfm入门_java图形编程
//将布局管理器设置为边框布局 this.setLayout(new BorderLayout()); 边框布局:将组件按东南西北中的方式进行放置.一个方向只能放一个组件,组件大小岁容 jfm.set ...
- 《JavaScript高效图形编程(修订版)》——6.7 画布绘制基础
本节书摘来自异步社区<JavaScript高效图形编程(修订版)>一书中的第6章,第6.7节,作者:[美]Raffaele Cecco著,更多章节内容可以访问云栖社区"异步社区& ...
- bada 2D游戏编程之一——图形绘制
bada 2D游戏编程之一--图形绘制 在2D游戏中,用户见到的画面通常是通过两种方式实现的,一种是图形绘制,就是在屏幕上绘制各种几何图元,如线条和矩形等:还有一种是图像绘制,也就是常说的贴图,游戏中 ...
- EGE基础入门篇(六):基本图形
EGE专栏:EGE专栏 上一篇:EGE基础入门篇(五):窗口简单操作 下一篇:EGE基础入门篇(七):组合图形 一.EGE提供的基本图形 EGE绘制图形相关库函数文档 https://xege.org ...
- 计算机图形编程基础,Windows图形编程基础.ppt
Windows图形编程基础 软件教研室 计算机图形学 第三章 Window图形编程基础 一.设备描述表DC及相关的MFC类 二.图形设备接口(GDI : Graphics device Interfa ...
- windows图形编程基础
windows图形编程基础 2010年08月30日 图形设备接口(GDI,Graphics Device Interface)的主要目标之一是支持在输出设备(如视频显示器.打印机和绘图仪)上的与设备无 ...
最新文章
- OneAPM挂牌新三板,资本市场一片看好!
- SDUT 贪心算法 删数问题
- Red Hat Enterprise Linux 5.4安装GCC
- 【阿里云课程】生成模型之GAN优化目标设计与改进
- php 机数,PHP实现自动刷数和“灌水”机
- 【最贴心】C++字符串转换(stoi;stol;stoul;stoll;stoull;stof;stod;stold)
- mysql 自动备份发送,Centos定时自动备份MySQL数据库并发送至指定邮箱
- read.table与readr::read_delim
- lua和unity如何交互_(XLua)C#与Lua中的交互
- python程序设计教程胡建华_Python程序设计教程
- 7-9 40059 四则运算 (15 分)
- ZMQ == 服务端创建,接受请求的过程
- 【转】Windows下部署Appium教程(Android App自动化测试框架搭建)
- 站在巨人的肩膀上-听课感想
- 人工智能真的具有创造力?
- [转贴]民国记者有多牛:揭黑损人骂街是常事
- C语言知识-关键字stastic
- word文件图标无法显示的问题
- 资金互助社业务学习园地(一) 灵活运用通知储蓄存款
- Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?