{"id":16088722,"url":"https://github.com/dougbinks/rccpp_dx11_example","last_synced_at":"2025-03-16T08:32:21.196Z","repository":{"id":95098717,"uuid":"231243980","full_name":"dougbinks/RCCpp_DX11_Example","owner":"dougbinks","description":"Runtime Compiled C++ example based on the Dear ImGui DirectX11 Example","archived":false,"fork":false,"pushed_at":"2024-05-28T17:55:55.000Z","size":82,"stargazers_count":44,"open_issues_count":0,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-16T00:11:19.606Z","etag":null,"topics":["c-plus-plus","compile","dear-imgui","directx11","live-coding","runtimecompiledcplusplus","tutorial","visual-studio"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dougbinks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"dougbinks","patreon":"enkisoftware","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":"https://www.enkisoftware.com/avoyd"}},"created_at":"2020-01-01T17:24:13.000Z","updated_at":"2025-03-07T23:13:18.000Z","dependencies_parsed_at":"2023-05-26T16:00:35.474Z","dependency_job_id":null,"html_url":"https://github.com/dougbinks/RCCpp_DX11_Example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougbinks%2FRCCpp_DX11_Example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougbinks%2FRCCpp_DX11_Example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougbinks%2FRCCpp_DX11_Example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougbinks%2FRCCpp_DX11_Example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dougbinks","download_url":"https://codeload.github.com/dougbinks/RCCpp_DX11_Example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243846976,"owners_count":20357294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","compile","dear-imgui","directx11","live-coding","runtimecompiledcplusplus","tutorial","visual-studio"],"created_at":"2024-10-09T13:44:22.026Z","updated_at":"2025-03-16T08:32:20.893Z","avatar_url":"https://github.com/dougbinks.png","language":"C++","readme":"Support development of RCC++ through [GitHub Sponsors](https://github.com/sponsors/dougbinks) or [Patreon](https://www.patreon.com/enkisoftware)\n\n[\u003cimg src=\"https://img.shields.io/static/v1?logo=github\u0026label=Github\u0026message=Sponsor\u0026color=#ea4aaa\" width=\"200\"/\u003e](https://github.com/sponsors/dougbinks)    [\u003cimg src=\"https://c5.patreon.com/external/logo/become_a_patron_button@2x.png\" alt=\"Become a Patron\" width=\"150\"/\u003e](https://www.patreon.com/enkisoftware)\n\n# RuntimeCompiledCPlusPlus Dear ImGui and DirectX11 Tutorial\nYou can also find this tutorial in the devlog post [Runtime Compiled C++ Dear ImGui and DirectX11 Tutorial](https://www.enkisoftware.com/devlogpost-20200202-1-Runtime-Compiled-C++-Dear-ImGui-and-DirectX11-Tutorial).\n\nThis tutorial takes a small DirectX11 project, the Dear ImGui Example, and adds Runtime Compiled C++ to it. This enables us to edit the code at runtime and see the results live, without recompiling and restarting the project. \n\nThis is a Windows only project but both Dear ImGui and Runtime Compiled C++ are cross platform. Thanks to Jonathan Bleeker and [Milviz](https://milviz.com/flight/index.php) for funding this tutorial.\n\nRuntime-Compiled C++ (RCC++) is a way to reliably make major changes to C++ code at runtime and see the results immediately. It's aimed at games development but could be useful in any industry where turnaround times are a bottleneck.\n\nhttps://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus\n\nRCC++ is primarily designed to shorten iteration times in development - developers can build their project, run it, make changes during runtime and see the results in a few seconds.\n\n![Short teaser of Runtime Compiled C++ Dear ImGui and DirectX11 Example](https://github.com/dougbinks/images/blob/master/RCCpp_DX11_Example_ShortTeaser.gif)\n\n## Getting the tutorial code\nThe complete finished code for this tutorial, including Dear ImGui and RuntimeCompiledCPlusPlus can be found on [GitHub as RCCpp_DX11_Example](https://github.com/dougbinks/RCCpp_DX11_Example). Each chapter of the tutorial has a branch with the changes up to that point, so the implementation can be followed step by step.\n\nA similar cross platform example using [Dear ImGui](https://github.com/ocornut/imgui) with [GLFW](https://www.glfw.org/) and OpenGL is available on [GitHub as RCCpp-DearImGui-GLFW-example](https://github.com/juliettef/RCCpp-DearImGui-GLFW-example).\n\n[RCC++ Dear ImGui and DirectX Tutorial Video Part 1: Introduction and Getting the Code](https://www.youtube.com/watch?v=dSCp4wNpcH4\u0026list=PLRp7HE6uWI1m6tu_-vNUY-N_gnXT17WHQ\u0026index=1)\n\nThe easiest way to get hold of the example code if you have git is to run the following command using a shell you can run git:\n\n```\ngit clone --recursive https://github.com/dougbinks/RCCpp_DX11_Example\n```\n\nYou can download git for windows from https://git-scm.com/download/win, and use the right click menu in Windows File Explorer to \"Git Bash here\" and then run git commands.\n\nThis will create the directory RCCpp_DX11_Example and get the latest source code, using the ```--recursive``` option to download the Dear ImGui and RuntimeCompiledCPlusPlus code, which have been included in the tutorial repository as submodules. If you want to run further git commands from the command line you'll need to cd into the directory:\n\n```\ncd RCCpp_DX11_Example\n```\n\nAlternatively you can use a git GUI program to get the code, most of these will automatically download the git submodules.\n\nIf you download the code via the \"Download ZIP\" approach, you'll also need to download RuntimeCompiledCPlusPlus and Dear ImGui into the RuntimeCompiledCPlusPlus and  imgui folders. The correct versions can be found by clicking on the RuntimeCompiledCPlusPlus and imgui folders you see on the front page of the [RCCpp_DX11_Example GitHub page](https://github.com/dougbinks/RCCpp_DX11_Example) as below.\n\nThe project is split into [several branches](https://github.com/dougbinks/RCCpp_DX11_Example/branches/all) to allow you to navigate to important points in its development, notably:\n\n1. Project_Setup - [branch](https://github.com/dougbinks/RCCpp_DX11_Example/tree/Project_Setup) - [.zip](https://github.com/dougbinks/RCCpp_DX11_Example/archive/Project_Setup.zip)\n1. Working_RCC++ - [branch](https://github.com/dougbinks/RCCpp_DX11_Example/tree/Working_RCC++) - [.zip](https://github.com/dougbinks/RCCpp_DX11_Example/archive/Working_RCC++.zip)\n1. RCC++_With_ImGui - [branch](https://github.com/dougbinks/RCCpp_DX11_Example/tree/RCC++_With_ImGui) - [.zip](https://github.com/dougbinks/RCCpp_DX11_Example/archive/RCC++_With_ImGui.zip)\n1. RCC++_With_D3D - [branch](https://github.com/dougbinks/RCCpp_DX11_Example/tree/RCC++_With_D3D) - [.zip](https://github.com/dougbinks/RCCpp_DX11_Example/archive/RCC++_With_D3D.zip)\n1. RCC++_With_D3D_Library - [branch](https://github.com/dougbinks/RCCpp_DX11_Example/tree/RCC++_With_D3D_Library) - [.zip](https://github.com/dougbinks/RCCpp_DX11_Example/archive/RCC++_With_D3D_Library.zip)\n1. master (latest code). - [branch](https://github.com/dougbinks/RCCpp_DX11_Example/tree/master) - [.zip](https://github.com/dougbinks/RCCpp_DX11_Example/archive/master.zip)\n\nWith git the following command can be used to change branches (using the RCC++_With_ImGui branch as an example):\n```\ngit checkout RCC++_With_ImGui\n```\n\n## Initial Project Setup with Visual Studio\nIn this section I'm going to give an overview of the steps needed to setup a Visual Studio solution and projects with the files needed for RCC++, using the Dear ImGui example app as a basis.\n\nBoth Dear ImGui and RCC++ are on GitHub, and both provide Visual Studio project files. However, the project files need to be updated to match the version of VS in use. A simple approach to the project setup would be to fork each repo, but for this tutorial we copy the project files into another folder so we can keep the source repos clean of any changes.\n\nThis is somewhat tedious so I recommend you skip to the next chapter - if you're following along with the code you can grab the starting project on branch Project_Setup in your git clone using:\n```\ngit checkout Project_Setup\n```\n\n[RCC++ Dear ImGui and DirectX Tutorial Video Part 2: Project Setup](https://www.youtube.com/watch?v=bwGpNbJeg5s\u0026list=PLRp7HE6uWI1m6tu_-vNUY-N_gnXT17WHQ\u0026index=2)\n\nFor detailed steps see the [repo commit history on branch  Project_Setup](https://github.com/dougbinks/RCCpp_DX11_Example/commits/Project_Setup).\n\nThe principal steps are to create a new Visual Studio solution with the ```example_win32_directx11``` Dear ImGui example and the RCC++ libraries. RCC++ consists of two libraries:\n- the RuntimeCompiler which handles compiling; and \n- RuntimeObjectSystem which handles automatically compiling the appropriate files (this will be detailed later) whenever a file is changed.\n\nA useful tip is that Visual Studio projects consist of two files - the .vcxproj and .vcxproj.filters file. The other VS files aren't required to setup a project. In the following instructions, and in the example repository, we copy the project files we need rather than create them from scratch and add the required code, though for RCC++ the later approach is fairly simple.\n\nThe setup consists of the following steps:\n1. Set up a new repo and add RCC++ and Dear ImGui as submodules. If git isn't being used this step would be to create an empty directory for the project and download RCC++ and Dear ImGui into separate sub-directories\n1. Test the example code for both works. This requires the projects to be updated to an installed version of Visual Studio which we're prompted for on opening the solution for the first time. Discard the project changes once tested\n1. Create an empty Visual Studio Win32 Console project, and delete the project as we'll be making our own\n1. Copy the example code from ```imgui\\examples\\example_win32_directx11``` root folder; ```main.cpp```, ```example_win32_directx11.vcxproj``` and ```example_win32_directx11.vcxproj.filters``` need to be copied.\n1. Rename ```example_win32_directx11.vcxproj.*``` in the root folder to ```RCCpp_DX11_Example.*```, the same names as the project we deleted above.\n1. Change the following paths in the project files ```RCCpp_DX11_Example.vcxproj.*``` we just renamed using a text editor with search and replace:\n    1. Replace ```..\\..``` with ```imgui```\n    1. Replace ```..``` with ```imgui\\examples```\n1. Copy the RCC++ project files (```*.vcxproj``` and ```*.vcxproj.filters```) from folders ```RuntimeCompiledCPlusPlus\\Aurora\\RuntimeCompiler``` and ```RuntimeCompiledCPlusPlus\\Aurora\\RuntimeObjectSystem``` to our root folder. Change the following paths using a text editor with search and replace\n    1. In ```RuntimeCompiler.vcxproj``` and ```RuntimeCompiler.vcxproj.filters``` ( renamed from RuntimeCompiler_VS2010.* ):\n        1. Replace ```\u003cClCompile Include=\"``` with ```\u003cClCompile Include=\"RuntimeCompiledCPlusPlus\\Aurora\\RuntimeCompiler\\```\n        1. Replace ```\u003cClInclude Include=\"``` with ```\u003cClInclude Include=\"RuntimeCompiledCPlusPlus\\Aurora\\RuntimeCompiler\\```\n    1. In ```RuntimeObjectSystem.vcxproj``` and ```RuntimeObjectSystem.vcxproj.filters```:\n        1. Replace ```\u003cClCompile Include=\"``` with ```\u003cClCompile Include=\"RuntimeCompiledCPlusPlus\\Aurora\\RuntimeObjectSystem\\```\n         1. Replace ```\u003cClInclude Include=\"``` with ```\u003cClInclude Include=\"RuntimeCompiledCPlusPlus\\Aurora\\RuntimeObjectSystem\\```\n1. For the following project changes, when opening the project properties (right clicking on a project in the Solution Explorer and selecting properties) pages make sure to set the configuration to ```All Configurations``` and Platform to ```All Platforms```.\n1. Add the projects to our solution and switch the platform toolset to our version of Visual Studio: version 142 for Visual Studio 2019\n1. Add the include directories to the RCC++ and imgui by changing the C/C++ General 'Additional Include Directories' to read: ```imgui;imgui\\examples;RuntimeCompiledCPlusPlus\\Aurora\\RuntimeObjectSystem;RuntimeCompiledCPlusPlus\\Aurora\\RuntimeCompiler;%(AdditionalIncludeDirectories)```.\n1. Setup project dependencies - right click on the Solution in the Solution Explorer and select Project Dependencies. For the project ```RCCpp_DX11_Example``` the ```RuntimeCompiler``` and ```RuntimeObjectSystem``` should be selected as 'depends on'.\n1. Right click on all the projects ```RCCpp_DX11_Example```, ```RuntimeCompiler.lib``` and ```RuntimeObjectSystem.lib```, in General tab change the output directory to: ```$(SolutionDir)build\\$(PlatformTarget)\\$(Configuration)\\``` and the Intermediate Directory to: ```$(SolutionDir)build\\intermediates\\$(ProjectName)\\$(PlatformTarget)\\$(Configuration)\\```.\n1. Right click on the ```RCCpp_DX11_Example``` project and select Properties. Under the Linker General settings add the output directory as an Additional Library Directory by entering ```$(OutDir)``` before the other directories.\n1. In the Linker Input properties for the ```RCCpp_DX11_Example```  project add ```RuntimeCompiler.lib``` and ```RuntimeObjectSystem.lib``` as link Additional Dependencies.\n\nThe code up to this point is available in the example from the branch Project_Setup at https://github.com/dougbinks/RCCpp_DX11_Example/tree/Project_Setup. This runs the Dear ImGui example code and has the RuntimeCompiler and RuntimeObjectSystem libraries linked, but has no RCC++ code setup as yet.\n\n## Working RCC++\nThe next step after the project setup is to get RCC++ working with the minimal code required.\n\n[RCC++ Dear ImGui and DirectX Tutorial Video Part 3: Working RCC++](https://www.youtube.com/watch?v=MFhuu7eWBzM\u0026list=PLRp7HE6uWI1m6tu_-vNUY-N_gnXT17WHQ\u0026index=3)\n\nFor detailed steps take a look at the  [repo commit history on branch  Working_RCC++](https://github.com/dougbinks/RCCpp_DX11_Example/commits/Working_RCC++). \n\nThe basic code to initialise and cleanup RCC++ is:\n\n**main.cpp**\n```cpp\n#include \"RuntimeObjectSystem.h\"\n\n// headers from our example \n#include \"StdioLogSystem.h\"\n\n// RCC++ Data\nstatic IRuntimeObjectSystem*    g_pRuntimeObjectSystem;\nstatic StdioLogSystem           g_Logger;\n\n// Forward declarations of RCC++ helper functions\nbool RCCppInit();\nvoid RCCppCleanup();\n\n// Main code\nint main(int, char**)\n{\n    // Create application window\n    //...\n\n    // Initialize RCC++\n    RCCppInit();\n    \n    // Initialize Direct3D\n    //...\n    \n    // Cleanup\n    RCCppCleanup();\n    //...\n}\n\nbool RCCppInit()\n{\n    g_pRuntimeObjectSystem = new RuntimeObjectSystem;\n    if( !g_pRuntimeObjectSystem-\u003eInitialise(\u0026g_Logger, NULL) )\n    {\n        delete g_pRuntimeObjectSystem;\n        g_pRuntimeObjectSystem = NULL;\n        return false;\n    }\n    return true;\n}\n\nvoid RCCppCleanup()\n{\n    delete g_pRuntimeObjectSystem;\n}\n```\n\nOne of the parameters which can be passed to the Initialise function for the RuntimeObjectSystem is an ```ICompilerLogger``` pointer. When non-null, RCC++ will log important information to this including all compiler output. StdioLogSystem is a simple implementation which takes the output of RCC++ compiles and passes them to the Visual Studio IDE debug stream via ```OutputDebugStream``` as well as to ```std::cout```. The log is formatted so that if there is an error in the compilation, double clicking on it goes to that line and file.\n\nThe RCC++ RuntimeObjectSystem file change notifier must have its update function called regularly so it can detect changed files. Additionally the code needs to load any compiled modules when a compile is complete. \n\nThis code could go in a runtime compiled file but that requires care to ensure that when that file is compiled, any code which comes after loading a module does not reference memory which could have been deleted. In order to do this we place the code in main.cpp:\n\n**main.cpp**\n```cpp\n// Forward declarations of RCC++ helper functions\n//...\nvoid RCCppUpdate();\n\n// Main code\nint main(int, char**)\n{\n    //...\n    while (msg.message != WM_QUIT)\n    {\n        //...\n\n        // Update RCC++\n        RCCppUpdate();\n    \n    //...\n    }\n    //...\n}\nvoid RCCppUpdate()\n{\n    //check status of any compile\n    if( g_pRuntimeObjectSystem-\u003eGetIsCompiledComplete() )\n    {\n        // load module when compile complete\n        g_pRuntimeObjectSystem-\u003eLoadCompiledModule();\n    }\n\n    if( !g_pRuntimeObjectSystem-\u003eGetIsCompiling() )\n    {\n        float deltaTime = 1.0f / ImGui::GetIO().Framerate;\n        g_pRuntimeObjectSystem-\u003eGetFileChangeNotifier()-\u003eUpdate( deltaTime );\n    }\n}\n```\n\nNote that a time delta is passed to RCC++. This is used to delay compilation of any files until 0.1 seconds have passed so that RCC++ captures all files saved if multiple files are saved at once. \n\nFor RCC++ to work, at least one file must have a class derived from RCC++ IObject and registered with RCC++ using a register macro. For this example the file which will be registered for runtime compilation is called RCCppMainLoop.cpp as it is going to handle the inner main loop of the program. \n\nInitial code for the RCC++ file **RCCppMainLoop.cpp**:\n```cpp\n#include \"ObjectInterfacePerModule.h\"\n#include \"IObject.h\"\n\n\n// RCC++ uses interface Id's to distinguish between different classes\n// here we have only one, so we don't need a header for this enum and put it in the same\n// source code file as the rest of the code\nenum InterfaceIDEnumConsoleExample\n{\n    IID_IRCCPP_MAIN_LOOP = IID_ENDInterfaceID, // IID_ENDInterfaceID from IObject.h InterfaceIDEnum\n\n    IID_ENDInterfaceIDEnumConsoleExample\n};\n\nstruct RCCppMainLoop : TInterface\u003cIID_IRCCPP_MAIN_LOOP,IObject\u003e\n{\n\n};\n\nREGISTERSINGLETON(RCCppMainLoop,true);\n```\n\nNote I often use ```struct``` instead of ```class``` when we don't need private members.\n\nThe important elements here are:\n\n```InterfaceIDEnumConsoleExample``` - this enum is used by the IObject factory system to identify objects. For RCC++ projects with more than one file it's normally in a separate header (the name is an accidental holdover from the console example in RCC++).\n\n```struct RCCppMainLoop : TInterface\u003cIID_IRCCPP_MAIN_LOOP,IObject\u003e``` - this struct definition uses the ```TInterface``` template to help define a class (a struct is class which is default public) which can be automatically recompiled at runtime. We derive from the base runtime compiled class ```IObject``, and use the ```IID_IRCCPP_MAIN_LOOP``` enumeration as an id. RCC++ needs these enums, though in this example we'll only have one class so it's not going to be used except here.\n\n```REGISTERSINGLETON(RCCppMainLoop,true)``` - this macro registers the class ```RCCppMainLoop``` with RCC++ as one which will only have one instance (i.e. a singleton), and the second parameter instructs RCC++ to construct one instance when RCC++ is initialized. This way we don't have to construct an instance of the class in our own code.\n\nThe ```REGISTERSINGLETON``` macro and an alternative ```REGISTERCLASS``` macro are the primary methods through which the RuntimeObjectSystem in RCC++ is informed about which files are needed for compilation. At least one file must have a class registered through one of these macros. We'll show how to register code dependencies later on in this tutorial. See the [wiki page on Runtime Modifiable Classes](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki/Runtime-Modifiable-Classes) for more information.\n\nThe code up to this point is available in the example from the branch Working_RCC++ at https://github.com/dougbinks/RCCpp_DX11_Example/tree/Working_RCC++. At this point we can run the program. When we save out the file RCCppMainLoop.cpp we should see debug output in Visual Studio with the code compiling.\n\n## Working Dear ImGui with RCC++\nNow that we have a working runtime compiled file, we add code to use Dear ImGui and call that from main.cpp.\n\n[RCC++ Dear ImGui and DirectX Tutorial Video Part 4: Dear ImGui with RCC++](https://www.youtube.com/watch?v=3UOxrvr4TH8\u0026list=PLRp7HE6uWI1m6tu_-vNUY-N_gnXT17WHQ\u0026index=4)\n\nFor detailed steps see the [repo commit history on branch  RCC++_With_ImGui](https://github.com/dougbinks/RCCpp_DX11_Example/commits/RCC++_With_ImGui). \n\n\nAll functions needed in main.cpp from the RCCppMainLoop class need to be exposed. To do so, add an abstract interface which exposes each function as a pure virtual function in a header, and derive from that in the RCCppMainLoop class:\n\n**RCCppMainLoop.h**\n```cpp\n#pragma once\n\n// abstract interface to our RCCppMainLoop class, using I at end to denote Interface\nstruct RCCppMainLoopI\n{\n    virtual void MainLoop() = 0;\n};\n```\n\nNext step is to include the header in RCCppMainLoop.cpp then derive from the interface with an implementation of the MainLoop() function we added:\n\n**RCCppMainLoop.cpp**\n```cpp\nstruct RCCppMainLoop : RCCppMainLoopI, TInterface\u003cIID_IRCCPP_MAIN_LOOP,IObject\u003e\n{\n    void MainLoop() override\n    {\n    }\n};\n```\n\nOur Main.cpp code needs to be able to get hold of the instance of our RCCppMainLoop class. This can be done through the IObjectFactorySystem but we'll use a simpler approach through a struct we call the SystemTable.\n\nThe RuntimeObjectSystem can be initialized with SystemTable pointer which is then exposed via ```PerModuleInterface::g_pSystemTable```. This is linked into modules compiled at runtime. RCC++ only forward declares ```SystemTable```, and to use this we need to add a definition which includes the variables and functions we need as members. We'll be adding useful data to our SystemTable to communicate between main.cpp and our RCCppMainLoop class.\n\nWe create a header for our SystemTable:\n\n**SystemTable.h**\n```cpp\n#pragma once\n\n#include \"RuntimeInclude.h\"\nRUNTIME_MODIFIABLE_INCLUDE; //recompile runtime files when this changes\n\nstruct RCCppMainLoopI;\nstruct ImGuiContext;\n\nstruct SystemTable\n{\n    RCCppMainLoopI* pRCCppMainLoopI = 0;\n    ImGuiContext*   pImContext      = 0;\n};\n```\n\nWe now add a constructor to our RCCppMainLoop class:\n\n**RCCppMainLoop.cpp**\n```cpp\nstruct RCCppMainLoop : RCCppMainLoopI, TInterface\u003cIID_IRCCPP_MAIN_LOOP,IObject\u003e\n{\n    RCCppMainLoop()\n    {\n        PerModuleInterface::g_pSystemTable-\u003epRCCppMainLoopI = this;\n    }\n\n    void MainLoop() override\n    {\n    }\n};\n```\n\nThe constructor uses the PerModuleInterface to access the system table and set pRCCppMainLoopI. So when RCCppMainLoop  is recompiled we'll automatically see this pointer switch to the new class.\n\nIn main.cpp we now create a SystemTable object and change our RCC++ initialization code to pass the SystemTable to the RuntimeObjectSystem and at the same time we add code to add an include directory to the RCC++ build system using ```AddIncludeDir()```.:\n\n**main.cpp**\n```cpp\n#include \"SystemTable.h\"\n#include \"RCCppMainLoop.h\"\n\n//...\n\nstatic SystemTable              g_SystemTable;\n\n//...\n\nbool RCCppInit()\n{\n    g_pRuntimeObjectSystem = new RuntimeObjectSystem;\n    if( !g_pRuntimeObjectSystem-\u003eInitialise(\u0026g_Logger, \u0026g_SystemTable) )\n    {\n        delete g_pRuntimeObjectSystem;\n        g_pRuntimeObjectSystem = NULL;\n        return false;\n    }\n\n    // ensure include directories are set - use location of this file as starting point\n    FileSystemUtils::Path basePath = g_pRuntimeObjectSystem-\u003eFindFile( __FILE__ ).ParentPath();\n    FileSystemUtils::Path imguiIncludeDir = basePath / \"imgui\";\n    g_pRuntimeObjectSystem-\u003eAddIncludeDir( imguiIncludeDir.c_str() );\n\n    return true;\n}\n```\n\nWe also add a call to the MainLoop() function in our **main.cpp** loop:\n```cpp\n        // Call the function in our RCC++ class\n        g_SystemTable.pRCCppMainLoopI-\u003eMainLoop();\n```\n\nWe need to let the RCC++ system know how to link the RCCppMainLoop.cpp file when it is compiled to Dear ImGui. We could build Dear ImGui as a library and use [RUNTIME_COMPILER_LINKLIBRARY](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki/Using-libraries-from-runtime-modifiable-classes) but instead we'll be using [RUNTIME_COMPILER_SOURCEDEPENDENCY_FILE](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki/Runtime-source-dependencies).\n\nThe ```RUNTIME_COMPILER_SOURCEDEPENDENCY_FILE``` macro allows us to specify files which are required to be built and linked to our RCC++ compiled code. For Dear ImGui we need to compile and link to several files, so we add these to our RCCppMainLoop.cpp file and then we can add Dear ImGui code and change it at runtime.\n\nChanges to **RCCppMainLoop.cpp**:\n```cpp\n#include \"imgui.h\"\n\n// add imgui source dependencies\n// an alternative is to put imgui into a library and use RuntimeLinkLibrary\n#include \"RuntimeSourceDependency.h\"\nRUNTIME_COMPILER_SOURCEDEPENDENCY_FILE( \"imgui/imgui\", \".cpp\" );\nRUNTIME_COMPILER_SOURCEDEPENDENCY_FILE( \"imgui/imgui_widgets\", \".cpp\" );\nRUNTIME_COMPILER_SOURCEDEPENDENCY_FILE( \"imgui/imgui_draw\", \".cpp\" );\nRUNTIME_COMPILER_SOURCEDEPENDENCY_FILE( \"imgui/imgui_demo\", \".cpp\" );\n\n//...\n\n    void MainLoop() override\n    {\n        ImGui::SetCurrentContext( PerModuleInterface::g_pSystemTable-\u003epImContext );\n\n        ImGui::SetNextWindowPos(ImVec2(50,400), ImGuiCond_Appearing );\n        ImGui::SetNextWindowSize(ImVec2(0,0), ImGuiCond_Always );\n        ImGui::Begin(\"RCCppMainLoop Window\" );\n        ImGui::Text(\"You can change Window's code at runtime!\");\n        ImGui::End();\n    }\n```\n\nThe code up to this point is available in the example from the branch RCC++_With_ImGui at https://github.com/dougbinks/RCCpp_DX11_Example/tree/RCC++_With_ImGui. The Dear ImGui code in MainLoop() can now be modified at runtime.\n\n## Using DirectX with RCC++: part 1\nFor detailed steps take a look at the [repo commit history up to branch RCC++_With_D3D](https://github.com/dougbinks/RCCpp_DX11_Example/commits/RCC++_With_D3D).\n\n[RCC++ Dear ImGui and DirectX Tutorial Video Part 5: Using DirectX with RCC++](https://www.youtube.com/watch?v=njCwsD8yJ0A\u0026list=PLRp7HE6uWI1m6tu_-vNUY-N_gnXT17WHQ\u0026index=5)\n\nMost DirectX functionality uses interfaces (abstract base classes using pure virtual functions), which can be used without linking to a library. This means that passing a pointer and including a header is all that's needed to use them with RCC++, which can be done through the SystemTable.\n\nModified **SystemTable.h**:\n```cpp\n#pragma once\n\n#include \"RuntimeInclude.h\"\nRUNTIME_MODIFIABLE_INCLUDE; //recompile runtime files when this changes\n\nstruct RCCppMainLoopI;\nstruct ImGuiContext;\nstruct ID3D11Device;\nstruct ID3D11DeviceContext;\nstruct IDXGISwapChain;\nstruct ID3D11RenderTargetView;\n\nstatic SystemTable*\u0026 g_pSys  = PerModuleInterface::g_pSystemTable;\n\nstruct SystemTable\n{\n    RCCppMainLoopI* pRCCppMainLoopI = 0;\n    ImGuiContext*   pImContext      = 0;\n    ID3D11Device*            pd3dDevice            = NULL;\n    ID3D11DeviceContext*     pd3dDeviceContext     = NULL;\n    IDXGISwapChain*          pSwapChain            = NULL;\n    ID3D11RenderTargetView*  pMainRenderTargetView = NULL;\n};\n```\n\nA static reference to the SystemTable is added so it's easier to use, the following code:\n```cpp\n        PerModuleInterface::g_pSystemTable-\u003epd3dDeviceContext;\n```\ncan be simplified to:\n```cpp\n        g_pSys--\u003epd3dDeviceContext;\n```\n\nInitialize these pointers in main.cpp and in RCCppMainLoop.cpp add ```#include \u003cd3d11.h\u003e``` to use most D3D functionality through the pointers in the system table.\n\nWe can now use the device context in our **RCCppMainLoop.cpp** code:\n```cpp\n// ...\n\n#include \u003cd3d11.h\u003e\n#define DIRECTINPUT_VERSION 0x0800\n\n// ...\n\n    void MainLoop() override\n    {\n        // rest of code...\n\n        g_pSys-\u003epd3dDeviceContext-\u003eOMSetRenderTargets(1, \u0026g_pSys-\u003epMainRenderTargetView, NULL);\n        g_pSys-\u003epd3dDeviceContext-\u003eClearRenderTargetView( g_pSys-\u003epMainRenderTargetView, (float*)\u0026clear_color);\n    }\n\n//...\n```\n\nHowever we've not been able to move over the call to ```Present()``` at this point as this we need to call ```ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());``` which is a function in imgui_impl_dx11.h. We could move all the Dear ImGui code into a library and then [use the library from the runtime modifiable code](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki/Using-libraries-from-runtime-modifiable-classes) as we do in the next chapter, but instead as this is only one function we add a function pointer to the System Table.\n\nUpdates to **SystemTable.h**:\n```cpp\n//...\n\ntypedef void (*ImGui_ImplDX11_RenderDrawDataFunc)( ImDrawData* draw_data );\n\n// more code...\nstruct SystemTable\n{\n    //...\n\n    ImGui_ImplDX11_RenderDrawDataFunc  ImGui_ImplDX11_RenderDrawData = NULL;\n\n    //...\n}\n```\n\nIn **main.cpp** we initialize this after our Dear ImGui context:\n```cpp\n    // set system table variables for ImGui and ImGui_Impl\n    g_SystemTable.pImContext = ImGui::GetCurrentContext();\n    g_SystemTable.ImGui_ImplDX11_RenderDrawData = ImGui_ImplDX11_RenderDrawData;\n```\n\nand then in **RCCppMainLoop.cpp** the end we have:\n```cpp\n    void MainLoop() override\n    {\n        //...\n\n        // Rendering\n        ImGui::Render();\n        g_pSys-\u003epd3dDeviceContext-\u003eOMSetRenderTargets(1, \u0026g_pSys-\u003epMainRenderTargetView, NULL);\n        g_pSys-\u003epd3dDeviceContext-\u003eClearRenderTargetView( g_pSys-\u003epMainRenderTargetView, (float*)\u0026clear_color);\n\n        g_pSys-\u003eImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());\n        g_pSys-\u003epSwapChain-\u003ePresent(1, 0); // Present with vsync\n\n    }\n```\n\nThe code up to this point is available in the example from the branch RCC++_With_D3D at https://github.com/dougbinks/RCCpp_DX11_Example/tree/RCC++_With_D3D. The D3D code can be modified at runtime, for example vsync can be turned off by changing ```g_pSys-\u003epSwapChain-\u003ePresent(1, 0);``` to ```g_pSys-\u003epSwapChain-\u003ePresent(0, 0);```.\n\n## Using DirectX with RCC++: part 2\nWhilst most D3D functionality can be accessed through interface pointers, there are some functions which require linking to the appropriate D3D library. See the RCC++ wiki on [using libraries from runtime modifiable classes](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki/Using-libraries-from-runtime-modifiable-classes) for more information on linking to libraries.\n\nFor detailed steps take a look at the [repo commit history up to branch RCC++_With_D3D_Library](https://github.com/dougbinks/RCCpp_DX11_Example/commits/RCC++_With_D3D_Library).\n\nTo inform RCC++ that it needs to link with a library when performing runtime compilation, use the ```RUNTIME_COMPILER_LINKLIBRARY``` macro. For non system libraries the library directories to search can be added with the ```IRuntimeObjectSystem::AddLibraryDir``` function.\n\nIn **RCCppMainLoop.cpp** add the following lines:\n```cpp\n#include \"RuntimeLinkLibrary.h\"\nRUNTIME_COMPILER_LINKLIBRARY( \"d3d11.lib\" ); \n```\n\nThe device creation can now be moved over to the RCCppMainLoop.cpp, extending the interface so main.cpp can call the creation functions:\n\nWe add the creation and cleanup interface functions to **RCCppMainLoop.h**:\n```cpp\n#pragma once\n\n// abstract interface to our RCCppMainLoop class, using I at end to denote Interface\nstruct RCCppMainLoopI\n{\n    virtual void MainLoop() = 0;\n    virtual bool CreateDeviceD3D(void* hWnd) = 0;\n    virtual void CleanupDeviceD3D() = 0;\n    virtual void CreateRenderTarget() = 0;\n    virtual void CleanupRenderTarget() = 0;\n};\n```\n\nAnd move those functions over to **RCCppMainLoop.cpp**:\n```cpp\nstruct RCCppMainLoop : RCCppMainLoopI, TInterface\u003cIID_IRCCPP_MAIN_LOOP,IObject\u003e\n{\n\n    // rest of code....\n\n    bool CreateDeviceD3D(void* hWnd) override\n    {\n        // Setup swap chain\n        DXGI_SWAP_CHAIN_DESC sd;\n        ZeroMemory(\u0026sd, sizeof(sd));\n        sd.BufferCount = 2;\n        sd.BufferDesc.Width = 0;\n        sd.BufferDesc.Height = 0;\n        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;\n        sd.BufferDesc.RefreshRate.Numerator = 60;\n        sd.BufferDesc.RefreshRate.Denominator = 1;\n        sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;\n        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;\n        sd.OutputWindow = (HWND)hWnd;\n        sd.SampleDesc.Count = 1;\n        sd.SampleDesc.Quality = 0;\n        sd.Windowed = TRUE;\n        sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;\n\n        UINT createDeviceFlags = 0;\n        //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;\n        D3D_FEATURE_LEVEL featureLevel;\n        const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };\n        if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, \u0026sd, \u0026g_pSys-\u003epSwapChain, \u0026g_pSys-\u003epd3dDevice, \u0026featureLevel, \u0026g_pSys-\u003epd3dDeviceContext) != S_OK)\n            return false;\n\n        CreateRenderTarget();\n        return true;\n    }\n\n    void CleanupDeviceD3D() override\n    {\n        CleanupRenderTarget();\n        if (g_pSys-\u003epSwapChain) { g_pSys-\u003epSwapChain-\u003eRelease(); g_pSys-\u003epSwapChain = NULL; }\n        if (g_pSys-\u003epd3dDeviceContext) { g_pSys-\u003epd3dDeviceContext-\u003eRelease(); g_pSys-\u003epd3dDeviceContext = NULL; }\n        if (g_pSys-\u003epd3dDevice) { g_pSys-\u003epd3dDevice-\u003eRelease(); g_pSys-\u003epd3dDevice = NULL; }\n    }\n\n    void CreateRenderTarget() override\n    {\n        ID3D11Texture2D* pBackBuffer;\n        g_pSys-\u003epSwapChain-\u003eGetBuffer(0, IID_PPV_ARGS(\u0026pBackBuffer));\n        g_pSys-\u003epd3dDevice-\u003eCreateRenderTargetView(pBackBuffer, NULL, \u0026g_pSys-\u003epMainRenderTargetView);\n        pBackBuffer-\u003eRelease();\n    }\n\n    void CleanupRenderTarget() override\n    {\n        if (g_pSys-\u003epMainRenderTargetView) { g_pSys-\u003epMainRenderTargetView-\u003eRelease(); g_pSys-\u003epMainRenderTargetView = NULL; }\n    }\n};\n```\n\nThese functions are the same as we had in the ```main.cpp``` code, but with the struct access ```g_SystemTable.``` replaced with the system table pointer access ```g_pSys-\u003e```. In ```main.cpp``` we remove these functions and their forward declarations and add ```g_SystemTable.pRCCppMainLoopI-\u003e``` in front of calls to these functions as they are now accessed through the pointer to our RCCppMainLoop object pointer in the System Table. So for example:\n```cpp\n        CleanupDeviceD3D();\n```\nbecomes:\n```cpp\n        g_SystemTable.pRCCppMainLoopI-\u003eCleanupDeviceD3D();\n```\n\nThe code up to this point is available in the example from the branch RCC++_With_D3D at https://github.com/dougbinks/RCCpp_DX11_Example/tree/RCC++_With_D3D_Library.\n\n## Conclusion\nIn addition to showing how to convert a small example to code which can use RCC++ for live code editing, the RCCpp_DX11_Example is a good starting point for prototyping Dear ImGui code.\n\nThis tutorial has covered:\n1. Adding the required RCC++ projects to a Visual Studio project\n1. Adding a file with a class which can be compiled using runtime compilation\n1. Adding the code needed to detect file changes, compile and then load them\n1. Passing information to \u0026 from the runtime compiled code with the system table\n1. Using source code dependencies\n1. Using code which has abstract interfaces such as the ```ID3D11DeviceContext```\n1. Linking to libraries with runtime compiled code\n\nThese techniques are the main approaches for building applications which use RCC++. For more advanced usage, from adding runtime protection, setting compiler optimization and debug levels, disabling RCC++ in shipping, to undo and redo functionality etc. check out the [Runtime Compiled C++ Wiki](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki).\n","funding_links":["https://github.com/sponsors/dougbinks","https://patreon.com/enkisoftware","https://www.enkisoftware.com/avoyd","https://www.patreon.com/enkisoftware"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdougbinks%2Frccpp_dx11_example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdougbinks%2Frccpp_dx11_example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdougbinks%2Frccpp_dx11_example/lists"}