一般我们用RenderDoc调试DirectX12时,是在Launch Application中填入启动的EXE和工作目录,然后Launch:

不过有时也想像Unity一样,通过App内置代码来启动RenderDoc,所以我参考了文档In Application API ,改造现有的程序。
首先上RenderDoc安装目录,找到renderdoc.dll,和renderdoc_app.h,注意,如果程序是32位的,要到RenderDoc的X86子目录中找dll。
暂时不考虑其他平台,Windows下,动态加载dll用下面的方法:
//别忘了#include "renderdoc_app.h"
RENDERDOC_API_1_1_2 *rdoc_api = nullptr;//API接口
if (HMODULE mod = LoadLibraryA("renderdoc.dll"))
{
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api);
assert(ret == 1);
}
else
{
std::cout << "RenderDoc Lode Error: " << GetLastError() << std::endl;
}
Renderdoc安装时会在注册表计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{5D6BF029-A6BA-417A-8523-120492B1DCE3}\InprocServer32
中,记录dll路径,Unity和UE都是通过这种方法找到renderdoc.dll的。
这个代码具体放置位置有要求,要在所有图形API调用之前,所以根据DX12龙书,我找到d3dApp.cpp定义的Initialize方法中,正好开头就是下面这种代码:
if(!InitMainWindow())
return false;
//Init renderdoc api
//...
if(!InitDirect3D())
return false;
初始化后定义暂存截帧文件的位置模版,我是这么定义的:
rdoc_api->SetCaptureFilePathTemplate("RenderDocCapture/Capture");
这样会在工作路径/RenderDocCapture下,不断存取Capture_frame1.rdc这样的文件,后面的数字是App运行到当前时间的帧数。
如果不自定义,会存在C盘的某个Temp目录中,这个目录可以通过const char *GetCaptureFilePathTemplate()
得到。
然后用下面的方法截帧:
if (GetKeyDown(Key::C))
{
rdoc_api->TriggerCapture();
if(!rdoc_api->IsTargetControlConnected())
rdoc_api->LaunchReplayUI(1, nullptr);
}
GetKeyDown是我自己定义的按键模块,这个根据自己的项目修改,TriggerCapture触发下一帧截取,IsTargetControlConnected判断是否打开了UI,如果没打开,则调用LaunchReplayUI打开RenderDoc,参数1是指立刻打开UI,参数2的nullptr是命令行参数。
抓到的帧会存在刚刚定义的文件中,当RenderDoc退出时会询问是否保存抓到的帧,如果否,则文件会被删除。
功能大致这样,也可以根据需要简单封装。
网友评论