Skip to content

Instantly share code, notes, and snippets.

@NPatch
Last active September 29, 2022 17:55
Show Gist options
  • Save NPatch/3c3b7686ad31fc3bcd7ec2566f6ca1af to your computer and use it in GitHub Desktop.
Save NPatch/3c3b7686ad31fc3bcd7ec2566f6ca1af to your computer and use it in GitHub Desktop.
raylib RenderDoc integration

Apart from copying the renderdoc.dll and renderdoc_api.h files from RenderDoc installation path, into the raylib project, we also need to create two files, a cpp and a header. I call them raylib_renderdoc.h and raylib_renderdoc.cpp.

In the header we add:

/**********************************************************************************************
*
*   RenderDoc integration
*
**********************************************************************************************/

#ifndef RAYLIB_RENDERDOC_H
#define RAYLIB_RENDERDOC_H

void* LoadRenderDoc();
void UnloadRenderDoc();

bool RenderDocIsFrameCapturing();
void RenderDocBeginFrameCapture();
void RenderDocEndFrameCapture();
#endif //RAYLIB_RENDERDOC_H

and in the cpp:

#ifndef WIN32_LEAN_AND_MEAN
#	define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include "3rdparty/renderdoc_app.h"
#include "raylib_renderdoc.h"

pRENDERDOC_GetAPI RENDERDOC_GetAPI;
static RENDERDOC_API_1_1_2* rdoc_api = NULL; 
static void* renderdoc_dll = NULL;

void* LoadRenderDoc()
{
	if (NULL != rdoc_api)
	{
		return renderdoc_dll;
	}

	void* renderdoc_dll = (void*)LoadLibraryA("renderdoc.dll");
	if(NULL != renderdoc_dll)
	{
		pRENDERDOC_GetAPI RENDERDOC_GetAPI =
		(pRENDERDOC_GetAPI)GetProcAddress((HMODULE)renderdoc_dll, "RENDERDOC_GetAPI");
		int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api);
		assert(ret == 1);
	}
	else 
	{
		renderdoc_dll = NULL;
	}

	return renderdoc_dll;
}

void UnloadRenderDoc()
{
	if (NULL != renderdoc_dll)
	{
		// Once RenderDoc is loaded there shouldn't be calls
		// to Shutdown or unload RenderDoc DLL.
		// https://github.com/bkaradzic/bgfx/issues/1192
		//
		// rdoc_api->Shutdown();
	}
}

bool RenderDocIsFrameCapturing()
{
	if (NULL != rdoc_api) return rdoc_api->IsFrameCapturing();
	return false;
}

void RenderDocBeginFrameCapture() 
{
	// To start a frame capture, call StartFrameCapture.
	// You can specify NULL, NULL for the device to capture on if you have only one device and
	// either no windows at all or only one window, and it will capture from that device.
	// See the documentation below for a longer explanation
	if (NULL != rdoc_api)
	{
		rdoc_api->StartFrameCapture(NULL, NULL);
	}
}

void RenderDocEndFrameCapture()
{
	// stop the capture
	if (NULL != rdoc_api)
	{
		rdoc_api->EndFrameCapture(NULL, NULL);
	}
}

Then in the main.cpp we have:

#include "raylib_renderdoc.h"
#include <raylib.h>

int main(void)
{
    LoadRenderDoc();
    InitWindow(width, height, "Window Title");
    
    ...

    while (!WindowShouldClose())
    {
        if (RenderDocIsFrameCapturing())
        {
            RenderDocBeginFrameCapture();
        }
        
        BeginDrawing ();
        ...
        EndDrawing();

        if (RenderDocIsFrameCapturing())
        {
            RenderDocEndFrameCapture();
        }
    }

    CloseWindow();
    UnloadRenderDoc();

    return 0;
}

We need to call LoadRenderDoc before any graphics context has been created, which in our case is created through raylib's InitWindow. Within the loop the first thing we do is to query whether a capture has been triggered somehow and call RenderDocBeginFrameCapture, while at the end of the frame we call RenderDocEndFrameCapture as the last thing of the frame in order to capture the full frame. RenderDoc's integration tutorial has a call for UnloadingRenderDoc too, but it seems it's not a best practice. I've added it as a placeholder mostly, but it's not needed according to bkaradzic/bgfx#1192.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment