Merge pull request #1327 from Soreepeong/feature/object-vtable-hook-with-swapchain

This commit is contained in:
goat 2023-08-13 23:25:22 +02:00 committed by GitHub
commit 26ee756427
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 7198 additions and 306 deletions

View file

@ -57,12 +57,12 @@ dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static,readonly
dotnet_style_parentheses_in_arithmetic_binary_operators =always_for_clarity:suggestion
dotnet_style_parentheses_in_other_binary_operators =always_for_clarity:suggestion
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
dotnet_style_parentheses_in_other_operators=always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = always_for_clarity:silent
dotnet_style_object_initializer = false
dotnet_style_qualification_for_event = true:suggestion
dotnet_style_qualification_for_field = true:suggestion
@ -78,7 +78,7 @@ csharp_space_before_comma = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_comma = true
csharp_space_after_cast = false
csharp_space_around_binary_operators = before_and_after
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = none
@ -101,7 +101,7 @@ resharper_braces_for_ifelse = required_for_multiline
resharper_can_use_global_alias = false
resharper_csharp_align_multiline_parameter = true
resharper_csharp_align_multiple_declaration = true
resharper_csharp_empty_block_style = together_same_line
resharper_csharp_empty_block_style = multiline
resharper_csharp_int_align_comments = true
resharper_csharp_new_line_before_while = true
resharper_csharp_wrap_after_declaration_lpar = true
@ -133,13 +133,13 @@ resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
resharper_suggest_var_or_type_simple_types_highlighting = hint
resharper_unused_auto_property_accessor_global_highlighting = none
csharp_style_deconstructed_variable_declaration=true:silent
csharp_style_deconstructed_variable_declaration = true:silent
[*.{appxmanifest,asax,ascx,aspx,axaml,axml,build,c,c++,cc,cginc,compute,config,cp,cpp,cs,cshtml,csproj,css,cu,cuh,cxx,dbml,discomap,dtd,h,hh,hlsl,hlsli,hlslinc,hpp,htm,html,hxx,inc,inl,ino,ipp,js,json,jsproj,jsx,lsproj,master,mpp,mq4,mq5,mqh,njsproj,nuspec,paml,proj,props,proto,razor,resjson,resw,resx,skin,StyleCop,targets,tasks,tpp,ts,tsx,usf,ush,vb,vbproj,xaml,xamlx,xml,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4
dotnet_style_parentheses_in_other_operators=always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = always_for_clarity:silent
[*.{yaml,yml}]
indent_style = space

View file

@ -46,6 +46,7 @@
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc17</LanguageStandard_C>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@ -66,6 +67,7 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">26812</DisableSpecificWarnings>
<BuildStlModules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</BuildStlModules>
</ClCompile>
<Link>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
@ -156,6 +158,14 @@
<ClInclude Include="..\lib\CoreCLR\core\coreclr_delegates.h" />
<ClInclude Include="..\lib\CoreCLR\core\hostfxr.h" />
<ClInclude Include="..\lib\CoreCLR\nethost\nethost.h" />
<ClInclude Include="..\lib\reshade\include\reshade.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_api.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_api_device.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_api_format.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_api_pipeline.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_api_resource.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_events.hpp" />
<ClInclude Include="..\lib\reshade\include\reshade_overlay.hpp" />
<ClInclude Include="..\lib\TsudaKageyu-minhook\include\MinHook.h" />
<ClInclude Include="..\lib\TsudaKageyu-minhook\src\buffer.h" />
<ClInclude Include="..\lib\TsudaKageyu-minhook\src\HDE\hde32.h" />

View file

@ -17,6 +17,9 @@
<Filter Include="MinHook">
<UniqueIdentifier>{6ec5597d-e293-4d2a-a307-7444c8fac04b}</UniqueIdentifier>
</Filter>
<Filter Include="ReshadePlugin">
<UniqueIdentifier>{fff0ec42-beda-42f6-997b-953cc54d3d29}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@ -140,6 +143,30 @@
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="crashhandler_shared.h" />
<ClInclude Include="..\lib\reshade\include\reshade.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_api.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_api_device.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_api_format.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_api_pipeline.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_api_resource.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_events.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
<ClInclude Include="..\lib\reshade\include\reshade_overlay.hpp">
<Filter>ReshadePlugin</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Dalamud.Boot.rc" />

View file

@ -8,6 +8,14 @@
HMODULE g_hModule;
HINSTANCE g_hGameInstance = GetModuleHandleW(nullptr);
bool g_bReshadeAvailable = false;
static void(*s_pfnReshadeOverlayCallback)(void*) = nullptr;
static void OnReshadeOverlay(reshade::api::effect_runtime *runtime) {
if (s_pfnReshadeOverlayCallback)
s_pfnReshadeOverlayCallback(reinterpret_cast<void*>(runtime->get_native()));
}
DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
g_startInfo.from_envvars();
@ -127,7 +135,7 @@ DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
if (result != 0)
return result;
using custom_component_entry_point_fn = void (CORECLR_DELEGATE_CALLTYPE*)(LPVOID, HANDLE);
using custom_component_entry_point_fn = void (CORECLR_DELEGATE_CALLTYPE*)(LPVOID, HANDLE, LPVOID);
const auto entrypoint_fn = reinterpret_cast<custom_component_entry_point_fn>(entrypoint_vfn);
// ============================== VEH ======================================== //
@ -153,7 +161,7 @@ DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
// utils::wait_for_game_window();
logging::I("Initializing Dalamud...");
entrypoint_fn(lpParam, hMainThreadContinue);
entrypoint_fn(lpParam, hMainThreadContinue, g_bReshadeAvailable ? &s_pfnReshadeOverlayCallback : nullptr);
logging::I("Done!");
return 0;
@ -169,6 +177,9 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese
switch (dwReason) {
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
g_bReshadeAvailable = reshade::register_addon(hModule);
if (g_bReshadeAvailable)
reshade::register_event<reshade::addon_event::reshade_overlay>(&OnReshadeOverlay);
break;
case DLL_PROCESS_DETACH:
@ -178,7 +189,10 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese
// process is terminating; don't bother cleaning up
if (lpReserved)
return TRUE;
if (g_bReshadeAvailable)
reshade::unregister_event<reshade::addon_event::reshade_overlay>(&OnReshadeOverlay);
logging::update_dll_load_status(false);
xivfixes::apply_all(false);

View file

@ -59,6 +59,9 @@
// https://github.com/nlohmann/json
#include "../lib/nlohmann-json/json.hpp"
// https://github.com/crosire/reshade/tree/main/include
#include "../lib/reshade/include/reshade.hpp"
#include "unicode.h"
// Commonly used macros
@ -67,6 +70,7 @@
// Global variables
extern HMODULE g_hModule;
extern HINSTANCE g_hGameInstance;
extern bool g_bReshadeAvailable;
extern std::optional<CoreCLR> g_clr;
#endif //PCH_H

View file

@ -368,7 +368,8 @@ DllExport void WINAPI RewrittenEntryPoint(RewrittenEntryPointParameters& params)
loadInfo = params.pLoadInfo;
}
InitializeImpl(&loadInfo[0], params.hMainThreadContinue);
if (const auto err = InitializeImpl(&loadInfo[0], params.hMainThreadContinue))
throw std::exception(std::format("{:08X}", err).c_str());
return 0;
} catch (const std::exception& e) {
MessageBoxA(nullptr, std::format("Failed to load Dalamud.\n\nError: {}", e.what()).c_str(), "Dalamud.Boot", MB_OK | MB_ICONERROR);

View file

@ -1,8 +1,9 @@
namespace Dalamud.Game.Internal.DXGI.Definitions;
namespace Dalamud.ComInterfaceVTables;
/// <summary>
/// Contains a full list of ID3D11Device functions to be used as an indexer into the DirectX Virtual Function Table entries.
/// </summary>
// ReSharper disable once InconsistentNaming
internal enum ID3D11DeviceVtbl
{
// IUnknown

View file

@ -1,9 +1,10 @@
namespace Dalamud.Game.Internal.DXGI.Definitions;
namespace Dalamud.ComInterfaceVTables;
/// <summary>
/// Contains a full list of IDXGISwapChain functions to be used as an indexer into the SwapChain Virtual Function Table
/// entries.
/// </summary>
// ReSharper disable once InconsistentNaming
internal enum IDXGISwapChainVtbl
{
// IUnknown

View file

@ -25,19 +25,26 @@ namespace Dalamud;
/// <summary>
/// The main entrypoint for the Dalamud system.
/// </summary>
public sealed class EntryPoint
public static class EntryPoint
{
/// <summary>
/// Log level switch for runtime log level change.
/// </summary>
public static readonly LoggingLevelSwitch LogLevelSwitch = new(LogEventLevel.Verbose);
/// <summary>
/// Pointer to function pointer that will be called upon Reshade's Present callback.
/// The value is set to null if Reshade is not detected.
/// </summary>
private static unsafe void** reshadePresentCallbackPtrPtr;
/// <summary>
/// A delegate used during initialization of the CLR from Dalamud.Boot.
/// </summary>
/// <param name="infoPtr">Pointer to a serialized <see cref="DalamudStartInfo"/> data.</param>
/// <param name="mainThreadContinueEvent">Event used to signal the main thread to continue.</param>
public delegate void InitDelegate(IntPtr infoPtr, IntPtr mainThreadContinueEvent);
/// <param name="externalPresentDetour">Pointer to function pointer that will be called upon Reshade's Present callback.</param>
public delegate void InitDelegate(IntPtr infoPtr, IntPtr mainThreadContinueEvent, IntPtr externalPresentDetour);
/// <summary>
/// A delegate used from VEH handler on exception which CoreCLR will fast fail by default.
@ -50,10 +57,15 @@ public sealed class EntryPoint
/// </summary>
/// <param name="infoPtr">Pointer to a serialized <see cref="DalamudStartInfo"/> data.</param>
/// <param name="mainThreadContinueEvent">Event used to signal the main thread to continue.</param>
public static void Initialize(IntPtr infoPtr, IntPtr mainThreadContinueEvent)
/// <param name="externalPresentDetour">Pointer to function pointer that will be called upon Reshade's Present callback.</param>
public static void Initialize(IntPtr infoPtr, IntPtr mainThreadContinueEvent, IntPtr externalPresentDetour)
{
var infoStr = Marshal.PtrToStringUTF8(infoPtr)!;
var info = JsonConvert.DeserializeObject<DalamudStartInfo>(infoStr)!;
unsafe
{
reshadePresentCallbackPtrPtr = (void**)externalPresentDetour;
}
if ((info.BootWaitMessageBox & 4) != 0)
MessageBoxW(IntPtr.Zero, "Press OK to continue (BeforeDalamudConstruct)", "Dalamud Boot", MessageBoxType.Ok);
@ -61,6 +73,19 @@ public sealed class EntryPoint
new Thread(() => RunThread(info, mainThreadContinueEvent)).Start();
}
/// <summary>
/// Attempt to register a callback for Reshade Present.
/// </summary>
/// <param name="ptr">Pointer to the callback function.</param>
/// <returns>Whether the operation has been successful and Reshade will use this feature.</returns>
public static unsafe bool TryRegisterReshadePresentCallback(nint ptr)
{
if (reshadePresentCallbackPtrPtr == null)
return false;
*reshadePresentCallbackPtrPtr = (void*)ptr;
return true;
}
/// <summary>
/// Returns stack trace.
/// </summary>
@ -272,7 +297,7 @@ public sealed class EntryPoint
// ignored
}
const MessageBoxType flags = NativeFunctions.MessageBoxType.YesNo | NativeFunctions.MessageBoxType.IconError | NativeFunctions.MessageBoxType.SystemModal;
const MessageBoxType flags = MessageBoxType.YesNo | MessageBoxType.IconError | MessageBoxType.SystemModal;
var result = MessageBoxW(
Process.GetCurrentProcess().MainWindowHandle,
$"An internal error in a Dalamud plugin occurred.\nThe game must close.\n\n{ex.GetType().Name}\n{info}\n\n{pluginInfo}More information has been recorded separately{supportText}.\n\nDo you want to disable all plugins the next time you start the game?",

View file

@ -1,19 +0,0 @@
using System;
namespace Dalamud.Game.Internal.DXGI;
/// <summary>
/// An interface binding for the address resolvers that attempt to find native D3D11 methods.
/// </summary>
public interface ISwapChainAddressResolver
{
/// <summary>
/// Gets or sets the address of the native D3D11.Present method.
/// </summary>
IntPtr Present { get; set; }
/// <summary>
/// Gets or sets the address of the native D3D11.ResizeBuffers method.
/// </summary>
IntPtr ResizeBuffers { get; set; }
}

View file

@ -1,35 +0,0 @@
using System;
using System.Diagnostics;
using System.Linq;
using Serilog;
namespace Dalamud.Game.Internal.DXGI;
/// <summary>
/// The address resolver for native D3D11 methods to facilitate displaying the Dalamud UI.
/// </summary>
[Obsolete("This has been deprecated in favor of the VTable resolver.")]
public sealed class SwapChainSigResolver : BaseAddressResolver, ISwapChainAddressResolver
{
/// <inheritdoc/>
public IntPtr Present { get; set; }
/// <inheritdoc/>
public IntPtr ResizeBuffers { get; set; }
/// <inheritdoc/>
protected override void Setup64Bit(SigScanner sig)
{
var module = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().First(m => m.ModuleName == "dxgi.dll");
Log.Debug($"Found DXGI: 0x{module.BaseAddress.ToInt64():X}");
var scanner = new SigScanner(module);
// This(code after the function head - offset of it) was picked to avoid running into issues with other hooks being installed into this function.
this.Present = scanner.ScanModule("41 8B F0 8B FA 89 54 24 ?? 48 8B D9 48 89 4D ?? C6 44 24 ?? 00") - 0x37;
this.ResizeBuffers = scanner.ScanModule("48 8B C4 55 41 54 41 55 41 56 41 57 48 8D 68 B1 48 81 EC ?? ?? ?? ?? 48 C7 45 ?? ?? ?? ?? ?? 48 89 58 10 48 89 70 18 48 89 78 20 45 8B F9 45 8B E0 44 8B EA 48 8B F9 8B 45 7F 89 44 24 30 8B 75 77 89 74 24 28 44 89 4C 24");
}
}

View file

@ -1,128 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Dalamud.Game.Internal.DXGI.Definitions;
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using Serilog;
namespace Dalamud.Game.Internal.DXGI;
/// <summary>
/// This class attempts to determine the D3D11 SwapChain vtable addresses via instantiating a new form and inspecting it.
/// </summary>
/// <remarks>
/// If the normal signature based method of resolution fails, this is the backup.
/// </remarks>
public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver
{
/// <inheritdoc/>
public IntPtr Present { get; set; }
/// <inheritdoc/>
public IntPtr ResizeBuffers { get; set; }
/// <summary>
/// Gets a value indicating whether or not ReShade is loaded/used.
/// </summary>
public bool IsReshade { get; private set; }
/// <inheritdoc/>
protected override unsafe void Setup64Bit(SigScanner sig)
{
Device* kernelDev;
SwapChain* swapChain;
void* dxgiSwapChain;
while (true)
{
kernelDev = Device.Instance();
if (kernelDev == null)
continue;
swapChain = kernelDev->SwapChain;
if (swapChain == null)
continue;
dxgiSwapChain = swapChain->DXGISwapChain;
if (dxgiSwapChain == null)
continue;
break;
}
var scVtbl = GetVTblAddresses(new IntPtr(dxgiSwapChain), Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length);
this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present];
var modules = Process.GetCurrentProcess().Modules;
foreach (ProcessModule processModule in modules)
{
if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll"))
{
var fileInfo = FileVersionInfo.GetVersionInfo(processModule.FileName);
if (fileInfo.FileDescription == null)
break;
if (!fileInfo.FileDescription.Contains("GShade") && !fileInfo.FileDescription.Contains("ReShade"))
break;
// reshade master@4232872 RVA
// var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present
// var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present
// DXGISwapChain::handle_device_loss => DXGISwapChain::Present => DXGISwapChain::runtime_present
var scanner = new SigScanner(processModule);
var runtimePresentSig = "F6 C2 01 0F 85 ?? ?? ?? ??";
try
{
// Looks like this sig only works for GShade 4
if (fileInfo.FileDescription?.Contains("GShade 4.") == true)
{
Log.Verbose("Hooking present for GShade 4");
runtimePresentSig = "E8 ?? ?? ?? ?? 45 0F B6 5E ??";
}
}
catch (Exception ex)
{
Log.Error(ex, "Failed to get reshade version info - falling back to default DXGISwapChain::runtime_present signature");
}
try
{
var p = scanner.ScanText(runtimePresentSig);
Log.Information($"ReShade DLL: {processModule.FileName} with DXGISwapChain::runtime_present at {p:X}");
this.Present = p;
this.IsReshade = true;
break;
}
catch (Exception ex)
{
Log.Error(ex, "Could not find reshade DXGISwapChain::runtime_present offset!");
}
}
}
this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers];
}
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int numberOfMethods)
{
return GetVTblAddresses(pointer, 0, numberOfMethods);
}
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods)
{
var vtblAddresses = new List<IntPtr>();
var vTable = Marshal.ReadIntPtr(pointer);
for (var i = startIndex; i < startIndex + numberOfMethods; i++)
vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes
return vtblAddresses;
}
}

View file

@ -0,0 +1,167 @@
using System;
using System.Runtime.InteropServices;
namespace Dalamud.Hooking.Internal;
/// <summary>
/// Manages a hook that works by replacing the vtable of target object.
/// </summary>
internal unsafe class ObjectVTableHook : IDisposable
{
private readonly nint** ppVtbl;
private readonly int numMethods;
private readonly nint* pVtblOriginal;
private readonly nint* pVtblOverriden;
private readonly object?[] detourDelegates;
private bool released;
/// <summary>
/// Initializes a new instance of the <see cref="ObjectVTableHook"/> class.
/// </summary>
/// <param name="ppVtbl">Address to vtable. Usually the address of the object itself.</param>
/// <param name="numMethods">Number of methods in this vtable.</param>
public ObjectVTableHook(nint ppVtbl, int numMethods)
{
this.ppVtbl = (nint**)ppVtbl;
this.numMethods = numMethods;
this.detourDelegates = new object?[numMethods];
this.pVtblOriginal = *this.ppVtbl;
this.pVtblOverriden = (nint*)Marshal.AllocHGlobal(sizeof(void*) * numMethods);
this.VtblOriginal.CopyTo(this.VtblOverriden);
}
/// <summary>
/// Initializes a new instance of the <see cref="ObjectVTableHook"/> class.
/// </summary>
/// <param name="ppVtbl">Address to vtable. Usually the address of the object itself.</param>
/// <param name="numMethods">Number of methods in this vtable.</param>
public ObjectVTableHook(void* ppVtbl, int numMethods)
: this((nint)ppVtbl, numMethods)
{
}
/// <summary>
/// Finalizes an instance of the <see cref="ObjectVTableHook"/> class.
/// </summary>
~ObjectVTableHook() => this.ReleaseUnmanagedResources();
/// <summary>
/// Gets the span view of original vtable.
/// </summary>
private Span<nint> VtblOriginal => new(this.pVtblOriginal, this.numMethods);
/// <summary>
/// Gets the span view of overriden vtable.
/// </summary>
private Span<nint> VtblOverriden => new(this.pVtblOverriden, this.numMethods);
/// <summary>
/// Disables the hook.
/// </summary>
public void Disable() => *this.ppVtbl = this.pVtblOriginal;
/// <inheritdoc />
public void Dispose()
{
this.ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
/// <summary>
/// Enables the hook.
/// </summary>
public void Enable() => *this.ppVtbl = this.pVtblOverriden;
/// <summary>
/// Gets the original method address of the given method index.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <returns>Address of the original method.</returns>
public nint GetOriginalMethodAddress(int methodIndex)
{
this.EnsureMethodIndex(methodIndex);
return this.pVtblOriginal[methodIndex];
}
/// <summary>
/// Gets the original method of the given method index, as a delegate of given type.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <typeparam name="T">Type of delegate.</typeparam>
/// <returns>Delegate to the original method.</returns>
public T GetOriginalMethodDelegate<T>(int methodIndex)
where T : Delegate
{
this.EnsureMethodIndex(methodIndex);
return Marshal.GetDelegateForFunctionPointer<T>(this.pVtblOriginal[methodIndex]);
}
/// <summary>
/// Resets a method to the original function.
/// </summary>
/// <param name="methodIndex">The method index.</param>
public void ResetVtableEntry(int methodIndex)
{
this.EnsureMethodIndex(methodIndex);
this.VtblOverriden[methodIndex] = this.pVtblOriginal[methodIndex];
this.detourDelegates[methodIndex] = null;
}
/// <summary>
/// Sets a method in vtable to the given address of function.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <param name="pfn">Address of the detour function.</param>
/// <param name="refkeep">Additional reference to keep in memory.</param>
public void SetVtableEntry(int methodIndex, nint pfn, object? refkeep)
{
this.EnsureMethodIndex(methodIndex);
this.VtblOverriden[methodIndex] = pfn;
this.detourDelegates[methodIndex] = refkeep;
}
/// <summary>
/// Sets a method in vtable to the given delegate.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <param name="detourDelegate">Detour delegate.</param>
/// <typeparam name="T">Type of delegate.</typeparam>
public void SetVtableEntry<T>(int methodIndex, T detourDelegate)
where T : Delegate =>
this.SetVtableEntry(methodIndex, Marshal.GetFunctionPointerForDelegate(detourDelegate), detourDelegate);
/// <summary>
/// Sets a method in vtable to the given delegate.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <param name="detourDelegate">Detour delegate.</param>
/// <param name="originalMethodDelegate">Original method delegate.</param>
/// <typeparam name="T">Type of delegate.</typeparam>
public void SetVtableEntry<T>(int methodIndex, T detourDelegate, out T originalMethodDelegate)
where T : Delegate
{
originalMethodDelegate = this.GetOriginalMethodDelegate<T>(methodIndex);
this.SetVtableEntry(methodIndex, Marshal.GetFunctionPointerForDelegate(detourDelegate), detourDelegate);
}
private void EnsureMethodIndex(int methodIndex)
{
if (methodIndex < 0 || methodIndex >= this.numMethods)
{
throw new ArgumentOutOfRangeException(nameof(methodIndex), methodIndex, null);
}
}
private void ReleaseUnmanagedResources()
{
if (!this.released)
{
this.Disable();
Marshal.FreeHGlobal((nint)this.pVtblOverriden);
this.released = true;
}
}
}

View file

@ -0,0 +1,85 @@
using System;
using System.Runtime.InteropServices;
namespace Dalamud.Hooking.Internal;
/// <summary>
/// Typed version of <see cref="ObjectVTableHook"/>.
/// </summary>
/// <typeparam name="TVTableEnum">Type of VTable enum.</typeparam>
internal unsafe class ObjectVTableHook<TVTableEnum> : ObjectVTableHook
where TVTableEnum : unmanaged, Enum
{
/// <summary>
/// Initializes a new instance of the <see cref="ObjectVTableHook{TVTable}"/> class.
/// </summary>
/// <param name="ppVtbl">Address to vtable. Usually the address of the object itself.</param>
public ObjectVTableHook(TVTableEnum** ppVtbl)
: base(ppVtbl, Enum.GetValues(typeof(TVTableEnum)).Length)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ObjectVTableHook{TVTable}"/> class.
/// </summary>
/// <param name="ppVtbl">Address to vtable. Usually the address of the object itself.</param>
public ObjectVTableHook(void* ppVtbl)
: base(ppVtbl, Enum.GetValues(typeof(TVTableEnum)).Length)
{
}
/// <summary>
/// Gets the original method address of the given method index.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <returns>Address of the original method.</returns>
public nint GetOriginalMethodAddress(TVTableEnum methodIndex) =>
this.GetOriginalMethodAddress((int)(object)methodIndex);
/// <summary>
/// Gets the original method of the given method index, as a delegate of given type.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <typeparam name="T">Type of delegate.</typeparam>
/// <returns>Delegate to the original method.</returns>
public T GetOriginalMethodDelegate<T>(TVTableEnum methodIndex)
where T : Delegate
=> this.GetOriginalMethodDelegate<T>((int)(object)methodIndex);
/// <summary>
/// Resets a method to the original function.
/// </summary>
/// <param name="methodIndex">The method index.</param>
public void ResetVtableEntry(TVTableEnum methodIndex)
=> this.ResetVtableEntry((int)(object)methodIndex);
/// <summary>
/// Sets a method in vtable to the given address of function.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <param name="pfn">Address of the detour function.</param>
/// <param name="refkeep">Additional reference to keep in memory.</param>
public void SetVtableEntry(TVTableEnum methodIndex, nint pfn, object? refkeep)
=> this.SetVtableEntry((int)(object)methodIndex, pfn, refkeep);
/// <summary>
/// Sets a method in vtable to the given delegate.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <param name="detourDelegate">Detour delegate.</param>
/// <typeparam name="T">Type of delegate.</typeparam>
public void SetVtableEntry<T>(TVTableEnum methodIndex, T detourDelegate)
where T : Delegate =>
this.SetVtableEntry(methodIndex, Marshal.GetFunctionPointerForDelegate(detourDelegate), detourDelegate);
/// <summary>
/// Sets a method in vtable to the given delegate.
/// </summary>
/// <param name="methodIndex">The method index.</param>
/// <param name="detourDelegate">Detour delegate.</param>
/// <param name="originalMethodDelegate">Original method delegate.</param>
/// <typeparam name="T">Type of delegate.</typeparam>
public void SetVtableEntry<T>(TVTableEnum methodIndex, T detourDelegate, out T originalMethodDelegate)
where T : Delegate
=> this.SetVtableEntry((int)(object)methodIndex, detourDelegate, out originalMethodDelegate);
}

View file

@ -8,13 +8,14 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Dalamud.ComInterfaceVTables;
using Dalamud.Configuration.Internal;
using Dalamud.Game;
using Dalamud.Game.ClientState.GamePad;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.Gui.Internal;
using Dalamud.Game.Internal.DXGI;
using Dalamud.Hooking;
using Dalamud.Hooking.Internal;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.Internal.ManagedAsserts;
using Dalamud.Interface.Internal.Notifications;
@ -24,6 +25,7 @@ using Dalamud.Utility;
using Dalamud.Utility.Timing;
using ImGuiNET;
using ImGuiScene;
using JetBrains.Annotations;
using PInvoke;
using Serilog;
using SharpDX;
@ -64,15 +66,26 @@ internal class InterfaceManager : IDisposable, IServiceType
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service<Framework>.Get();
[ServiceManager.ServiceDependency]
private readonly SigScanner sigScanner = Service<SigScanner>.Get();
private readonly ManualResetEvent fontBuildSignal;
private readonly SwapChainVtableResolver address;
private readonly Hook<DispatchMessageWDelegate> dispatchMessageWHook;
private readonly Hook<SetCursorDelegate> setCursorHook;
private Hook<ProcessMessageDelegate> processMessageHook;
private readonly Hook<ProcessMessageDelegate> processMessageHook;
private RawDX11Scene? scene;
private Hook<PresentDelegate>? presentHook;
private Hook<ResizeBuffersDelegate>? resizeBuffersHook;
private ObjectVTableHook<IDXGISwapChainVtbl>? swapChainHook;
// For handling the case where ReShade is being used.
// Marked UsedImplicitly to keep refcount for delegate so that the function pointer remains valid.
[UsedImplicitly]
private PresentCoreDelegate? presentCoreDelegate;
// Use these instead of querying for functions inside the above,
// since we behave differently if ReShade or stuff are detected.
private PresentDelegate? presentOriginal;
private ResizeBuffersDelegate? resizeBuffersOriginal;
// can't access imgui IO before first present call
private bool lastWantCapture = false;
@ -87,11 +100,18 @@ internal class InterfaceManager : IDisposable, IServiceType
this.setCursorHook = Hook<SetCursorDelegate>.FromImport(
null, "user32.dll", "SetCursor", 0, this.SetCursorDetour);
this.fontBuildSignal = new ManualResetEvent(false);
var wndProcAddress = this.sigScanner.ScanText("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8");
Log.Information($"WndProc address 0x{wndProcAddress.ToInt64():X}");
this.processMessageHook = Hook<ProcessMessageDelegate>.FromAddress(wndProcAddress, this.ProcessMessageDetour);
this.address = new SwapChainVtableResolver();
this.fontBuildSignal = new(false);
this.QueueHookResolution();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate void PresentCoreDelegate(IntPtr swapChain);
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr PresentDelegate(IntPtr swapChain, uint syncInterval, uint presentFlags);
@ -110,22 +130,22 @@ internal class InterfaceManager : IDisposable, IServiceType
/// <summary>
/// This event gets called each frame to facilitate ImGui drawing.
/// </summary>
public event RawDX11Scene.BuildUIDelegate Draw;
public event RawDX11Scene.BuildUIDelegate? Draw;
/// <summary>
/// This event gets called when ResizeBuffers is called.
/// </summary>
public event Action ResizeBuffers;
public event Action? ResizeBuffers;
/// <summary>
/// Gets or sets an action that is executed right before fonts are rebuilt.
/// </summary>
public event Action BuildFonts;
public event Action? BuildFonts;
/// <summary>
/// Gets or sets an action that is executed right after fonts are rebuilt.
/// </summary>
public event Action AfterBuildFonts;
public event Action? AfterBuildFonts;
/// <summary>
/// Gets the default ImGui font.
@ -224,13 +244,13 @@ internal class InterfaceManager : IDisposable, IServiceType
this.framework.RunOnFrameworkThread(() =>
{
this.setCursorHook.Dispose();
this.presentHook?.Dispose();
this.resizeBuffersHook?.Dispose();
this.dispatchMessageWHook.Dispose();
this.processMessageHook?.Dispose();
this.processMessageHook.Dispose();
}).Wait();
this.scene?.Dispose();
this.swapChainHook?.Dispose();
}
#nullable enable
@ -408,9 +428,9 @@ internal class InterfaceManager : IDisposable, IServiceType
ImFontPtr foundFont = null;
unsafe
{
for (int i = 0, i_ = fonts.Size; i < i_; i++)
for (int i = 0, iTo = fonts.Size; i < iTo; i++)
{
if (!this.glyphRequests.Any(x => x.FontInternal.NativePtr == fonts[i].NativePtr))
if (this.glyphRequests.All(x => x.FontInternal.NativePtr != fonts[i].NativePtr))
continue;
allContained = true;
@ -513,8 +533,8 @@ internal class InterfaceManager : IDisposable, IServiceType
if (this.GameWindowHandle == nint.Zero)
return;
int value = enabled ? 1 : 0;
var hr = NativeFunctions.DwmSetWindowAttribute(
var value = enabled ? 1 : 0;
_ = NativeFunctions.DwmSetWindowAttribute(
this.GameWindowHandle,
NativeFunctions.DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE,
ref value,
@ -533,14 +553,14 @@ internal class InterfaceManager : IDisposable, IServiceType
{
try
{
newScene = new RawDX11Scene(swapChain);
newScene = new(swapChain);
}
catch (DllNotFoundException ex)
{
Service<InterfaceManagerWithScene>.ProvideException(ex);
Log.Error(ex, "Could not load ImGui dependencies.");
var res = PInvoke.User32.MessageBox(
var res = User32.MessageBox(
IntPtr.Zero,
"Dalamud plugins require the Microsoft Visual C++ Redistributable to be installed.\nPlease install the runtime from the official Microsoft website or disable Dalamud.\n\nDo you want to download the redistributable now?",
"Dalamud Error",
@ -565,14 +585,14 @@ internal class InterfaceManager : IDisposable, IServiceType
var startInfo = Service<DalamudStartInfo>.Get();
var configuration = Service<DalamudConfiguration>.Get();
var iniFileInfo = new FileInfo(Path.Combine(Path.GetDirectoryName(startInfo.ConfigurationPath), "dalamudUI.ini"));
var iniFileInfo = new FileInfo(Path.Combine(Path.GetDirectoryName(startInfo.ConfigurationPath)!, "dalamudUI.ini"));
try
{
if (iniFileInfo.Length > 1200000)
{
Log.Warning("dalamudUI.ini was over 1mb, deleting");
iniFileInfo.CopyTo(Path.Combine(iniFileInfo.DirectoryName, $"dalamudUI-{DateTimeOffset.Now.ToUnixTimeSeconds()}.ini"));
iniFileInfo.CopyTo(Path.Combine(iniFileInfo.DirectoryName!, $"dalamudUI-{DateTimeOffset.Now.ToUnixTimeSeconds()}.ini"));
iniFileInfo.Delete();
}
}
@ -652,32 +672,19 @@ internal class InterfaceManager : IDisposable, IServiceType
Service<InterfaceManagerWithScene>.Provide(new(this));
}
/*
* NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg.
* Seems to work fine regardless, I guess, so whatever.
*/
private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
private void PresentCore(IntPtr swapChain)
{
if (this.scene != null && swapChain != this.scene.SwapChain.NativePointer)
return this.presentHook!.Original(swapChain, syncInterval, presentFlags);
if (this.scene == null)
this.InitScene(swapChain);
if (this.address.IsReshade)
{
var pRes = this.presentHook.Original(swapChain, syncInterval, presentFlags);
this.RenderImGui();
this.DisposeTextures();
return pRes;
this.InitScene(swapChain);
}
else if (swapChain != this.scene.SwapChain.NativePointer)
{
return;
}
this.RenderImGui();
this.DisposeTextures();
return this.presentHook.Original(swapChain, syncInterval, presentFlags);
}
private void DisposeTextures()
@ -694,6 +701,101 @@ internal class InterfaceManager : IDisposable, IServiceType
}
}
/*
* NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg.
* Seems to work fine regardless, I guess, so whatever.
*/
private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
{
this.PresentCore(swapChain);
return this.presentOriginal!(swapChain, syncInterval, presentFlags);
}
private unsafe void QueueHookResolution()
{
if (this.GameWindowHandle != 0)
{
return;
}
this.framework.RunOnFrameworkThread(() =>
{
void* dxgiSwapChain;
try
{
var kernelDev = Util.NotNull(FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Device.Instance());
var swapChain = Util.NotNull(kernelDev->SwapChain);
dxgiSwapChain = Util.NotNull(swapChain->DXGISwapChain);
}
catch (ArgumentNullException)
{
// Try again later
return;
}
if (this.GameWindowHandle == 0)
{
while ((this.GameWindowHandle = NativeFunctions.FindWindowEx(IntPtr.Zero, this.GameWindowHandle, "FFXIVGAME", IntPtr.Zero)) != IntPtr.Zero)
{
_ = User32.GetWindowThreadProcessId(this.GameWindowHandle, out var pid);
if (pid == Environment.ProcessId && User32.IsWindowVisible(this.GameWindowHandle))
{
break;
}
}
}
if (this.GameWindowHandle == 0)
{
return;
}
try
{
if (Service<DalamudConfiguration>.Get().WindowIsImmersive)
{
this.SetImmersiveMode(true);
}
}
catch (Exception ex)
{
Log.Error(ex, "Could not enable immersive mode");
}
this.swapChainHook = new(dxgiSwapChain);
if (EntryPoint.TryRegisterReshadePresentCallback(
Marshal.GetFunctionPointerForDelegate(this.presentCoreDelegate = this.PresentCore)))
{
Log.Information("Using ReShade addon interface to provide implementation for Present.");
}
else
{
Log.Information("Using IDXGISwapChain VTable forging to provide implementation for Present.");
this.swapChainHook.SetVtableEntry(
IDXGISwapChainVtbl.Present,
this.PresentDetour,
out this.presentOriginal);
}
// Use ResizeBuffers, since we're hooking this just to be informed that it happened,
// and order does not matter whether we get called before or after ReShade.
this.swapChainHook.SetVtableEntry(
IDXGISwapChainVtbl.ResizeBuffers,
this.ResizeBuffersDetour,
out this.resizeBuffersOriginal);
this.swapChainHook.Enable();
Log.Information("Present and ResizeBuffers hooked");
this.setCursorHook.Enable();
this.dispatchMessageWHook.Enable();
this.processMessageHook.Enable();
Log.Information("Hooks enabled");
}).ContinueWith(_ => this.QueueHookResolution());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void RenderImGui()
{
@ -703,14 +805,14 @@ internal class InterfaceManager : IDisposable, IServiceType
// Check if we can still enable viewports without any issues.
this.CheckViewportState();
this.scene.Render();
this.scene!.Render();
}
private void CheckViewportState()
{
var configuration = Service<DalamudConfiguration>.Get();
if (configuration.IsDisableViewport || this.scene.SwapChain.IsFullScreen || ImGui.GetPlatformIO().Monitors.Size == 1)
if (configuration.IsDisableViewport || this.scene!.SwapChain.IsFullScreen || ImGui.GetPlatformIO().Monitors.Size == 1)
{
ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.ViewportsEnable;
return;
@ -779,7 +881,7 @@ internal class InterfaceManager : IDisposable, IServiceType
this.UseAxis ? TargetFontModification.AxisMode.Overwrite : TargetFontModification.AxisMode.GameGlyphsOnly,
this.UseAxis ? DefaultFontSizePx : DefaultFontSizePx + 1,
io.FontGlobalScale);
Log.Verbose("[FONT] SetupFonts - Default corresponding AXIS size: {0}pt ({1}px)", fontInfo.SourceAxis.Style.BaseSizePt, fontInfo.SourceAxis.Style.BaseSizePx);
Log.Verbose("[FONT] SetupFonts - Default corresponding AXIS size: {0}pt ({1}px)", fontInfo.SourceAxis?.Style.BaseSizePt, fontInfo.SourceAxis?.Style.BaseSizePx);
fontConfig.SizePixels = fontInfo.TargetSizePx * io.FontGlobalScale;
if (this.UseAxis)
{
@ -850,13 +952,15 @@ internal class InterfaceManager : IDisposable, IServiceType
foreach (var (fontSize, requests) in extraFontRequests)
{
List<Tuple<ushort, ushort>> codepointRanges = new();
codepointRanges.Add(Tuple.Create(Fallback1Codepoint, Fallback1Codepoint));
codepointRanges.Add(Tuple.Create(Fallback2Codepoint, Fallback2Codepoint));
// ImGui default ellipsis characters
codepointRanges.Add(Tuple.Create<ushort, ushort>(0x2026, 0x2026));
codepointRanges.Add(Tuple.Create<ushort, ushort>(0x0085, 0x0085));
List<Tuple<ushort, ushort>> codepointRanges = new()
{
new(Fallback1Codepoint, Fallback1Codepoint),
new(Fallback2Codepoint, Fallback2Codepoint),
// ImGui default ellipsis characters
new(0x2026, 0x2026),
new(0x0085, 0x0085),
};
foreach (var request in requests)
{
@ -890,7 +994,7 @@ internal class InterfaceManager : IDisposable, IServiceType
if (this.UseAxis)
{
fontConfig.GlyphRanges = dummyRangeHandle.AddrOfPinnedObject();
fontConfig.SizePixels = fontInfo.SourceAxis.Style.BaseSizePx;
fontConfig.SizePixels = fontInfo.SourceAxis!.Style.BaseSizePx;
fontConfig.PixelSnapH = false;
var sizedFont = ioFonts.AddFontDefault(fontConfig);
@ -920,7 +1024,7 @@ internal class InterfaceManager : IDisposable, IServiceType
this.BuildFonts?.InvokeSafely();
Log.Verbose("[FONT] OnBuildFonts OK!");
for (int i = customFontFirstConfigIndex, i_ = ioFonts.ConfigData.Size; i < i_; i++)
for (int i = customFontFirstConfigIndex, iTo = ioFonts.ConfigData.Size; i < iTo; i++)
{
var config = ioFonts.ConfigData[i];
if (gameFontManager.OwnsFont(config.DstFont))
@ -957,7 +1061,7 @@ internal class InterfaceManager : IDisposable, IServiceType
config.SizePixels = config.SizePixels * io.FontGlobalScale;
}
for (int i = 0, i_ = ioFonts.ConfigData.Size; i < i_; i++)
for (int i = 0, iTo = ioFonts.ConfigData.Size; i < iTo; i++)
{
var config = ioFonts.ConfigData[i];
config.RasterizerGamma *= fontGamma;
@ -1003,7 +1107,7 @@ internal class InterfaceManager : IDisposable, IServiceType
}
else if (mod.Axis == TargetFontModification.AxisMode.GameGlyphsOnly)
{
Log.Verbose("[FONT] {0}: Overwrite game specific glyphs from AXIS of size {1}px", mod.Name, mod.SourceAxis.ImFont.FontSize, font.FontSize);
Log.Verbose("[FONT] {0}: Overwrite game specific glyphs from AXIS of size {1}px (was {2}px)", mod.Name, mod.SourceAxis.ImFont.FontSize, font.FontSize);
if (!this.UseAxis && font.NativePtr == DefaultFont.NativePtr)
mod.SourceAxis.ImFont.FontSize -= 1;
ImGuiHelpers.CopyGlyphsAcrossFonts(mod.SourceAxis.ImFont, font, true, false, 0xE020, 0xE0DB);
@ -1018,7 +1122,7 @@ internal class InterfaceManager : IDisposable, IServiceType
// Fill missing glyphs in MonoFont from DefaultFont
ImGuiHelpers.CopyGlyphsAcrossFonts(DefaultFont, MonoFont, true, false);
for (int i = 0, i_ = ioFonts.Fonts.Size; i < i_; i++)
for (int i = 0, iTo = ioFonts.Fonts.Size; i < iTo; i++)
{
var font = ioFonts.Fonts[i];
if (font.Glyphs.Size == 0)
@ -1056,49 +1160,6 @@ internal class InterfaceManager : IDisposable, IServiceType
}
}
[ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(SigScanner sigScanner, Framework framework)
{
this.address.Setup(sigScanner);
framework.RunOnFrameworkThread(() =>
{
while ((this.GameWindowHandle = NativeFunctions.FindWindowEx(IntPtr.Zero, this.GameWindowHandle, "FFXIVGAME", IntPtr.Zero)) != IntPtr.Zero)
{
_ = User32.GetWindowThreadProcessId(this.GameWindowHandle, out var pid);
if (pid == Environment.ProcessId && User32.IsWindowVisible(this.GameWindowHandle))
break;
}
try
{
if (Service<DalamudConfiguration>.Get().WindowIsImmersive)
this.SetImmersiveMode(true);
}
catch (Exception ex)
{
Log.Error(ex, "Could not enable immersive mode");
}
this.presentHook = Hook<PresentDelegate>.FromAddress(this.address.Present, this.PresentDetour);
this.resizeBuffersHook = Hook<ResizeBuffersDelegate>.FromAddress(this.address.ResizeBuffers, this.ResizeBuffersDetour);
Log.Verbose("===== S W A P C H A I N =====");
Log.Verbose($"Present address 0x{this.presentHook!.Address.ToInt64():X}");
Log.Verbose($"ResizeBuffers address 0x{this.resizeBuffersHook!.Address.ToInt64():X}");
var wndProcAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8");
Log.Verbose($"WndProc address 0x{wndProcAddress.ToInt64():X}");
this.processMessageHook = Hook<ProcessMessageDelegate>.FromAddress(wndProcAddress, this.ProcessMessageDetour);
this.setCursorHook.Enable();
this.presentHook.Enable();
this.resizeBuffersHook.Enable();
this.dispatchMessageWHook.Enable();
this.processMessageHook.Enable();
});
}
// This is intended to only be called as a handler attached to scene.OnNewRenderFrame
private void RebuildFontsInternal()
{
@ -1119,7 +1180,7 @@ internal class InterfaceManager : IDisposable, IServiceType
private unsafe IntPtr ProcessMessageDetour(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled)
{
var ime = Service<DalamudIME>.GetNullable();
var res = ime?.ProcessWndProcW(hWnd, (User32.WindowMessage)msg, (void*)wParam, (void*)lParam);
_ = ime?.ProcessWndProcW(hWnd, (User32.WindowMessage)msg, (void*)wParam, (void*)lParam);
return this.processMessageHook.Original(hWnd, msg, wParam, lParam, handeled);
}
@ -1143,14 +1204,9 @@ internal class InterfaceManager : IDisposable, IServiceType
this.ResizeBuffers?.InvokeSafely();
// We have to ensure we're working with the main swapchain,
// as viewports might be resizing as well
if (this.scene == null || swapChain != this.scene.SwapChain.NativePointer)
return this.resizeBuffersHook!.Original(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
this.scene?.OnPreResize();
var ret = this.resizeBuffersHook!.Original(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
var ret = this.resizeBuffersOriginal!(swapChain, bufferCount, width, height, newFormat, swapChainFlags);
if (ret.ToInt64() == 0x887A0001)
{
Log.Error("invalid call to resizeBuffers");
@ -1163,7 +1219,7 @@ internal class InterfaceManager : IDisposable, IServiceType
private IntPtr SetCursorDetour(IntPtr hCursor)
{
if (this.lastWantCapture == true && (!this.scene?.IsImGuiCursor(hCursor) ?? false) && this.OverrideGameCursor)
if (this.lastWantCapture && (!this.scene?.IsImGuiCursor(hCursor) ?? false) && this.OverrideGameCursor)
return IntPtr.Zero;
return this.setCursorHook.IsDisposed ? User32.SetCursor(new User32.SafeCursorHandle(hCursor, false)).DangerousGetHandle() : this.setCursorHook.Original(hCursor);

View file

@ -137,6 +137,7 @@ internal static partial class NativeFunctions
/// <summary>
/// MB_* from winuser.
/// </summary>
[Flags]
public enum MessageBoxType : uint
{
/// <summary>

View file

@ -546,6 +546,44 @@ public static class Util
/// <returns>If Windows 11 has been detected.</returns>
public static bool IsWindows11() => Environment.OSVersion.Version.Build >= 22000;
/// <summary>
/// Ensures that a pointer is not null, or throw a <see cref="NullReferenceException" />
/// </summary>
/// <param name="value">Pointer value.</param>
/// <param name="what">Help text for exception.</param>
/// <typeparam name="T">Backing data type of the pointer.</typeparam>
/// <returns>The value, ensured to be not null.</returns>
public static unsafe T* NotNull<T>(T* value, string what)
where T : unmanaged
=> value == null ? throw new NullReferenceException($"{what} is null.") : value;
/// <summary>
/// Ensures that a pointer is not null, or throw a <see cref="NullReferenceException" />
/// </summary>
/// <param name="value">Pointer value.</param>
/// <param name="what">Help text for exception.</param>
/// <returns>The value, ensured to be not null.</returns>
public static unsafe void* NotNull(void* value, string what)
=> value == null ? throw new NullReferenceException($"{what} is null.") : value;
/// <summary>
/// Ensures that a pointer is not null, or throw a <see cref="NullReferenceException" />
/// </summary>
/// <param name="value">Pointer value.</param>
/// <typeparam name="T">Backing data type of the pointer.</typeparam>
/// <returns>The value, ensured to be not null.</returns>
public static unsafe T* NotNull<T>(T* value)
where T : unmanaged
=> value == null ? throw new NullReferenceException() : value;
/// <summary>
/// Ensures that a pointer is not null, or throw a <see cref="NullReferenceException" />
/// </summary>
/// <param name="value">Pointer value.</param>
/// <returns>The value, ensured to be not null.</returns>
public static unsafe void* NotNull(void* value)
=> value == null ? throw new NullReferenceException() : value;
/// <summary>
/// Open a link in the default browser.
/// </summary>

View file

@ -0,0 +1,346 @@
/*
* Copyright (C) 2021 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause OR MIT
*/
#pragma once
#include "reshade_events.hpp"
#include "reshade_overlay.hpp"
#include <charconv>
#include <Windows.h>
// Current version of the ReShade API
#define RESHADE_API_VERSION 8
// Optionally import ReShade API functions when 'RESHADE_API_LIBRARY' is defined instead of using header-only mode
#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT)
#ifdef RESHADE_API_LIBRARY_EXPORT
#define RESHADE_API_LIBRARY_DECLSPEC extern "C" __declspec(dllexport)
#else
#define RESHADE_API_LIBRARY_DECLSPEC extern "C" __declspec(dllimport)
#endif
RESHADE_API_LIBRARY_DECLSPEC void ReShadeLogMessage(HMODULE module, int level, const char *message);
RESHADE_API_LIBRARY_DECLSPEC void ReShadeGetBasePath(char *path, size_t *path_size);
RESHADE_API_LIBRARY_DECLSPEC bool ReShadeGetConfigValue(HMODULE module, reshade::api::effect_runtime *runtime, const char *section, const char *key, char *value, size_t *value_size);
RESHADE_API_LIBRARY_DECLSPEC void ReShadeSetConfigValue(HMODULE module, reshade::api::effect_runtime *runtime, const char *section, const char *key, const char *value);
RESHADE_API_LIBRARY_DECLSPEC bool ReShadeRegisterAddon(HMODULE module, uint32_t api_version);
RESHADE_API_LIBRARY_DECLSPEC void ReShadeUnregisterAddon(HMODULE module);
RESHADE_API_LIBRARY_DECLSPEC void ReShadeRegisterEvent(reshade::addon_event ev, void *callback);
RESHADE_API_LIBRARY_DECLSPEC void ReShadeUnregisterEvent(reshade::addon_event ev, void *callback);
RESHADE_API_LIBRARY_DECLSPEC void ReShadeRegisterOverlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime));
RESHADE_API_LIBRARY_DECLSPEC void ReShadeUnregisterOverlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime));
#else
// Use the kernel32 variant of module enumeration functions so it can be safely called from 'DllMain'
extern "C" BOOL WINAPI K32EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded);
namespace reshade { namespace internal
{
/// <summary>
/// Gets the handle to the ReShade module.
/// </summary>
inline HMODULE get_reshade_module_handle(HMODULE reshade_module = nullptr)
{
static HMODULE handle = reshade_module;
if (handle == nullptr)
{
HMODULE modules[1024]; DWORD num = 0;
if (K32EnumProcessModules(GetCurrentProcess(), modules, sizeof(modules), &num))
{
if (num > sizeof(modules))
num = sizeof(modules);
for (DWORD i = 0; i < num / sizeof(HMODULE); ++i)
{
if (GetProcAddress(modules[i], "ReShadeRegisterAddon") &&
GetProcAddress(modules[i], "ReShadeUnregisterAddon"))
{
handle = modules[i];
break;
}
}
}
}
return handle;
}
/// <summary>
/// Gets the handle to the current add-on module.
/// </summary>
inline HMODULE get_current_module_handle(HMODULE addon_module = nullptr)
{
static HMODULE handle = addon_module;
return handle;
}
} }
#endif
namespace reshade
{
/// <summary>
/// Available log severity levels.
/// </summary>
enum class log_level
{
error = 1,
warning = 2,
info = 3,
debug = 4
};
/// <summary>
/// Writes a message to ReShade's log.
/// </summary>
/// <param name="level">Severity level.</param>
/// <param name="message">A null-terminated message string.</param>
inline void log_message(log_level level, const char *message)
{
#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT)
ReShadeLogMessage(nullptr, static_cast<int>(level), message);
#else
static const auto func = reinterpret_cast<void(*)(HMODULE, int, const char *)>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeLogMessage"));
func(internal::get_current_module_handle(), static_cast<int>(level), message);
#endif
}
/// <summary>
/// Gets the file path ReShade uses to resolve relative paths.
/// </summary>
/// <param name="path">Pointer to a string buffer that is filled with the file path to the preset, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="path_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
inline void get_reshade_base_path(char *path, size_t *path_size)
{
#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT)
ReShadeGetBasePath(path, path_size);
#else
static const auto func = reinterpret_cast<bool(*)(char *, size_t *)>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeGetBasePath"));
func(path, path_size);
#endif
}
/// <summary>
/// Gets a value from one of ReShade's config files.
/// </summary>
/// <param name="runtime">Optional effect runtime to use the config file from, or <see langword="nullptr"/> to use the global config file.</param>
/// <param name="section">Name of the config section.</param>
/// <param name="key">Name of the config value.</param>
/// <param name="value">Pointer to a string buffer that is filled with the config value, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="value_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
/// <returns><see langword="true"/> if the specified config value exists, <see cref="false"/> otherwise.</returns>
inline bool get_config_value(api::effect_runtime *runtime, const char *section, const char *key, char *value, size_t *value_size)
{
#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT)
return ReShadeGetConfigValue(nullptr, runtime, section, key, value, value_size);
#else
static const auto func = reinterpret_cast<bool(*)(HMODULE, api::effect_runtime *, const char *, const char *, char *, size_t *)>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeGetConfigValue"));
return func(internal::get_current_module_handle(), runtime, section, key, value, value_size);
#endif
}
#if _HAS_CXX17
template <typename T>
inline bool get_config_value(api::effect_runtime *runtime, const char *section, const char *key, T &value)
{
char value_string[32]; size_t value_length = sizeof(value_string) - 1;
if (!get_config_value(runtime, section, key, value_string, &value_length))
return false;
return std::from_chars(value_string, value_string + value_length, value).ec == std::errc {};
}
template <>
inline bool get_config_value<bool>(api::effect_runtime *runtime, const char *section, const char *key, bool &value)
{
int value_int = 0;
if (!get_config_value<int>(runtime, section, key, value_int))
return false;
value = (value_int != 0);
return true;
}
#endif
/// <summary>
/// Sets and saves a value in one of ReShade's config files.
/// </summary>
/// <param name="runtime">Optional effect runtime to use the config file from, or <see langword="nullptr"/> to use the global config file.</param>
/// <param name="section">Name of the config section.</param>
/// <param name="key">Name of the config value.</param>
/// <param name="value">Config value to set.</param>
inline void set_config_value(api::effect_runtime *runtime, const char *section, const char *key, const char *value)
{
#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT)
ReShadeSetConfigValue(nullptr, runtime, section, key, value);
#else
static const auto func = reinterpret_cast<void(*)(HMODULE, api::effect_runtime *, const char *, const char *, const char *)>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeSetConfigValue"));
func(internal::get_current_module_handle(), runtime, section, key, value);
#endif
}
#if _HAS_CXX17
template <typename T>
inline void set_config_value(api::effect_runtime *runtime, const char *section, const char *key, const T &value)
{
char value_string[32] = "";
std::to_chars(value_string, value_string + sizeof(value_string) - 1, value);
set_config_value(runtime, section, key, static_cast<const char *>(value_string));
}
template <>
inline void set_config_value<bool>(api::effect_runtime *runtime, const char *section, const char *key, const bool &value)
{
set_config_value<int>(runtime, section, key, value ? 1 : 0);
}
#endif
/// <summary>
/// Registers this module as an add-on with ReShade.
/// Call this in 'AddonInit' or 'DllMain' during process attach, before any of the other API functions!
/// </summary>
/// <param name="addon_module">Handle of the current module.</param>
/// <param name="reshade_module">Handle of the ReShade module in the process, or <see langword="nullptr"/> to find it automatically.</param>
inline bool register_addon(HMODULE addon_module, [[maybe_unused]] HMODULE reshade_module = nullptr)
{
#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON)
return ReShadeRegisterAddon(addon_module, RESHADE_API_VERSION);
#elif !defined(RESHADE_API_LIBRARY_EXPORT)
addon_module = internal::get_current_module_handle(addon_module);
reshade_module = internal::get_reshade_module_handle(reshade_module);
if (reshade_module == nullptr)
return false;
const auto func = reinterpret_cast<bool(*)(HMODULE, uint32_t)>(
GetProcAddress(reshade_module, "ReShadeRegisterAddon"));
// Check that the ReShade module supports the used API
if (func == nullptr || !func(addon_module, RESHADE_API_VERSION))
return false;
#if defined(IMGUI_VERSION_NUM)
const auto imgui_func = reinterpret_cast<const imgui_function_table *(*)(uint32_t)>(
GetProcAddress(reshade_module, "ReShadeGetImGuiFunctionTable"));
// Check that the ReShade module was built with Dear ImGui support and supports the used version
if (imgui_func == nullptr || !(imgui_function_table_instance() = imgui_func(IMGUI_VERSION_NUM)))
return false;
#endif
return true;
#else
UNREFERENCED_PARAMETER(addon_module);
UNREFERENCED_PARAMETER(reshade_module);
return false;
#endif
}
/// <summary>
/// Unregisters this module.
/// Call this in 'AddonUninit' or 'DllMain' during process detach, after any of the other API functions.
/// </summary>
/// <param name="addon_module">Handle of the current module.</param>
/// <param name="reshade_module">Handle of the ReShade module in the process, or <see langword="nullptr"/> to find it automatically.</param>
inline void unregister_addon(HMODULE addon_module, [[maybe_unused]] HMODULE reshade_module = nullptr)
{
#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON)
ReShadeUnregisterAddon(addon_module);
#elif !defined(RESHADE_API_LIBRARY_EXPORT)
addon_module = internal::get_current_module_handle(addon_module);
reshade_module = internal::get_reshade_module_handle(reshade_module);
if (reshade_module == nullptr)
return;
const auto func = reinterpret_cast<bool(*)(HMODULE)>(
GetProcAddress(reshade_module, "ReShadeUnregisterAddon"));
if (func != nullptr)
func(addon_module);
#else
UNREFERENCED_PARAMETER(addon_module);
UNREFERENCED_PARAMETER(reshade_module);
#endif
}
/// <summary>
/// Registers a callback for the specified event (via template) with ReShade.
/// <para>The callback function is then called whenever the application performs a task associated with this event (see also the <see cref="addon_event"/> enumeration).</para>
/// </summary>
/// <param name="callback">Pointer to the callback function.</param>
template <reshade::addon_event ev>
inline void register_event(typename reshade::addon_event_traits<ev>::decl callback)
{
#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON)
ReShadeRegisterEvent(ev, static_cast<void *>(callback));
#elif !defined(RESHADE_API_LIBRARY_EXPORT)
static const auto func = reinterpret_cast<void(*)(reshade::addon_event, void *)>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeRegisterEvent"));
if (func != nullptr)
func(ev, static_cast<void *>(callback));
#else
UNREFERENCED_PARAMETER(callback);
#endif
}
/// <summary>
/// Unregisters a callback for the specified event (via template) that was previously registered via <see cref="register_event"/>.
/// </summary>
/// <param name="callback">Pointer to the callback function.</param>
template <reshade::addon_event ev>
inline void unregister_event(typename reshade::addon_event_traits<ev>::decl callback)
{
#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON)
ReShadeUnregisterEvent(ev, static_cast<void *>(callback));
#elif !defined(RESHADE_API_LIBRARY_EXPORT)
static const auto func = reinterpret_cast<void(*)(reshade::addon_event, void *)>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeUnregisterEvent"));
if (func != nullptr)
func(ev, static_cast<void *>(callback));
#else
UNREFERENCED_PARAMETER(callback);
#endif
}
/// <summary>
/// Registers an overlay with ReShade.
/// <para>The callback function is then called when the overlay is visible and allows adding Dear ImGui widgets for user interaction.</para>
/// </summary>
/// <param name="title">Null-terminated title string, or <see langword="nullptr"/> to register a settings overlay for this add-on.</param>
/// <param name="callback">Pointer to the callback function.</param>
inline void register_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime))
{
#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON && RESHADE_GUI)
ReShadeRegisterOverlay(title, callback);
#elif !defined(RESHADE_API_LIBRARY_EXPORT)
static const auto func = reinterpret_cast<void(*)(const char *, void(*)(reshade::api::effect_runtime *))>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeRegisterOverlay"));
if (func != nullptr)
func(title, callback);
#else
UNREFERENCED_PARAMETER(title);
UNREFERENCED_PARAMETER(callback);
#endif
}
/// <summary>
/// Unregisters an overlay that was previously registered via <see cref="register_overlay"/>.
/// </summary>
/// <param name="title">Null-terminated title string.</param>
/// <param name="callback">Pointer to the callback function.</param>
inline void unregister_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime))
{
#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON && RESHADE_GUI)
ReShadeUnregisterOverlay(title, callback);
#elif !defined(RESHADE_API_LIBRARY_EXPORT)
static const auto func = reinterpret_cast<void(*)(const char *, void(*)(reshade::api::effect_runtime *))>(
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeUnregisterOverlay"));
if (func != nullptr)
func(title, callback);
#else
UNREFERENCED_PARAMETER(title);
UNREFERENCED_PARAMETER(callback);
#endif
}
}

View file

@ -0,0 +1,726 @@
/*
* Copyright (C) 2021 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause OR MIT
*/
#pragma once
#include "reshade_api_device.hpp"
namespace reshade { namespace api
{
/// <summary>
/// An opaque handle to a technique in an effect.
/// </summary>
/// <remarks>
/// This handle is only valid until effects are next reloaded again (<see cref="addon_event::reshade_reloaded_effects"/>).
/// </remarks>
RESHADE_DEFINE_HANDLE(effect_technique);
/// <summary>
/// An opaque handle to a texture variable in an effect.
/// </summary>
/// <remarks>
/// This handle is only valid until effects are next reloaded again (<see cref="addon_event::reshade_reloaded_effects"/>).
/// </remarks>
RESHADE_DEFINE_HANDLE(effect_texture_variable);
/// <summary>
/// An opaque handle to a uniform variable in an effect.
/// </summary>
/// <remarks>
/// This handle is only valid until effects are next reloaded again (<see cref="addon_event::reshade_reloaded_effects"/>).
/// </remarks>
RESHADE_DEFINE_HANDLE(effect_uniform_variable);
/// <summary>
/// A ReShade effect runtime, used to control effects.
/// <para>A separate runtime is instantiated for every swap chain.</para>
/// </summary>
struct __declspec(novtable) effect_runtime : public swapchain
{
/// <summary>
/// Gets the main graphics command queue associated with this effect runtime.
/// This may potentially be different from the presentation queue and should be used to execute graphics commands on.
/// </summary>
virtual command_queue *get_command_queue() = 0;
/// <summary>
/// Applies post-processing effects to the specified render targets and prevents the usual rendering of effects before swap chain presentation of the current frame.
/// This can be used to force ReShade to render effects at a certain point during the frame to e.g. avoid effects being applied to user interface elements of the application.
/// </summary>
/// <remarks>
/// The resource the render target views point to has to be in the <see cref="resource_usage::render_target"/> state.
/// This call may modify current state on the command list (pipeline, render targets, descriptor tables, ...), so it may be necessary for an add-on to backup and restore state around it if the application does not bind all state again afterwards already.
/// Calling this with <paramref name="rtv"/> set to zero will cause nothing to be rendered, but uniform variables to still be updated.
/// </remarks>
/// <param name="cmd_list">Command list to add effect rendering commands to.</param>
/// <param name="rtv">Render target view to use for passes that write to the back buffer with <c>SRGBWriteEnabled</c> state set to <see langword="false"/>.</param>
/// <param name="rtv_srgb">Render target view to use for passes that write to the back buffer with <c>SRGBWriteEnabled</c> state set to <see langword="true"/>, or zero in which case the view from <paramref name="rtv"/> is used.</param>
virtual void render_effects(command_list *cmd_list, resource_view rtv, resource_view rtv_srgb = { 0 }) = 0;
/// <summary>
/// Captures a screenshot of the current back buffer resource and returns its image data in 32 bits-per-pixel RGBA format.
/// </summary>
/// <param name="pixels">Pointer to an array of <c>width * height * 4</c> bytes the image data is written to.</param>
virtual bool capture_screenshot(uint8_t *pixels) = 0;
/// <summary>
/// Gets the current buffer dimensions of the swap chain.
/// </summary>
virtual void get_screenshot_width_and_height(uint32_t *out_width, uint32_t *out_height) const = 0;
/// <summary>
/// Gets the current status of the specified key.
/// </summary>
/// <param name="keycode">The virtual key code to check.</param>
/// <returns><see langword="true"/> if the key is currently pressed down, <see langword="false"/> otherwise.</returns>
virtual bool is_key_down(uint32_t keycode) const = 0;
/// <summary>
/// Gets whether the specified key was pressed this frame.
/// </summary>
/// <param name="keycode">The virtual key code to check.</param>
/// <returns><see langword="true"/> if the key was pressed this frame, <see langword="false"/> otherwise.</returns>
virtual bool is_key_pressed(uint32_t keycode) const = 0;
/// <summary>
/// Gets whether the specified key was released this frame.
/// </summary>
/// <param name="keycode">The virtual key code to check.</param>
/// <returns><see langword="true"/> if the key was released this frame, <see langword="false"/> otherwise.</returns>
virtual bool is_key_released(uint32_t keycode) const = 0;
/// <summary>
/// Gets the current status of the specified mouse button.
/// </summary>
/// <param name="button">The mouse button index to check (0 = left, 1 = middle, 2 = right).</param>
/// <returns><see langword="true"/> if the mouse button is currently pressed down, <see langword="false"/> otherwise.</returns>
virtual bool is_mouse_button_down(uint32_t button) const = 0;
/// <summary>
/// Gets whether the specified mouse button was pressed this frame.
/// </summary>
/// <param name="button">The mouse button index to check (0 = left, 1 = middle, 2 = right).</param>
/// <returns><see langword="true"/> if the mouse button was pressed this frame, <see langword="false"/> otherwise.</returns>
virtual bool is_mouse_button_pressed(uint32_t button) const = 0;
/// <summary>
/// Gets whether the specified mouse button was released this frame.
/// </summary>
/// <param name="button">The mouse button index to check (0 = left, 1 = middle, 2 = right).</param>
/// <returns><see langword="true"/> if the mouse button was released this frame, <see langword="false"/> otherwise.</returns>
virtual bool is_mouse_button_released(uint32_t button) const = 0;
/// <summary>
/// Gets the current absolute position of the mouse cursor in screen coordinates.
/// </summary>
/// <param name="out_x">Pointer to a variable that is set to the X coordinate of the current cursor position.</param>
/// <param name="out_y">Pointer to a variable that is set to the Y coordinate of the current cursor position.</param>
/// <param name="out_wheel_delta">Optional pointer to a variable that is set to the mouse wheel delta since the last frame.</param>
virtual void get_mouse_cursor_position(uint32_t *out_x, uint32_t *out_y, int16_t *out_wheel_delta = nullptr) const = 0;
/// <summary>
/// Enumerates all uniform variables of loaded effects and calls the specified <paramref name="callback"/> function with a handle for each one.
/// </summary>
/// <param name="effect_name">File name of the effect file to enumerate uniform variables from, or <see langword="nullptr"/> to enumerate those of all loaded effects.</param>
/// <param name="callback">Function to call for every uniform variable.</param>
/// <param name="user_data">Optional pointer passed to the callback function.</param>
virtual void enumerate_uniform_variables(const char *effect_name, void(*callback)(effect_runtime *runtime, effect_uniform_variable variable, void *user_data), void *user_data) = 0;
/// <summary>
/// Enumerates all uniform variables of loaded effects and calls the specified callback function with a handle for each one.
/// </summary>
/// <param name="effect_name">File name of the effect file to enumerate uniform variables from, or <see langword="nullptr"/> to enumerate those of all loaded effects.</param>
/// <param name="lambda">Function to call for every uniform variable.</param>
template <typename F>
inline void enumerate_uniform_variables(const char *effect_name, F lambda)
{
enumerate_uniform_variables(effect_name, [](effect_runtime *runtime, effect_uniform_variable variable, void *user_data) { static_cast<F *>(user_data)->operator()(runtime, variable); }, &lambda);
}
/// <summary>
/// Finds a specific uniform variable in the loaded effects and returns a handle to it.
/// </summary>
/// <param name="effect_name">File name of the effect file the variable is declared in, or <see langword="nullptr"/> to search in all loaded effects.</param>
/// <param name="variable_name">Name of the uniform variable declaration to find.</param>
/// <returns>Opaque handle to the uniform variable, or zero in case it was not found.</returns>
virtual effect_uniform_variable find_uniform_variable(const char *effect_name, const char *variable_name) const = 0;
/// <summary>
/// Gets information about the data type of a uniform <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="out_base_type">Optional pointer to a variable that is set to the base type of the uniform variable (<see cref="format::r32_typeless"/>, <see cref="format::r32_sint"/>, <see cref="format::r32_uint"/> or <see cref="format::r32_float"/>).</param>
/// <param name="out_rows">Optional pointer to a variable that is set to the number of vector rows of the uniform variable type.</param>
/// <param name="out_columns">Optional pointer to a variable that is set to the number of matrix column of the uniform variable type.</param>
/// <param name="out_array_length">Optional pointer to a variable that is set to the number of array elements of the uniform variable type.</param>
virtual void get_uniform_variable_type(effect_uniform_variable variable, format *out_base_type, uint32_t *out_rows = nullptr, uint32_t *out_columns = nullptr, uint32_t *out_array_length = nullptr) const = 0;
/// <summary>
/// Gets the name of a uniform <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="name">Pointer to a string buffer that is filled with the name of the uniform variable, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="name_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_uniform_variable_name(effect_uniform_variable variable, char *name, size_t *name_size) const = 0;
template <size_t SIZE>
inline void get_uniform_variable_name(effect_uniform_variable variable, char(&name)[SIZE]) const
{
size_t name_size = SIZE;
get_uniform_variable_name(variable, name, &name_size);
}
/// <summary>
/// Gets the value from an annotation attached to the specified uniform <paramref name="variable"/> as boolean values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of booleans that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_bool_from_uniform_variable(effect_uniform_variable variable, const char *name, bool *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified uniform <paramref name="variable"/> as floating-point values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of floating-points that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_float_from_uniform_variable(effect_uniform_variable variable, const char *name, float *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified uniform <paramref name="variable"/> as signed integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of signed integers that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_int_from_uniform_variable(effect_uniform_variable variable, const char *name, int32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified uniform <paramref name="variable"/> as unsigned integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of unsigned integers that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_uint_from_uniform_variable(effect_uniform_variable variable, const char *name, uint32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from a string annotation attached to the specified uniform <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="value">Pointer to a string buffer that is filled with the value of the annotation, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="value_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual bool get_annotation_string_from_uniform_variable(effect_uniform_variable variable, const char *name, char *value, size_t *value_size) const = 0;
template <size_t SIZE>
inline bool get_annotation_string_from_uniform_variable(effect_uniform_variable variable, const char *name, char(&value)[SIZE]) const
{
size_t value_size = SIZE;
return get_annotation_string_from_uniform_variable(variable, name, value, &value_size);
}
/// <summary>
/// Gets the value of the specified uniform <paramref name="variable"/> as boolean values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of booleans that is filled with the values of this uniform variable.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when this uniform variable is an array variable.</param>
virtual void get_uniform_value_bool(effect_uniform_variable variable, bool *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value of the specified uniform <paramref name="variable"/> as floating-point values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of floating-points that is filled with the values of this uniform variable.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when this uniform variable is an array variable.</param>
virtual void get_uniform_value_float(effect_uniform_variable variable, float *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value of the specified uniform <paramref name="variable"/> as signed integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of signed integers that is filled with the values of this uniform variable.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when this uniform variable is an array variable.</param>
virtual void get_uniform_value_int(effect_uniform_variable variable, int32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value of the specified uniform <paramref name="variable"/> as unsigned integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of unsigned integers that is filled with the values of this uniform variable.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when this uniform variable is an array variable.</param>
virtual void get_uniform_value_uint(effect_uniform_variable variable, uint32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as boolean values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of booleans that are used to update this uniform variable.</param>
/// <param name="count">Number of values to write.</param>
/// <param name="array_index">Array offset to start writing values to when this uniform variable is an array variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
virtual void set_uniform_value_bool(effect_uniform_variable variable, const bool *values, size_t count, size_t array_index = 0) = 0;
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as a vector of boolean values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="x">Value of the first component in the vector that is used to update this uniform variable.</param>
/// <param name="y">Optional value of the second component in the vector that is used to update this uniform variable.</param>
/// <param name="z">Optional value of the third component in the vector that is used to update this uniform variable.</param>
/// <param name="w">Optional value of the fourth component in the vector that is used to update this uniform variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
inline void set_uniform_value_bool(effect_uniform_variable variable, bool x, bool y = bool(0), bool z = bool(0), bool w = bool(0))
{
const bool values[4] = { x, y, z, w };
set_uniform_value_bool(variable, values, 4);
}
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as floating-point values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of floating-points that are used to update this uniform variable.</param>
/// <param name="count">Number of values to write.</param>
/// <param name="array_index">Array offset to start writing values to when this uniform variable is an array variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
virtual void set_uniform_value_float(effect_uniform_variable variable, const float *values, size_t count, size_t array_index = 0) = 0;
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as a vector of floating-point values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="x">Value of the first component in the vector that is used to update this uniform variable.</param>
/// <param name="y">Optional value of the second component in the vector that is used to update this uniform variable.</param>
/// <param name="z">Optional value of the third component in the vector that is used to update this uniform variable.</param>
/// <param name="w">Optional value of the fourth component in the vector that is used to update this uniform variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
inline void set_uniform_value_float(effect_uniform_variable variable, float x, float y = float(0), float z = float(0), float w = float(0))
{
const float values[4] = { x, y, z, w };
set_uniform_value_float(variable, values, 4);
}
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as signed integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of signed integers that are used to update this uniform variable.</param>
/// <param name="count">Number of values to write.</param>
/// <param name="array_index">Array offset to start writing values to when this uniform variable is an array variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
virtual void set_uniform_value_int(effect_uniform_variable variable, const int32_t *values, size_t count, size_t array_index = 0) = 0;
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as a vector of signed integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="x">Value of the first component in the vector that is used to update this uniform variable.</param>
/// <param name="y">Optional value of the second component in the vector that is used to update this uniform variable.</param>
/// <param name="z">Optional value of the third component in the vector that is used to update this uniform variable.</param>
/// <param name="w">Optional value of the fourth component in the vector that is used to update this uniform variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
inline void set_uniform_value_int(effect_uniform_variable variable, int32_t x, int32_t y = int32_t(0), int32_t z = int32_t(0), int32_t w = int32_t(0))
{
const int32_t values[4] = { x, y, z, w };
set_uniform_value_int(variable, values, 4);
}
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as unsigned integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="values">Pointer to an array of unsigned integers that are used to update this uniform variable.</param>
/// <param name="count">Number of values to write.</param>
/// <param name="array_index">Array offset to start writing values to when this uniform variable is an array variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
virtual void set_uniform_value_uint(effect_uniform_variable variable, const uint32_t *values, size_t count, size_t array_index = 0) = 0;
/// <summary>
/// Sets the value of the specified uniform <paramref name="variable"/> as a vector of unsigned integer values.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="x">Value of the first component in the vector that is used to update this uniform variable.</param>
/// <param name="y">Optional value of the second component in the vector that is used to update this uniform variable.</param>
/// <param name="z">Optional value of the third component in the vector that is used to update this uniform variable.</param>
/// <param name="w">Optional value of the fourth component in the vector that is used to update this uniform variable.</param>
/// <remarks>Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value
/// is saved to disk, call <see cref="save_current_preset"/></remarks>
inline void set_uniform_value_uint(effect_uniform_variable variable, uint32_t x, uint32_t y = uint32_t(0), uint32_t z = uint32_t(0), uint32_t w = uint32_t(0))
{
const uint32_t values[4] = { x, y, z, w };
set_uniform_value_uint(variable, values, 4);
}
/// <summary>
/// Enumerates all texture variables of loaded effects and calls the specified <paramref name="callback"/> function with a handle for each one.
/// </summary>
/// <param name="effect_name">File name of the effect file to enumerate texture variables from, or <see langword="nullptr"/> to enumerate those of all loaded effects.</param>
/// <param name="callback">Function to call for every texture variable.</param>
/// <param name="user_data">Optional pointer passed to the callback function.</param>
virtual void enumerate_texture_variables(const char *effect_name, void(*callback)(effect_runtime *runtime, effect_texture_variable variable, void *user_data), void *user_data) = 0;
/// <summary>
/// Enumerates all texture variables of loaded effects and calls the specified callback function with a handle for each one.
/// </summary>
/// <param name="effect_name">File name of the effect file to enumerate texture variables from, or <see langword="nullptr"/> to enumerate those of all loaded effects.</param>
/// <param name="lambda">Function to call for every texture variable.</param>
template <typename F>
inline void enumerate_texture_variables(const char *effect_name, F lambda)
{
enumerate_texture_variables(effect_name, [](effect_runtime *runtime, effect_texture_variable variable, void *user_data) { static_cast<F *>(user_data)->operator()(runtime, variable); }, &lambda);
}
/// <summary>
/// Finds a specific texture variable in the loaded effects and returns a handle to it.
/// </summary>
/// <param name="effect_name">File name of the effect file the variable is declared in, or <see langword="nullptr"/> to search in all loaded effects.</param>
/// <param name="variable_name">Name of the texture variable declaration to find.</param>
/// <returns>Opaque handle to the texture variable, or zero in case it was not found.</returns>
virtual effect_texture_variable find_texture_variable(const char *effect_name, const char *variable_name) const = 0;
/// <summary>
/// Gets the name of a texture <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="name">Pointer to a string buffer that is filled with the name of the texture variable, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="name_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_texture_variable_name(effect_texture_variable variable, char *name, size_t *name_size) const = 0;
template <size_t SIZE>
inline void get_texture_variable_name(effect_texture_variable variable, char(&name)[SIZE]) const
{
size_t name_size = SIZE;
get_texture_variable_name(variable, name, &name_size);
}
/// <summary>
/// Gets the value from an annotation attached to the specified texture <paramref name="variable"/> as boolean values.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of booleans that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_bool_from_texture_variable(effect_texture_variable variable, const char *name, bool *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified texture <paramref name="variable"/> as floating-point values.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of floating-points that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_float_from_texture_variable(effect_texture_variable variable, const char *name, float *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified texture <paramref name="variable"/> as signed integer values.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of signed integers that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_int_from_texture_variable(effect_texture_variable variable, const char *name, int32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified texture <paramref name="variable"/> as unsigned integer values.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of unsigned integers that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_uint_from_texture_variable(effect_texture_variable variable, const char *name, uint32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from a string annotation attached to the specified texture <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="value">Pointer to a string buffer that is filled with the value of the annotation, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="value_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual bool get_annotation_string_from_texture_variable(effect_texture_variable variable, const char *name, char *value, size_t *value_size) const = 0;
template <size_t SIZE>
inline bool get_annotation_string_from_texture_variable(effect_texture_variable variable, const char *name, char(&value)[SIZE]) const
{
size_t value_size = SIZE;
return get_annotation_string_from_texture_variable(variable, name, value, &value_size);
}
/// <summary>
/// Uploads 32 bits-per-pixel RGBA image data to the specified texture <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="width">Width of the image data.</param>
/// <param name="height">Height of the image data.</param>
/// <param name="pixels">Pointer to an array of <c>width * height * 4</c> bytes the image data is read from.</param>
virtual void update_texture(effect_texture_variable variable, const uint32_t width, const uint32_t height, const uint8_t *pixels) = 0;
/// <summary>
/// Gets the shader resource view that is bound to the specified texture <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="out_srv">Pointer to a variable that is set to the shader resource view.</param>
/// <param name="out_srv_srgb">Pointer to a variable that is set to the sRGB shader resource view.</param>
virtual void get_texture_binding(effect_texture_variable variable, resource_view *out_srv, resource_view *out_srv_srgb = nullptr) const = 0;
/// <summary>
/// Binds a new shader resource view to all texture variables that use the specified <paramref name="semantic"/>.
/// </summary>
/// <remarks>
/// The resource the shader resource views point to has to be in the <see cref="resource_usage::shader_resource"/> state at the time <see cref="render_effects"/> is executed.
/// </remarks>
/// <param name="semantic">ReShade FX semantic to filter textures to update by (<c>texture name : SEMANTIC</c>).</param>
/// <param name="srv">Shader resource view to use for samplers with <c>SRGBTexture</c> state set to <see langword="false"/>.</param>
/// <param name="srv_srgb">Shader resource view to use for samplers with <c>SRGBTexture</c> state set to <see langword="true"/>, or zero in which case the view from <paramref name="srv"/> is used.</param>
virtual void update_texture_bindings(const char *semantic, resource_view srv, resource_view srv_srgb = { 0 }) = 0;
/// <summary>
/// Enumerates all techniques of loaded effects and calls the specified <paramref name="callback"/> function with a handle for each one.
/// </summary>
/// <param name="effect_name">File name of the effect file to enumerate techniques from, or <see langword="nullptr"/> to enumerate those of all loaded effects.</param>
/// <param name="callback">Function to call for every technique.</param>
/// <param name="user_data">Optional pointer passed to the callback function.</param>
virtual void enumerate_techniques(const char *effect_name, void(*callback)(effect_runtime *runtime, effect_technique technique, void *user_data), void *user_data) = 0;
/// <summary>
/// Enumerates all techniques of loaded effects and calls the specified callback function with a handle for each one.
/// </summary>
/// <param name="effect_name">File name of the effect file to enumerate techniques from, or <see langword="nullptr"/> to enumerate those of all loaded effects.</param>
/// <param name="lambda">Function to call for every technique.</param>
template <typename F>
inline void enumerate_techniques(const char *effect_name, F lambda)
{
enumerate_techniques(effect_name, [](effect_runtime *runtime, effect_technique technique, void *user_data) { static_cast<F *>(user_data)->operator()(runtime, technique); }, &lambda);
}
/// <summary>
/// Finds a specific technique in the loaded effects and returns a handle to it.
/// </summary>
/// <param name="effect_name">File name of the effect file the technique is declared in, or <see langword="nullptr"/> to search in all loaded effects.</param>
/// <param name="technique_name">Name of the technique to find.</param>
/// <returns>Opaque handle to the technique, or zero in case it was not found.</returns>
virtual effect_technique find_technique(const char *effect_name, const char *technique_name) = 0;
/// <summary>
/// Gets the name of a <paramref name="technique"/>.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="name">Pointer to a string buffer that is filled with the name of the technique, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="name_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_technique_name(effect_technique technique, char *name, size_t *name_size) const = 0;
template <size_t SIZE>
inline void get_technique_name(effect_technique technique, char(&name)[SIZE]) const
{
size_t name_size = SIZE;
get_technique_name(technique, name, &name_size);
}
/// <summary>
/// Gets the value from an annotation attached to the specified <paramref name="technique"/> as boolean values.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of booleans that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_bool_from_technique(effect_technique technique, const char *name, bool *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified <paramref name="technique"/> as floating-point values.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of floating-points that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_float_from_technique(effect_technique technique, const char *name, float *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified <paramref name="technique"/> as signed integer values.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of signed integers that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_int_from_technique(effect_technique technique, const char *name, int32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from an annotation attached to the specified <paramref name="technique"/> as unsigned integer values.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="values">Pointer to an array of unsigned integers that is filled with the values of the annotation.</param>
/// <param name="count">Number of values to read.</param>
/// <param name="array_index">Array offset to start reading values from when the annotation is an array.</param>
virtual bool get_annotation_uint_from_technique(effect_technique technique, const char *name, uint32_t *values, size_t count, size_t array_index = 0) const = 0;
/// <summary>
/// Gets the value from a string annotation attached to the specified <paramref name="technique"/>.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="name">Name of the annotation.</param>
/// <param name="value">Pointer to a string buffer that is filled with the value of the annotation, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="value_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual bool get_annotation_string_from_technique(effect_technique technique, const char *name, char *value, size_t *value_size) const = 0;
template <size_t SIZE>
inline bool get_annotation_string_from_technique(effect_technique technique, const char *name, char(&value)[SIZE]) const
{
size_t value_size = SIZE;
return get_annotation_string_from_technique(technique, name, value, &value_size);
}
/// <summary>
/// Gets the state of a <paramref name="technique"/>.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
virtual bool get_technique_state(effect_technique technique) const = 0;
/// <summary>
/// Enables or disables the specified <paramref name="technique"/>.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="enabled">Set to <see langword="true"/> to enable the technique, or <see langword="false"/> to disable it.</param>
virtual void set_technique_state(effect_technique technique, bool enabled) = 0;
/// <summary>
/// Gets the value of a preprocessor definition.
/// </summary>
/// <param name="name">Name of the definition.</param>
/// <param name="value">Pointer to a string buffer that is filled with the value of the definition, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="value_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual bool get_preprocessor_definition(const char *name, char *value, size_t *value_size) const = 0;
template <size_t SIZE>
inline bool get_preprocessor_definition(const char *name, char(&value)[SIZE]) const
{
size_t value_size = SIZE;
return get_preprocessor_definition(name, value, &value_size);
}
/// <summary>
/// Defines a preprocessor definition to the specified <paramref name="value"/>.
/// </summary>
/// <param name="name">Name of the definition.</param>
/// <param name="value">Value of the definition.</param>
virtual void set_preprocessor_definition(const char *name, const char *value) = 0;
/// <summary>
/// Applies a <paramref name="technique"/> to the specified render targets (regardless of the state of this technique).
/// </summary>
/// <remarks>
/// The width and height of the specified render target should match those used to render all other effects!
/// The resource the render target views point to has to be in the <see cref="resource_usage::render_target"/> state.
/// This call may modify current state on the command list (pipeline, render targets, descriptor tables, ...), so it may be necessary for an add-on to backup and restore state around it if the application does not bind all state again afterwards already.
/// </remarks>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="cmd_list">Command list to add effect rendering commands to.</param>
/// <param name="rtv">Render target view to use for passes that write to the back buffer with <c>SRGBWriteEnabled</c> state set to <see langword="false"/>.</param>
/// <param name="rtv_srgb">Render target view to use for passes that write to the back buffer with <c>SRGBWriteEnabled</c> state set to <see langword="true"/>, or zero in which case the view from <paramref name="rtv"/> is used.</param>
virtual void render_technique(effect_technique technique, command_list *cmd_list, resource_view rtv, resource_view rtv_srgb = { 0 }) = 0;
/// <summary>
/// Gets whether effects are enabled or disabled.
/// </summary>
virtual bool get_effects_state() const = 0;
/// <summary>
/// Enables or disables all effects.
/// </summary>
/// <param name="enabled">Set to <see langword="true"/> to enable effects, or <see langword="false"/> to disable them.</param>
virtual void set_effects_state(bool enabled) = 0;
/// <summary>
/// Gets the file path to the currently active preset.
/// </summary>
/// <param name="path">Pointer to a string buffer that is filled with the file path to the preset, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="path_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_current_preset_path(char *path, size_t *path_size) const = 0;
template <size_t SIZE>
inline void get_current_preset_path(char(&path)[SIZE]) const
{
size_t path_size = SIZE;
get_current_preset_path(path, &path_size);
}
/// <summary>
/// Saves the currently active preset and then switches to the specified new preset.
/// </summary>
/// <param name="path">File path to the preset to switch to.</param>
virtual void set_current_preset_path(const char *path) = 0;
/// <summary>
/// Changes the rendering order of loaded techniques to that of the specified technique list.
/// </summary>
/// <param name="count">Number of handles in the technique list.</param>
/// <param name="techniques">Array of techniques in the order they should be rendered in.</param>
virtual void reorder_techniques(size_t count, const effect_technique *techniques) = 0;
/// <summary>
/// Makes ReShade block any keyboard and mouse input from reaching the game for the duration of the next frame.
/// Call this every frame for as long as input should be blocked. This can be used to ensure input is only applied to overlays created in a <see cref="addon_event::reshade_overlay"/> callback.
/// </summary>
virtual void block_input_next_frame() = 0;
/// <summary>
/// Gets the virtual key code of the last key that was pressed.
/// </summary>
virtual uint32_t last_key_pressed() const = 0;
/// <summary>
/// Gets the virtual key code of the last key that was released.
/// </summary>
virtual uint32_t last_key_released() const = 0;
/// <summary>
/// Gets the effect file name of a uniform <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the uniform variable.</param>
/// <param name="effect_name">Pointer to a string buffer that is filled with the effect file name of the uniform variable, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="effect_name_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_uniform_variable_effect_name(effect_uniform_variable variable, char *effect_name, size_t *effect_name_size) const = 0;
template <size_t SIZE>
inline void get_uniform_variable_effect_name(effect_uniform_variable variable, char(&effect_name)[SIZE]) const
{
size_t effect_name_size = SIZE;
get_uniform_variable_effect_name(variable, effect_name, &effect_name_size);
}
/// <summary>
/// Gets the effect file name of a texture <paramref name="variable"/>.
/// </summary>
/// <param name="variable">Opaque handle to the texture variable.</param>
/// <param name="effect_name">Pointer to a string buffer that is filled with the effect file name of the texture variable, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="effect_name_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_texture_variable_effect_name(effect_texture_variable variable, char *effect_name, size_t *effect_name_size) const = 0;
template <size_t SIZE>
inline void get_texture_variable_effect_name(effect_texture_variable variable, char(&effect_name)[SIZE]) const
{
size_t effect_name_size = SIZE;
get_texture_variable_effect_name(variable, effect_name, &effect_name_size);
}
/// <summary>
/// Gets the effect file name of a <paramref name="technique"/>.
/// </summary>
/// <param name="technique">Opaque handle to the technique.</param>
/// <param name="effect_name">Pointer to a string buffer that is filled with the effect file name of the technique, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="effect_name_size">Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator.</param>
virtual void get_technique_effect_name(effect_technique technique, char *effect_name, size_t *effect_name_size) const = 0;
template <size_t SIZE>
inline void get_technique_effect_name(effect_technique technique, char(&effect_name)[SIZE]) const
{
size_t effect_name_size = SIZE;
get_technique_effect_name(technique, effect_name, &effect_name_size);
}
/// <summary>
/// Saves the current preset with the current state of the loaded techniques and uniform variables.
/// </summary>
virtual void save_current_preset() const = 0;
/// <summary>
/// Gets the value of a preprocessor definition for the specified effect.
/// </summary>
/// <param name="effect_name">File name of the effect file the preprocessor definition is defined for.</param>
/// <param name="name">Name of the definition.</param>
/// <param name="value">Pointer to a string buffer that is filled with the value of the definition, or <see langword="nullptr"/> to query the necessary size.</param>
/// <param name="value_size">Pointer to an integer that contains the size of the string buffer and upon completion is set to the actual length of the string, including the null-terminator.</param>
virtual bool get_preprocessor_definition_for_effect(const char *effect_name, const char *name, char *value, size_t *value_size) const = 0;
template <size_t SIZE>
inline bool get_preprocessor_definition_for_effect(const char *effect_name, const char *name, char(&value)[SIZE]) const
{
size_t value_size = SIZE;
return get_preprocessor_definition_for_effect(effect_name, name, value, &value_size);
}
/// <summary>
/// Defines a preprocessor definition for the specified effect to the specified <paramref name="value"/>.
/// </summary>
/// <param name="effect_name">File name of the effect file the preprocessor definition should be defined for.</param>
/// <param name="name">Name of the definition.</param>
/// <param name="value">Value of the definition.</param>
virtual void set_preprocessor_definition_for_effect(const char *effect_name, const char *name, const char *value) = 0;
};
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,460 @@
/*
* Copyright (C) 2021 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause OR MIT
*/
#pragma once
#include <cfloat>
#include <cstdint>
namespace reshade { namespace api
{
/// <summary>
/// The available data and texture formats.
/// This is mostly compatible with 'DXGI_FORMAT'.
/// </summary>
enum class format : uint32_t
{
unknown = 0,
// Color formats
r1_unorm = 66,
l8_unorm = 0x3030384C,
a8_unorm = 65,
r8_typeless = 60,
r8_uint = 62,
r8_sint = 64,
r8_unorm = 61,
r8_snorm = 63,
l8a8_unorm = 0x3038414C,
r8g8_typeless = 48,
r8g8_uint = 50,
r8g8_sint = 52,
r8g8_unorm = 49,
r8g8_snorm = 51,
r8g8b8a8_typeless = 27,
r8g8b8a8_uint = 30,
r8g8b8a8_sint = 32,
r8g8b8a8_unorm = 28,
r8g8b8a8_unorm_srgb = 29,
r8g8b8a8_snorm = 31,
r8g8b8x8_unorm = 0x424757B9,
r8g8b8x8_unorm_srgb = 0x424757BA,
b8g8r8a8_typeless = 90,
b8g8r8a8_unorm = 87,
b8g8r8a8_unorm_srgb = 91,
b8g8r8x8_typeless = 92,
b8g8r8x8_unorm = 88,
b8g8r8x8_unorm_srgb = 93,
r10g10b10a2_typeless = 23,
r10g10b10a2_uint = 25,
r10g10b10a2_unorm = 24,
r10g10b10a2_xr_bias = 89,
b10g10r10a2_typeless = 0x42475330,
b10g10r10a2_uint = 0x42475332,
b10g10r10a2_unorm = 0x42475331,
l16_unorm = 0x3036314C,
r16_typeless = 53,
r16_uint = 57,
r16_sint = 59,
r16_unorm = 56,
r16_snorm = 58,
r16_float = 54,
l16a16_unorm = 0x3631414C,
r16g16_typeless = 33,
r16g16_uint = 36,
r16g16_sint = 38,
r16g16_unorm = 35,
r16g16_snorm = 37,
r16g16_float = 34,
r16g16b16a16_typeless = 9,
r16g16b16a16_uint = 12,
r16g16b16a16_sint = 14,
r16g16b16a16_unorm = 11,
r16g16b16a16_snorm = 13,
r16g16b16a16_float = 10,
r32_typeless = 39,
r32_uint = 42,
r32_sint = 43,
r32_float = 41,
r32g32_typeless = 15,
r32g32_uint = 17,
r32g32_sint = 18,
r32g32_float = 16,
r32g32b32_typeless = 5,
r32g32b32_uint = 7,
r32g32b32_sint = 8,
r32g32b32_float = 6,
r32g32b32a32_typeless = 1,
r32g32b32a32_uint = 3,
r32g32b32a32_sint = 4,
r32g32b32a32_float = 2,
r9g9b9e5 = 67,
r11g11b10_float = 26,
b5g6r5_unorm = 85,
b5g5r5a1_unorm = 86,
b5g5r5x1_unorm = 0x424757B5,
b4g4r4a4_unorm = 115,
a4b4g4r4_unorm = 191,
// Depth-stencil formats
s8_uint = 0x30303853,
d16_unorm = 55,
d16_unorm_s8_uint = 0x38363144,
d24_unorm_x8_uint = 0x38343244,
d24_unorm_s8_uint = 45,
d32_float = 40,
d32_float_s8_uint = 20,
r24_g8_typeless = 44,
r24_unorm_x8_uint = 46,
x24_unorm_g8_uint = 47,
r32_g8_typeless = 19,
r32_float_x8_uint = 21,
x32_float_g8_uint = 22,
// Compressed data formats
bc1_typeless = 70,
bc1_unorm = 71,
bc1_unorm_srgb = 72,
bc2_typeless = 73,
bc2_unorm = 74,
bc2_unorm_srgb = 75,
bc3_typeless = 76,
bc3_unorm = 77,
bc3_unorm_srgb = 78,
bc4_typeless = 79,
bc4_unorm = 80,
bc4_snorm = 81,
bc5_typeless = 82,
bc5_unorm = 83,
bc5_snorm = 84,
bc6h_typeless = 94,
bc6h_ufloat = 95,
bc6h_sfloat = 96,
bc7_typeless = 97,
bc7_unorm = 98,
bc7_unorm_srgb = 99,
// Video formats
r8g8_b8g8_unorm = 68,
g8r8_g8b8_unorm = 69,
// Special purpose formats
intz = 0x5A544E49,
};
/// <summary>
/// The available color space types for presentation.
/// </summary>
enum class color_space : uint32_t
{
unknown = 0,
srgb_nonlinear,
extended_srgb_linear,
hdr10_st2084,
hdr10_hlg,
};
/// <summary>
/// Converts the specified format <paramref name="value"/> to its equivalent typeless variant.
/// </summary>
/// <param name="value">The format to convert.</param>
inline format format_to_typeless(format value)
{
switch (value)
{
case format::l8_unorm:
case format::r8_typeless:
case format::r8_uint:
case format::r8_sint:
case format::r8_unorm:
case format::r8_snorm:
return format::r8_typeless;
case format::l8a8_unorm:
case format::r8g8_typeless:
case format::r8g8_uint:
case format::r8g8_sint:
case format::r8g8_unorm:
case format::r8g8_snorm:
return format::r8g8_typeless;
case format::r8g8b8a8_typeless:
case format::r8g8b8a8_uint:
case format::r8g8b8a8_sint:
case format::r8g8b8a8_unorm:
case format::r8g8b8a8_unorm_srgb:
case format::r8g8b8a8_snorm:
case format::r8g8b8x8_unorm:
case format::r8g8b8x8_unorm_srgb:
return format::r8g8b8a8_typeless;
case format::b8g8r8a8_typeless:
case format::b8g8r8a8_unorm:
case format::b8g8r8a8_unorm_srgb:
return format::b8g8r8a8_typeless;
case format::b8g8r8x8_typeless:
case format::b8g8r8x8_unorm:
case format::b8g8r8x8_unorm_srgb:
return format::b8g8r8x8_typeless;
case format::r10g10b10a2_typeless:
case format::r10g10b10a2_uint:
case format::r10g10b10a2_unorm:
case format::r10g10b10a2_xr_bias:
return format::r10g10b10a2_typeless;
case format::b10g10r10a2_typeless:
case format::b10g10r10a2_uint:
case format::b10g10r10a2_unorm:
return format::b10g10r10a2_typeless;
case format::l16_unorm:
case format::d16_unorm:
case format::r16_typeless:
case format::r16_uint:
case format::r16_sint:
case format::r16_float:
case format::r16_unorm:
case format::r16_snorm:
return format::r16_typeless;
case format::l16a16_unorm:
case format::r16g16_typeless:
case format::r16g16_uint:
case format::r16g16_sint:
case format::r16g16_float:
case format::r16g16_unorm:
case format::r16g16_snorm:
return format::r16g16_typeless;
case format::r16g16b16a16_typeless:
case format::r16g16b16a16_uint:
case format::r16g16b16a16_sint:
case format::r16g16b16a16_float:
case format::r16g16b16a16_unorm:
case format::r16g16b16a16_snorm:
return format::r16g16b16a16_typeless;
case format::d32_float:
case format::r32_typeless:
case format::r32_uint:
case format::r32_sint:
case format::r32_float:
return format::r32_typeless;
case format::r32g32_typeless:
case format::r32g32_uint:
case format::r32g32_sint:
case format::r32g32_float:
return format::r32g32_typeless;
case format::r32g32b32_typeless:
case format::r32g32b32_uint:
case format::r32g32b32_sint:
case format::r32g32b32_float:
return format::r32g32b32_typeless;
case format::r32g32b32a32_typeless:
case format::r32g32b32a32_uint:
case format::r32g32b32a32_sint:
case format::r32g32b32a32_float:
return format::r32g32b32a32_typeless;
case format::d32_float_s8_uint:
case format::r32_g8_typeless:
case format::r32_float_x8_uint:
case format::x32_float_g8_uint:
return format::r32_g8_typeless;
case format::d24_unorm_s8_uint: // Do not also convert 'd24_unorm_x8_uint' here, to keep it distinguishable from 'd24_unorm_s8_uint'
case format::r24_g8_typeless:
case format::r24_unorm_x8_uint:
case format::x24_unorm_g8_uint:
return format::r24_g8_typeless;
case format::bc1_typeless:
case format::bc1_unorm:
case format::bc1_unorm_srgb:
return format::bc1_typeless;
case format::bc2_typeless:
case format::bc2_unorm:
case format::bc2_unorm_srgb:
return format::bc2_typeless;
case format::bc3_typeless:
case format::bc3_unorm:
case format::bc3_unorm_srgb:
return format::bc2_typeless;
case format::bc4_typeless:
case format::bc4_unorm:
case format::bc4_snorm:
return format::bc4_typeless;
case format::bc5_typeless:
case format::bc5_unorm:
case format::bc5_snorm:
return format::bc5_typeless;
case format::bc6h_typeless:
case format::bc6h_ufloat:
case format::bc6h_sfloat:
return format::bc6h_typeless;
case format::bc7_typeless:
case format::bc7_unorm:
case format::bc7_unorm_srgb:
return format::bc7_typeless;
default:
return value;
}
}
/// <summary>
/// Converts the specified format <paramref name="value"/> to its equivalent typed variant ("unorm" or "float").
/// </summary>
/// <param name="value">The format to convert.</param>
/// <param name="srgb_variant">Set to 1 to get sRGB variant, 0 to get linear variant and -1 to preserve existing one.</param>
inline format format_to_default_typed(format value, int srgb_variant = -1)
{
switch (value)
{
case format::r8_typeless:
return format::r8_unorm;
case format::r8g8_typeless:
return format::r8g8_unorm;
case format::r8g8b8a8_typeless:
case format::r8g8b8a8_unorm:
return srgb_variant == 1 ? format::r8g8b8a8_unorm_srgb : format::r8g8b8a8_unorm;
case format::r8g8b8a8_unorm_srgb:
return srgb_variant != 0 ? format::r8g8b8a8_unorm_srgb : format::r8g8b8a8_unorm;
case format::r8g8b8x8_unorm:
return srgb_variant == 1 ? format::r8g8b8x8_unorm_srgb : format::r8g8b8x8_unorm;
case format::r8g8b8x8_unorm_srgb:
return srgb_variant != 0 ? format::r8g8b8x8_unorm_srgb : format::r8g8b8x8_unorm;
case format::b8g8r8a8_typeless:
case format::b8g8r8a8_unorm:
return srgb_variant == 1 ? format::b8g8r8a8_unorm_srgb : format::b8g8r8a8_unorm;
case format::b8g8r8a8_unorm_srgb:
return srgb_variant != 0 ? format::b8g8r8a8_unorm_srgb : format::b8g8r8a8_unorm;
case format::b8g8r8x8_typeless:
case format::b8g8r8x8_unorm:
return srgb_variant == 1 ? format::b8g8r8x8_unorm_srgb : format::b8g8r8x8_unorm;
case format::b8g8r8x8_unorm_srgb:
return srgb_variant != 0 ? format::b8g8r8x8_unorm_srgb : format::b8g8r8x8_unorm;
case format::r10g10b10a2_typeless:
return format::r10g10b10a2_unorm;
case format::b10g10r10a2_typeless:
return format::b10g10r10a2_unorm;
case format::d16_unorm:
case format::r16_typeless:
return format::r16_float;
case format::r16g16_typeless:
return format::r16g16_float;
case format::r16g16b16a16_typeless:
return format::r16g16b16a16_float;
case format::d32_float:
case format::r32_typeless:
return format::r32_float;
case format::r32g32_typeless:
return format::r32g32_float;
case format::r32g32b32_typeless:
return format::r32g32b32_float;
case format::r32g32b32a32_typeless:
return format::r32g32b32a32_float;
case format::d32_float_s8_uint:
case format::r32_g8_typeless:
return format::r32_float_x8_uint;
case format::d24_unorm_s8_uint: // Do not also convert 'd24_unorm_x8_uint' here, to keep it distinguishable from 'd24_unorm_s8_uint'
case format::r24_g8_typeless:
return format::r24_unorm_x8_uint;
case format::bc1_typeless:
case format::bc1_unorm:
return srgb_variant == 1 ? format::bc1_unorm_srgb : format::bc1_unorm;
case format::bc1_unorm_srgb:
return srgb_variant != 0 ? format::bc1_unorm_srgb : format::bc1_unorm;
case format::bc2_typeless:
case format::bc2_unorm:
return srgb_variant == 1 ? format::bc2_unorm_srgb : format::bc2_unorm;
case format::bc2_unorm_srgb:
return srgb_variant != 0 ? format::bc2_unorm_srgb : format::bc2_unorm;
case format::bc3_typeless:
case format::bc3_unorm:
return srgb_variant == 1 ? format::bc3_unorm_srgb : format::bc3_unorm;
case format::bc3_unorm_srgb:
return srgb_variant != 0 ? format::bc3_unorm_srgb : format::bc3_unorm;
case format::bc4_typeless:
return format::bc4_unorm;
case format::bc5_typeless:
return format::bc5_unorm;
case format::bc6h_typeless:
return format::bc6h_ufloat;
case format::bc7_typeless:
case format::bc7_unorm:
return srgb_variant == 1 ? format::bc7_unorm_srgb : format::bc7_unorm;
case format::bc7_unorm_srgb:
return srgb_variant != 0 ? format::bc7_unorm_srgb : format::bc7_unorm;
default:
return value;
}
}
/// <summary>
/// Converts the specified format <paramref name="value"/> to its equivalent depth-stencil variant.
/// </summary>
/// <param name="value">The format to convert.</param>
inline format format_to_depth_stencil_typed(format value)
{
switch (value)
{
case format::r16_typeless:
case format::r16_unorm:
return format::d16_unorm;
case format::r32_typeless:
case format::r32_float:
return format::d32_float;
case format::r32_g8_typeless:
case format::r32_float_x8_uint:
case format::x32_float_g8_uint:
return format::d32_float_s8_uint;
case format::r24_g8_typeless:
case format::r24_unorm_x8_uint:
case format::x24_unorm_g8_uint:
return format::d24_unorm_s8_uint;
default:
return value;
}
}
/// <summary>
/// Gets the number of bytes a texture row of the specified format <paramref name="value"/> occupies.
/// </summary>
inline const uint32_t format_row_pitch(format value, uint32_t width)
{
if (value == format::unknown)
return 0;
if (value <= format::r32g32b32a32_sint)
return 16 * width;
if (value <= format::r32g32b32_sint)
return 12 * width;
if (value <= format::x32_float_g8_uint)
return 8 * width;
if (value <= format::x24_unorm_g8_uint || value == format::l16a16_unorm)
return 4 * width;
if (value <= format::r16_sint || value == format::b5g6r5_unorm || value == format::b5g5r5a1_unorm || value == format::b5g5r5x1_unorm || value == format::l8a8_unorm || value == format::l16_unorm)
return 2 * width;
if (value <= format::a8_unorm || value == format::l8_unorm)
return 1 * width;
if (value <= format::g8r8_g8b8_unorm || (value >= format::b8g8r8a8_unorm && value <= format::b8g8r8x8_unorm_srgb) || (value == format::r8g8b8x8_unorm || value == format::r8g8b8x8_unorm_srgb))
return 4 * width;
// Block compressed formats are bytes per block, rather than per pixel
if ((value >= format::bc1_typeless && value <= format::bc1_unorm_srgb) || (value >= format::bc4_typeless && value <= format::bc4_snorm))
return 8 * ((width + 3) / 4);
if ((value >= format::bc2_typeless && value <= format::bc2_unorm_srgb) || (value >= format::bc3_typeless && value <= format::bc3_unorm_srgb) || (value >= format::bc5_typeless && value <= format::bc7_unorm_srgb))
return 16 * ((width + 3) / 4);
return 0;
}
/// <summary>
/// Gets the number of bytes a texture slice of the specified format <paramref name="value"/> occupies.
/// </summary>
inline const uint32_t format_slice_pitch(format value, uint32_t row_pitch, uint32_t height)
{
if ((value >= format::bc1_typeless && value <= format::bc5_snorm) || (value >= format::bc6h_typeless && value <= format::bc7_unorm_srgb))
return row_pitch * ((height + 3) / 4);
return row_pitch * height;
}
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,528 @@
/*
* Copyright (C) 2021 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause OR MIT
*/
#pragma once
#define RESHADE_DEFINE_HANDLE(name) \
typedef struct { uint64_t handle; } name; \
constexpr bool operator< (name lhs, name rhs) { return lhs.handle < rhs.handle; } \
constexpr bool operator!=(name lhs, name rhs) { return lhs.handle != rhs.handle; } \
constexpr bool operator!=(name lhs, uint64_t rhs) { return lhs.handle != rhs; } \
constexpr bool operator==(name lhs, name rhs) { return lhs.handle == rhs.handle; } \
constexpr bool operator==(name lhs, uint64_t rhs) { return lhs.handle == rhs; }
#define RESHADE_DEFINE_ENUM_FLAG_OPERATORS(type) \
constexpr type operator~(type a) { return static_cast<type>(~static_cast<uint32_t>(a)); } \
inline type &operator&=(type &a, type b) { return reinterpret_cast<type &>(reinterpret_cast<uint32_t &>(a) &= static_cast<uint32_t>(b)); } \
constexpr type operator&(type a, type b) { return static_cast<type>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b)); } \
inline type &operator|=(type &a, type b) { return reinterpret_cast<type &>(reinterpret_cast<uint32_t &>(a) |= static_cast<uint32_t>(b)); } \
constexpr type operator|(type a, type b) { return static_cast<type>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b)); } \
inline type &operator^=(type &a, type b) { return reinterpret_cast<type &>(reinterpret_cast<uint32_t &>(a) ^= static_cast<uint32_t>(b)); } \
constexpr type operator^(type a, type b) { return static_cast<type>(static_cast<uint32_t>(a) ^ static_cast<uint32_t>(b)); } \
constexpr bool operator==(type lhs, uint32_t rhs) { return static_cast<uint32_t>(lhs) == rhs; } \
constexpr bool operator!=(type lhs, uint32_t rhs) { return static_cast<uint32_t>(lhs) != rhs; }
#include "reshade_api_format.hpp"
namespace reshade { namespace api
{
/// <summary>
/// The available comparison types.
/// </summary>
enum class compare_op : uint32_t
{
never = 0,
less = 1,
equal = 2,
less_equal = 3,
greater = 4,
not_equal = 5,
greater_equal = 6,
always = 7
};
/// <summary>
/// The available filtering modes used for texture sampling operations.
/// </summary>
enum class filter_mode : uint32_t
{
min_mag_mip_point = 0,
min_mag_point_mip_linear = 0x1,
min_point_mag_linear_mip_point = 0x4,
min_point_mag_mip_linear = 0x5,
min_linear_mag_mip_point = 0x10,
min_linear_mag_point_mip_linear = 0x11,
min_mag_linear_mip_point = 0x14,
min_mag_mip_linear = 0x15,
min_mag_anisotropic_mip_point = 0x54,
anisotropic = 0x55,
compare_min_mag_mip_point = 0x80,
compare_min_mag_point_mip_linear = 0x81,
compare_min_point_mag_linear_mip_point = 0x84,
compare_min_point_mag_mip_linear = 0x85,
compare_min_linear_mag_mip_point = 0x90,
compare_min_linear_mag_point_mip_linear = 0x91,
compare_min_mag_linear_mip_point = 0x94,
compare_min_mag_mip_linear = 0x95,
compare_min_mag_anisotropic_mip_point = 0xd4,
compare_anisotropic = 0xd5
};
/// <summary>
/// Specifies behavior of sampling with texture coordinates outside a texture resource.
/// </summary>
enum class texture_address_mode : uint32_t
{
wrap = 1,
mirror = 2,
clamp = 3,
border = 4,
mirror_once = 5
};
/// <summary>
/// Describes a sampler state.
/// </summary>
struct sampler_desc
{
/// <summary>
/// Filtering mode to use when sampling a texture.
/// </summary>
filter_mode filter = filter_mode::min_mag_mip_linear;
/// <summary>
/// Method to use for resolving U texture coordinates outside 0 to 1 range.
/// </summary>
texture_address_mode address_u = texture_address_mode::clamp;
/// <summary>
/// Method to use for resolving V texture coordinates outside 0 to 1 range.
/// </summary>
texture_address_mode address_v = texture_address_mode::clamp;
/// <summary>
/// Method to use for resolving W texture coordinates outside 0 to 1 range.
/// </summary>
texture_address_mode address_w = texture_address_mode::clamp;
/// <summary>
/// Offset applied to the calculated mipmap level when sampling a texture.
/// </summary>
float mip_lod_bias = 0.0f;
/// <summary>
/// Clamping value to use when filtering mode is <see cref="filter_mode::anisotropic"/>.
/// </summary>
float max_anisotropy = 1.0f;
/// <summary>
/// Comparison function to use to compare sampled data against existing sampled data.
/// </summary>
compare_op compare_op = compare_op::never;
/// <summary>
/// RGBA value to return for texture coordinates outside 0 to 1 range when addressing mode is <see cref="texture_address_mode::border"/>.
/// </summary>
float border_color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
/// <summary>
/// Lower end of the mipmap range to clamp access to.
/// </summary>
float min_lod = -FLT_MAX;
/// <summary>
/// Upper end of the mipmap range to clamp access to.
/// </summary>
float max_lod = +FLT_MAX;
};
/// <summary>
/// An opaque handle to a sampler state object.
/// <para>Depending on the render API this can be a pointer to a 'ID3D10SamplerState', 'ID3D11SamplerState' or a 'D3D12_CPU_DESCRIPTOR_HANDLE' (to a sampler descriptor) or 'VkSampler' handle.</para>
/// </summary>
RESHADE_DEFINE_HANDLE(sampler);
/// <summary>
/// The available memory mapping access types.
/// </summary>
enum class map_access
{
read_only = 1,
write_only,
read_write,
write_discard
};
/// <summary>
/// The available memory heap types, which give a hint as to where to place the memory allocation for a resource.
/// </summary>
enum class memory_heap : uint32_t
{
unknown, // Usually indicates a resource that is reserved, but not yet bound to any memory.
gpu_only,
// Upload heap
cpu_to_gpu,
// Readback heap
gpu_to_cpu,
cpu_only,
custom
};
/// <summary>
/// The available resource types. The type of a resource is specified during creation and is immutable.
/// Various operations may have special requirements on the type of resources they operate on (e.g. copies can only happen between resources of the same type, ...).
/// </summary>
enum class resource_type : uint32_t
{
unknown,
buffer,
texture_1d,
texture_2d,
texture_3d,
surface // Special type for resources that are implicitly both resource and render target view.
};
/// <summary>
/// A list of flags that describe additional parameters of a resource.
/// </summary>
enum class resource_flags : uint32_t
{
none = 0,
dynamic = (1 << 3),
cube_compatible = (1 << 2),
generate_mipmaps = (1 << 0),
shared = (1 << 1),
shared_nt_handle = (1 << 11),
structured = (1 << 6),
sparse_binding = (1 << 18)
};
RESHADE_DEFINE_ENUM_FLAG_OPERATORS(resource_flags);
/// <summary>
/// A list of flags that specify how a resource is to be used.
/// This needs to be specified during creation and is also used to transition between different resource states within a command list.
/// </summary>
enum class resource_usage : uint32_t
{
undefined = 0,
index_buffer = 0x2,
vertex_buffer = 0x1,
constant_buffer = 0x8000,
stream_output = 0x100,
indirect_argument = 0x200,
depth_stencil = 0x30,
depth_stencil_read = 0x20,
depth_stencil_write = 0x10,
render_target = 0x4,
shader_resource = 0xC0,
shader_resource_pixel = 0x80,
shader_resource_non_pixel = 0x40,
unordered_access = 0x8,
copy_dest = 0x400,
copy_source = 0x800,
resolve_dest = 0x1000,
resolve_source = 0x2000,
// The following are special resource states and may only be used in barriers:
general = 0x80000000,
present = 0x80000000 | render_target | copy_source,
cpu_access = vertex_buffer | index_buffer | shader_resource | indirect_argument | copy_source
};
RESHADE_DEFINE_ENUM_FLAG_OPERATORS(resource_usage);
/// <summary>
/// Describes a resource, such as a buffer or texture.
/// </summary>
struct [[nodiscard]] resource_desc
{
constexpr resource_desc() : texture() {}
constexpr resource_desc(uint64_t size, memory_heap heap, resource_usage usage) :
type(resource_type::buffer), buffer({ size }), heap(heap), usage(usage) {}
constexpr resource_desc(uint32_t width, uint32_t height, uint16_t layers, uint16_t levels, format format, uint16_t samples, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) :
type(resource_type::texture_2d), texture({ width, height, layers, levels, format, samples }), heap(heap), usage(usage), flags(flags) {}
constexpr resource_desc(resource_type type, uint32_t width, uint32_t height, uint16_t depth_or_layers, uint16_t levels, format format, uint16_t samples, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) :
type(type), texture({ width, height, depth_or_layers, levels, format, samples }), heap(heap), usage(usage), flags(flags) {}
/// <summary>
/// Type of the resource.
/// </summary>
resource_type type = resource_type::unknown;
union
{
/// <summary>
/// Used when resource type is a buffer.
/// </summary>
struct
{
/// <summary>
/// Size of the buffer (in bytes).
/// </summary>
uint64_t size = 0;
/// <summary>
/// Structure stride for structured buffers (in bytes), otherwise zero.
/// </summary>
uint32_t stride = 0;
} buffer;
/// <summary>
/// Used when resource type is a texture or surface.
/// </summary>
struct
{
/// <summary>
/// Width of the texture (in texels).
/// </summary>
uint32_t width = 1;
/// <summary>
/// If this is a 2D or 3D texture, height of the texture (in texels), otherwise 1.
/// </summary>
uint32_t height = 1;
/// <summary>
/// If this is a 3D texture, depth of the texture (in texels), otherwise number of array layers.
/// </summary>
uint16_t depth_or_layers = 1;
/// <summary>
/// Maximum number of mipmap levels in the texture, including the base level, so at least 1.
/// Can also be zero in case the exact number of mipmap levels is unknown.
/// </summary>
uint16_t levels = 1;
/// <summary>
/// Data format of each texel in the texture.
/// </summary>
format format = format::unknown;
/// <summary>
/// The number of samples per texel. Set to a value higher than 1 for multisampling.
/// </summary>
uint16_t samples = 1;
} texture;
};
/// <summary>
/// Memory heap the resource allocation is placed in.
/// </summary>
memory_heap heap = memory_heap::unknown;
/// <summary>
/// Flags that specify how this resource may be used.
/// </summary>
resource_usage usage = resource_usage::undefined;
/// <summary>
/// Flags that describe additional parameters.
/// </summary>
resource_flags flags = resource_flags::none;
};
/// <summary>
/// An opaque handle to a resource object (buffer, texture, ...).
/// <para>Resources created by the application are only guaranteed to be valid during event callbacks.
/// <para>Depending on the render API this can be a pointer to a 'IDirect3DResource9', 'ID3D10Resource', 'ID3D11Resource' or 'ID3D12Resource' object or a 'VkImage' handle.</para>
/// </summary>
RESHADE_DEFINE_HANDLE(resource);
/// <summary>
/// The available resource view types. These identify how a resource view interprets the data of its resource.
/// </summary>
enum class resource_view_type : uint32_t
{
unknown,
buffer,
texture_1d,
texture_1d_array,
texture_2d,
texture_2d_array,
texture_2d_multisample,
texture_2d_multisample_array,
texture_3d,
texture_cube,
texture_cube_array
};
/// <summary>
/// Describes a resource view, which specifies how to interpret the data of a resource.
/// </summary>
struct [[nodiscard]] resource_view_desc
{
constexpr resource_view_desc() : texture() {}
constexpr resource_view_desc(format format, uint64_t offset, uint64_t size) :
type(resource_view_type::buffer), format(format), buffer({ offset, size }) {}
constexpr resource_view_desc(format format, uint32_t first_level, uint32_t levels, uint32_t first_layer, uint32_t layers) :
type(resource_view_type::texture_2d), format(format), texture({ first_level, levels, first_layer, layers }) {}
constexpr resource_view_desc(resource_view_type type, format format, uint32_t first_level, uint32_t levels, uint32_t first_layer, uint32_t layers) :
type(type), format(format), texture({ first_level, levels, first_layer, layers }) {}
constexpr explicit resource_view_desc(format format) : type(resource_view_type::texture_2d), format(format), texture({ 0, 1, 0, 1 }) {}
/// <summary>
/// Resource type the view should interpret the resource data to.
/// </summary>
resource_view_type type = resource_view_type::unknown;
/// <summary>
/// Format the view should reinterpret the resource data to (can be different than the format of the resource as long as they are compatible).
/// </summary>
format format = format::unknown;
union
{
/// <summary>
/// Used when view type is a buffer.
/// </summary>
struct
{
/// <summary>
/// Offset from the start of the buffer resource (in bytes).
/// </summary>
uint64_t offset = 0;
/// <summary>
/// Number of elements this view covers in the buffer resource (in bytes).
/// Set to -1 (UINT64_MAX) to indicate that the entire buffer resource should be used.
/// </summary>
uint64_t size = UINT64_MAX;
} buffer;
/// <summary>
/// Used when view type is a texture.
/// </summary>
struct
{
/// <summary>
/// Index of the most detailed mipmap level to use. This number has to be between zero and the maximum number of mipmap levels in the texture minus 1.
/// </summary>
uint32_t first_level = 0;
/// <summary>
/// Maximum number of mipmap levels for the view of the texture.
/// Set to -1 (UINT32_MAX) to indicate that all mipmap levels down to the least detailed should be used.
/// </summary>
uint32_t level_count = UINT32_MAX;
/// <summary>
/// Index of the first array layer of the texture array to use. This value is ignored if the texture is not layered.
/// </summary>
uint32_t first_layer = 0;
/// <summary>
/// Maximum number of array layers for the view of the texture array. This value is ignored if the texture is not layered.
/// Set to -1 (UINT32_MAX) to indicate that all array layers should be used.
/// </summary>
uint32_t layer_count = UINT32_MAX;
} texture;
};
};
/// <summary>
/// An opaque handle to a resource view object (depth-stencil, render target, shader resource view, ...).
/// <para>Resource views created by the application are only guaranteed to be valid during event callbacks.
/// <para>Depending on the render API this can be a pointer to a 'IDirect3DResource9', 'ID3D10View' or 'ID3D11View' object, or a 'D3D12_CPU_DESCRIPTOR_HANDLE' (to a view descriptor) or 'VkImageView' handle.</para>
/// </summary>
RESHADE_DEFINE_HANDLE(resource_view);
/// <summary>
/// Describes a region inside a subresource.
/// </summary>
struct subresource_box
{
int32_t left = 0;
int32_t top = 0;
int32_t front = 0;
int32_t right = 0;
int32_t bottom = 0;
int32_t back = 0;
constexpr uint32_t width() const { return right - left; }
constexpr uint32_t height() const { return bottom - top; }
constexpr uint32_t depth() const { return back - front; }
};
/// <summary>
/// Describes the data of a subresource.
/// </summary>
struct subresource_data
{
/// <summary>
/// Pointer to the data.
/// </summary>
void *data = nullptr;
/// <summary>
/// Row pitch of the data (added to the data pointer to move between texture rows, unused for buffers and 1D textures).
/// </summary>
/// <seealso cref="format_row_pitch"/>
uint32_t row_pitch = 0;
/// <summary>
/// Depth pitch of the data (added to the data pointer to move between texture depth/array slices, unused for buffers and 1D/2D textures).
/// </summary>
/// <seealso cref="format_slice_pitch"/>
uint32_t slice_pitch = 0;
};
/// <summary>
/// Specifies how the contents of a render target or depth-stencil view are treated at the start of a render pass.
/// </summary>
enum class render_pass_load_op : uint32_t
{
load,
clear,
discard,
no_access
};
/// <summary>
/// Specifies how the contents of a render target or depth-stencil view are treated at the end of a render pass.
/// </summary>
enum class render_pass_store_op : uint32_t
{
store,
discard,
no_access
};
/// <summary>
/// Describes a depth-stencil view and how it is treated at the start and end of a render pass.
/// </summary>
struct render_pass_depth_stencil_desc
{
/// <summary>
/// Depth-stencil resource view.
/// </summary>
resource_view view = { 0 };
/// <summary>
/// Specifies how the depth contents of the depth-stencil view are treated at the start of the render pass.
/// </summary>
render_pass_load_op depth_load_op = render_pass_load_op::load;
/// <summary>
/// Specifies how the depth contents of the depth-stencil view are treated at the end of the render pass.
/// </summary>
render_pass_store_op depth_store_op = render_pass_store_op::store;
/// <summary>
/// Specifies how the stencil contents of the depth-stencil view are treated at the start of the render pass.
/// </summary>
render_pass_load_op stencil_load_op = render_pass_load_op::load;
/// <summary>
/// Specifies how the stencil contents of the depth-stencil view are treated at the end of the render pass.
/// </summary>
render_pass_store_op stencil_store_op = render_pass_store_op::store;
/// <summary>
/// Value the depth contents of the depth-stencil resource is cleared to when <see cref="depth_load_op"/> is <see cref="render_pass_load_op::clear"/>.
/// </summary>
float clear_depth = 0.0f;
/// <summary>
/// Value the stencil contents of the depth-stencil resource is cleared to when <see cref="stencil_load_op"/> is <see cref="render_pass_load_op::clear"/>.
/// </summary>
uint8_t clear_stencil = 0;
};
/// <summary>
/// Describes a render target view and how it is treated at the start and end of a render pass.
/// </summary>
struct render_pass_render_target_desc
{
/// <summary>
/// Render target resource view.
/// </summary>
resource_view view = { 0 };
/// <summary>
/// Specifies how the contents of the render target view are treated at the start of the render pass.
/// </summary>
render_pass_load_op load_op = render_pass_load_op::load;
/// <summary>
/// Specifies how the contents of the render target view are treated at the end of the render pass.
/// </summary>
render_pass_store_op store_op = render_pass_store_op::store;
/// <summary>
/// Value the render target resource is cleared to when <see cref="load_op"/> is <see cref="render_pass_load_op::clear"/>.
/// </summary>
float clear_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
};
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,870 @@
/*
* Copyright (C) 2021 Patrick Mours
* Copyright (C) 2014-2023 Omar Cornut
* SPDX-License-Identifier: BSD-3-Clause OR MIT
*/
#if defined(IMGUI_VERSION_NUM)
#if IMGUI_VERSION_NUM != 18971
#error Unexpected ImGui version, please update the "imgui.h" header to version 18971!
#endif
// Check that the 'ImTextureID' type has the same size as 'reshade::api::resource_view'
static_assert(sizeof(ImTextureID) == 8, "missing \"#define ImTextureID ImU64\" before \"#include <imgui.h>\"");
struct imgui_function_table_18971
{
ImGuiIO&(*GetIO)();
ImGuiStyle&(*GetStyle)();
const char*(*GetVersion)();
bool(*Begin)(const char* name, bool* p_open, ImGuiWindowFlags flags);
void(*End)();
bool(*BeginChild)(const char* str_id, const ImVec2& size, bool border, ImGuiWindowFlags flags);
bool(*BeginChild2)(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags flags);
void(*EndChild)();
bool(*IsWindowAppearing)();
bool(*IsWindowCollapsed)();
bool(*IsWindowFocused)(ImGuiFocusedFlags flags);
bool(*IsWindowHovered)(ImGuiHoveredFlags flags);
ImDrawList*(*GetWindowDrawList)();
float(*GetWindowDpiScale)();
ImVec2(*GetWindowPos)();
ImVec2(*GetWindowSize)();
float(*GetWindowWidth)();
float(*GetWindowHeight)();
void(*SetNextWindowPos)(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot);
void(*SetNextWindowSize)(const ImVec2& size, ImGuiCond cond);
void(*SetNextWindowSizeConstraints)(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_data);
void(*SetNextWindowContentSize)(const ImVec2& size);
void(*SetNextWindowCollapsed)(bool collapsed, ImGuiCond cond);
void(*SetNextWindowFocus)();
void(*SetNextWindowScroll)(const ImVec2& scroll);
void(*SetNextWindowBgAlpha)(float alpha);
void(*SetWindowPos)(const ImVec2& pos, ImGuiCond cond);
void(*SetWindowSize)(const ImVec2& size, ImGuiCond cond);
void(*SetWindowCollapsed)(bool collapsed, ImGuiCond cond);
void(*SetWindowFocus)();
void(*SetWindowFontScale)(float scale);
void(*SetWindowPos2)(const char* name, const ImVec2& pos, ImGuiCond cond);
void(*SetWindowSize2)(const char* name, const ImVec2& size, ImGuiCond cond);
void(*SetWindowCollapsed2)(const char* name, bool collapsed, ImGuiCond cond);
void(*SetWindowFocus2)(const char* name);
ImVec2(*GetContentRegionAvail)();
ImVec2(*GetContentRegionMax)();
ImVec2(*GetWindowContentRegionMin)();
ImVec2(*GetWindowContentRegionMax)();
float(*GetScrollX)();
float(*GetScrollY)();
void(*SetScrollX)(float scroll_x);
void(*SetScrollY)(float scroll_y);
float(*GetScrollMaxX)();
float(*GetScrollMaxY)();
void(*SetScrollHereX)(float center_x_ratio);
void(*SetScrollHereY)(float center_y_ratio);
void(*SetScrollFromPosX)(float local_x, float center_x_ratio);
void(*SetScrollFromPosY)(float local_y, float center_y_ratio);
void(*PushFont)(ImFont* font);
void(*PopFont)();
void(*PushStyleColor)(ImGuiCol idx, ImU32 col);
void(*PushStyleColor2)(ImGuiCol idx, const ImVec4& col);
void(*PopStyleColor)(int count);
void(*PushStyleVar)(ImGuiStyleVar idx, float val);
void(*PushStyleVar2)(ImGuiStyleVar idx, const ImVec2& val);
void(*PopStyleVar)(int count);
void(*PushTabStop)(bool tab_stop);
void(*PopTabStop)();
void(*PushButtonRepeat)(bool repeat);
void(*PopButtonRepeat)();
void(*PushItemWidth)(float item_width);
void(*PopItemWidth)();
void(*SetNextItemWidth)(float item_width);
float(*CalcItemWidth)();
void(*PushTextWrapPos)(float wrap_local_pos_x);
void(*PopTextWrapPos)();
ImFont*(*GetFont)();
float(*GetFontSize)();
ImVec2(*GetFontTexUvWhitePixel)();
ImU32(*GetColorU32)(ImGuiCol idx, float alpha_mul);
ImU32(*GetColorU322)(const ImVec4& col);
ImU32(*GetColorU323)(ImU32 col);
const ImVec4&(*GetStyleColorVec4)(ImGuiCol idx);
void(*Separator)();
void(*SameLine)(float offset_from_start_x, float spacing);
void(*NewLine)();
void(*Spacing)();
void(*Dummy)(const ImVec2& size);
void(*Indent)(float indent_w);
void(*Unindent)(float indent_w);
void(*BeginGroup)();
void(*EndGroup)();
ImVec2(*GetCursorPos)();
float(*GetCursorPosX)();
float(*GetCursorPosY)();
void(*SetCursorPos)(const ImVec2& local_pos);
void(*SetCursorPosX)(float local_x);
void(*SetCursorPosY)(float local_y);
ImVec2(*GetCursorStartPos)();
ImVec2(*GetCursorScreenPos)();
void(*SetCursorScreenPos)(const ImVec2& pos);
void(*AlignTextToFramePadding)();
float(*GetTextLineHeight)();
float(*GetTextLineHeightWithSpacing)();
float(*GetFrameHeight)();
float(*GetFrameHeightWithSpacing)();
void(*PushID)(const char* str_id);
void(*PushID2)(const char* str_id_begin, const char* str_id_end);
void(*PushID3)(const void* ptr_id);
void(*PushID4)(int int_id);
void(*PopID)();
ImGuiID(*GetID)(const char* str_id);
ImGuiID(*GetID2)(const char* str_id_begin, const char* str_id_end);
ImGuiID(*GetID3)(const void* ptr_id);
void(*TextUnformatted)(const char* text, const char* text_end);
void(*TextV)(const char* fmt, va_list args);
void(*TextColoredV)(const ImVec4& col, const char* fmt, va_list args);
void(*TextDisabledV)(const char* fmt, va_list args);
void(*TextWrappedV)(const char* fmt, va_list args);
void(*LabelTextV)(const char* label, const char* fmt, va_list args);
void(*BulletTextV)(const char* fmt, va_list args);
void(*SeparatorText)(const char* label);
bool(*Button)(const char* label, const ImVec2& size);
bool(*SmallButton)(const char* label);
bool(*InvisibleButton)(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags);
bool(*ArrowButton)(const char* str_id, ImGuiDir dir);
bool(*Checkbox)(const char* label, bool* v);
bool(*CheckboxFlags)(const char* label, int* flags, int flags_value);
bool(*CheckboxFlags2)(const char* label, unsigned int* flags, unsigned int flags_value);
bool(*RadioButton)(const char* label, bool active);
bool(*RadioButton2)(const char* label, int* v, int v_button);
void(*ProgressBar)(float fraction, const ImVec2& size_arg, const char* overlay);
void(*Bullet)();
void(*Image)(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col);
bool(*ImageButton)(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col);
bool(*BeginCombo)(const char* label, const char* preview_value, ImGuiComboFlags flags);
void(*EndCombo)();
bool(*Combo)(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items);
bool(*Combo2)(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items);
bool(*Combo3)(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items);
bool(*DragFloat)(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragFloat2)(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragFloat3)(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragFloat4)(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragFloatRange2)(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, ImGuiSliderFlags flags);
bool(*DragInt)(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragInt2)(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragInt3)(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragInt4)(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*DragIntRange2)(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max, ImGuiSliderFlags flags);
bool(*DragScalar)(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
bool(*DragScalarN)(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderFloat)(const char* label, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderFloat2)(const char* label, float v[2], float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderFloat3)(const char* label, float v[3], float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderFloat4)(const char* label, float v[4], float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderAngle)(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderInt)(const char* label, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderInt2)(const char* label, int v[2], int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderInt3)(const char* label, int v[3], int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderInt4)(const char* label, int v[4], int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderScalar)(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
bool(*SliderScalarN)(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
bool(*VSliderFloat)(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags);
bool(*VSliderInt)(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags);
bool(*VSliderScalar)(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
bool(*InputText)(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
bool(*InputTextMultiline)(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
bool(*InputTextWithHint)(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
bool(*InputFloat)(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags);
bool(*InputFloat2)(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags);
bool(*InputFloat3)(const char* label, float v[3], const char* format, ImGuiInputTextFlags flags);
bool(*InputFloat4)(const char* label, float v[4], const char* format, ImGuiInputTextFlags flags);
bool(*InputInt)(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags);
bool(*InputInt2)(const char* label, int v[2], ImGuiInputTextFlags flags);
bool(*InputInt3)(const char* label, int v[3], ImGuiInputTextFlags flags);
bool(*InputInt4)(const char* label, int v[4], ImGuiInputTextFlags flags);
bool(*InputDouble)(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags);
bool(*InputScalar)(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags);
bool(*InputScalarN)(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags);
bool(*ColorEdit3)(const char* label, float col[3], ImGuiColorEditFlags flags);
bool(*ColorEdit4)(const char* label, float col[4], ImGuiColorEditFlags flags);
bool(*ColorPicker3)(const char* label, float col[3], ImGuiColorEditFlags flags);
bool(*ColorPicker4)(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col);
bool(*ColorButton)(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, const ImVec2& size);
void(*SetColorEditOptions)(ImGuiColorEditFlags flags);
bool(*TreeNode)(const char* label);
bool(*TreeNodeV)(const char* str_id, const char* fmt, va_list args);
bool(*TreeNodeV2)(const void* ptr_id, const char* fmt, va_list args);
bool(*TreeNodeEx)(const char* label, ImGuiTreeNodeFlags flags);
bool(*TreeNodeExV)(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args);
bool(*TreeNodeExV2)(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args);
void(*TreePush)(const char* str_id);
void(*TreePush2)(const void* ptr_id);
void(*TreePop)();
float(*GetTreeNodeToLabelSpacing)();
bool(*CollapsingHeader)(const char* label, ImGuiTreeNodeFlags flags);
bool(*CollapsingHeader2)(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags);
void(*SetNextItemOpen)(bool is_open, ImGuiCond cond);
bool(*Selectable)(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size);
bool(*Selectable2)(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size);
bool(*BeginListBox)(const char* label, const ImVec2& size);
void(*EndListBox)();
bool(*ListBox)(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items);
bool(*ListBox2)(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items);
void(*PlotLines)(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride);
void(*PlotLines2)(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
void(*PlotHistogram)(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride);
void(*PlotHistogram2)(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
void(*Value)(const char* prefix, bool b);
void(*Value2)(const char* prefix, int v);
void(*Value3)(const char* prefix, unsigned int v);
void(*Value4)(const char* prefix, float v, const char* float_format);
bool(*BeginMenuBar)();
void(*EndMenuBar)();
bool(*BeginMainMenuBar)();
void(*EndMainMenuBar)();
bool(*BeginMenu)(const char* label, bool enabled);
void(*EndMenu)();
bool(*MenuItem)(const char* label, const char* shortcut, bool selected, bool enabled);
bool(*MenuItem2)(const char* label, const char* shortcut, bool* p_selected, bool enabled);
bool(*BeginTooltip)();
void(*EndTooltip)();
void(*SetTooltipV)(const char* fmt, va_list args);
bool(*BeginItemTooltip)();
void(*SetItemTooltipV)(const char* fmt, va_list args);
bool(*BeginPopup)(const char* str_id, ImGuiWindowFlags flags);
bool(*BeginPopupModal)(const char* name, bool* p_open, ImGuiWindowFlags flags);
void(*EndPopup)();
void(*OpenPopup)(const char* str_id, ImGuiPopupFlags popup_flags);
void(*OpenPopup2)(ImGuiID id, ImGuiPopupFlags popup_flags);
void(*OpenPopupOnItemClick)(const char* str_id, ImGuiPopupFlags popup_flags);
void(*CloseCurrentPopup)();
bool(*BeginPopupContextItem)(const char* str_id, ImGuiPopupFlags popup_flags);
bool(*BeginPopupContextWindow)(const char* str_id, ImGuiPopupFlags popup_flags);
bool(*BeginPopupContextVoid)(const char* str_id, ImGuiPopupFlags popup_flags);
bool(*IsPopupOpen)(const char* str_id, ImGuiPopupFlags flags);
bool(*BeginTable)(const char* str_id, int column, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width);
void(*EndTable)();
void(*TableNextRow)(ImGuiTableRowFlags row_flags, float min_row_height);
bool(*TableNextColumn)();
bool(*TableSetColumnIndex)(int column_n);
void(*TableSetupColumn)(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id);
void(*TableSetupScrollFreeze)(int cols, int rows);
void(*TableHeadersRow)();
void(*TableHeader)(const char* label);
ImGuiTableSortSpecs*(*TableGetSortSpecs)();
int(*TableGetColumnCount)();
int(*TableGetColumnIndex)();
int(*TableGetRowIndex)();
const char*(*TableGetColumnName)(int column_n);
ImGuiTableColumnFlags(*TableGetColumnFlags)(int column_n);
void(*TableSetColumnEnabled)(int column_n, bool v);
void(*TableSetBgColor)(ImGuiTableBgTarget target, ImU32 color, int column_n);
void(*Columns)(int count, const char* id, bool border);
void(*NextColumn)();
int(*GetColumnIndex)();
float(*GetColumnWidth)(int column_index);
void(*SetColumnWidth)(int column_index, float width);
float(*GetColumnOffset)(int column_index);
void(*SetColumnOffset)(int column_index, float offset_x);
int(*GetColumnsCount)();
bool(*BeginTabBar)(const char* str_id, ImGuiTabBarFlags flags);
void(*EndTabBar)();
bool(*BeginTabItem)(const char* label, bool* p_open, ImGuiTabItemFlags flags);
void(*EndTabItem)();
bool(*TabItemButton)(const char* label, ImGuiTabItemFlags flags);
void(*SetTabItemClosed)(const char* tab_or_docked_window_label);
ImGuiID(*DockSpace)(ImGuiID id, const ImVec2& size, ImGuiDockNodeFlags flags, const ImGuiWindowClass* window_class);
void(*SetNextWindowDockID)(ImGuiID dock_id, ImGuiCond cond);
void(*SetNextWindowClass)(const ImGuiWindowClass* window_class);
ImGuiID(*GetWindowDockID)();
bool(*IsWindowDocked)();
bool(*BeginDragDropSource)(ImGuiDragDropFlags flags);
bool(*SetDragDropPayload)(const char* type, const void* data, size_t sz, ImGuiCond cond);
void(*EndDragDropSource)();
bool(*BeginDragDropTarget)();
const ImGuiPayload*(*AcceptDragDropPayload)(const char* type, ImGuiDragDropFlags flags);
void(*EndDragDropTarget)();
const ImGuiPayload*(*GetDragDropPayload)();
void(*BeginDisabled)(bool disabled);
void(*EndDisabled)();
void(*PushClipRect)(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
void(*PopClipRect)();
void(*SetItemDefaultFocus)();
void(*SetKeyboardFocusHere)(int offset);
void(*SetNextItemAllowOverlap)();
bool(*IsItemHovered)(ImGuiHoveredFlags flags);
bool(*IsItemActive)();
bool(*IsItemFocused)();
bool(*IsItemClicked)(ImGuiMouseButton mouse_button);
bool(*IsItemVisible)();
bool(*IsItemEdited)();
bool(*IsItemActivated)();
bool(*IsItemDeactivated)();
bool(*IsItemDeactivatedAfterEdit)();
bool(*IsItemToggledOpen)();
bool(*IsAnyItemHovered)();
bool(*IsAnyItemActive)();
bool(*IsAnyItemFocused)();
ImGuiID(*GetItemID)();
ImVec2(*GetItemRectMin)();
ImVec2(*GetItemRectMax)();
ImVec2(*GetItemRectSize)();
ImDrawList*(*GetBackgroundDrawList)();
ImDrawList*(*GetForegroundDrawList)();
ImDrawList*(*GetBackgroundDrawList2)(ImGuiViewport* viewport);
ImDrawList*(*GetForegroundDrawList2)(ImGuiViewport* viewport);
bool(*IsRectVisible)(const ImVec2& size);
bool(*IsRectVisible2)(const ImVec2& rect_min, const ImVec2& rect_max);
double(*GetTime)();
int(*GetFrameCount)();
ImDrawListSharedData*(*GetDrawListSharedData)();
const char*(*GetStyleColorName)(ImGuiCol idx);
void(*SetStateStorage)(ImGuiStorage* storage);
ImGuiStorage*(*GetStateStorage)();
bool(*BeginChildFrame)(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags);
void(*EndChildFrame)();
ImVec2(*CalcTextSize)(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width);
ImVec4(*ColorConvertU32ToFloat4)(ImU32 in);
ImU32(*ColorConvertFloat4ToU32)(const ImVec4& in);
void(*ColorConvertRGBtoHSV)(float r, float g, float b, float& out_h, float& out_s, float& out_v);
void(*ColorConvertHSVtoRGB)(float h, float s, float v, float& out_r, float& out_g, float& out_b);
bool(*IsKeyDown)(ImGuiKey key);
bool(*IsKeyPressed)(ImGuiKey key, bool repeat);
bool(*IsKeyReleased)(ImGuiKey key);
int(*GetKeyPressedAmount)(ImGuiKey key, float repeat_delay, float rate);
const char*(*GetKeyName)(ImGuiKey key);
void(*SetNextFrameWantCaptureKeyboard)(bool want_capture_keyboard);
bool(*IsMouseDown)(ImGuiMouseButton button);
bool(*IsMouseClicked)(ImGuiMouseButton button, bool repeat);
bool(*IsMouseReleased)(ImGuiMouseButton button);
bool(*IsMouseDoubleClicked)(ImGuiMouseButton button);
int(*GetMouseClickedCount)(ImGuiMouseButton button);
bool(*IsMouseHoveringRect)(const ImVec2& r_min, const ImVec2& r_max, bool clip);
bool(*IsMousePosValid)(const ImVec2* mouse_pos);
bool(*IsAnyMouseDown)();
ImVec2(*GetMousePos)();
ImVec2(*GetMousePosOnOpeningCurrentPopup)();
bool(*IsMouseDragging)(ImGuiMouseButton button, float lock_threshold);
ImVec2(*GetMouseDragDelta)(ImGuiMouseButton button, float lock_threshold);
void(*ResetMouseDragDelta)(ImGuiMouseButton button);
ImGuiMouseCursor(*GetMouseCursor)();
void(*SetMouseCursor)(ImGuiMouseCursor cursor_type);
void(*SetNextFrameWantCaptureMouse)(bool want_capture_mouse);
const char*(*GetClipboardText)();
void(*SetClipboardText)(const char* text);
void(*SetAllocatorFunctions)(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data);
void(*GetAllocatorFunctions)(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data);
void*(*MemAlloc)(size_t size);
void(*MemFree)(void* ptr);
int(*ImGuiStorage_GetInt)(const ImGuiStorage *_this, ImGuiID key, int default_val);
void(*ImGuiStorage_SetInt)(ImGuiStorage *_this, ImGuiID key, int val);
bool(*ImGuiStorage_GetBool)(const ImGuiStorage *_this, ImGuiID key, bool default_val);
void(*ImGuiStorage_SetBool)(ImGuiStorage *_this, ImGuiID key, bool val);
float(*ImGuiStorage_GetFloat)(const ImGuiStorage *_this, ImGuiID key, float default_val);
void(*ImGuiStorage_SetFloat)(ImGuiStorage *_this, ImGuiID key, float val);
void*(*ImGuiStorage_GetVoidPtr)(const ImGuiStorage *_this, ImGuiID key);
void(*ImGuiStorage_SetVoidPtr)(ImGuiStorage *_this, ImGuiID key, void* val);
int*(*ImGuiStorage_GetIntRef)(ImGuiStorage *_this, ImGuiID key, int default_val);
bool*(*ImGuiStorage_GetBoolRef)(ImGuiStorage *_this, ImGuiID key, bool default_val);
float*(*ImGuiStorage_GetFloatRef)(ImGuiStorage *_this, ImGuiID key, float default_val);
void**(*ImGuiStorage_GetVoidPtrRef)(ImGuiStorage *_this, ImGuiID key, void* default_val);
void(*ImGuiStorage_SetAllInt)(ImGuiStorage *_this, int val);
void(*ImGuiStorage_BuildSortByKey)(ImGuiStorage *_this);
void(*ConstructImGuiListClipper)(ImGuiListClipper *_this);
void(*DestructImGuiListClipper)(ImGuiListClipper *_this);
void(*ImGuiListClipper_Begin)(ImGuiListClipper *_this, int items_count, float items_height);
void(*ImGuiListClipper_End)(ImGuiListClipper *_this);
bool(*ImGuiListClipper_Step)(ImGuiListClipper *_this);
void(*ImGuiListClipper_IncludeRangeByIndices)(ImGuiListClipper *_this, int item_begin, int item_end);
void(*ImDrawList_PushClipRect)(ImDrawList *_this, const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
void(*ImDrawList_PushClipRectFullScreen)(ImDrawList *_this);
void(*ImDrawList_PopClipRect)(ImDrawList *_this);
void(*ImDrawList_PushTextureID)(ImDrawList *_this, ImTextureID texture_id);
void(*ImDrawList_PopTextureID)(ImDrawList *_this);
void(*ImDrawList_AddLine)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness);
void(*ImDrawList_AddRect)(ImDrawList *_this, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness);
void(*ImDrawList_AddRectFilled)(ImDrawList *_this, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags);
void(*ImDrawList_AddRectFilledMultiColor)(ImDrawList *_this, const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
void(*ImDrawList_AddQuad)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness);
void(*ImDrawList_AddQuadFilled)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col);
void(*ImDrawList_AddTriangle)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness);
void(*ImDrawList_AddTriangleFilled)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
void(*ImDrawList_AddCircle)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness);
void(*ImDrawList_AddCircleFilled)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments);
void(*ImDrawList_AddNgon)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness);
void(*ImDrawList_AddNgonFilled)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments);
void(*ImDrawList_AddText)(ImDrawList *_this, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end);
void(*ImDrawList_AddText2)(ImDrawList *_this, const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect);
void(*ImDrawList_AddPolyline)(ImDrawList *_this, const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
void(*ImDrawList_AddConvexPolyFilled)(ImDrawList *_this, const ImVec2* points, int num_points, ImU32 col);
void(*ImDrawList_AddBezierCubic)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments);
void(*ImDrawList_AddBezierQuadratic)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments);
void(*ImDrawList_AddImage)(ImDrawList *_this, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col);
void(*ImDrawList_AddImageQuad)(ImDrawList *_this, ImTextureID user_texture_id, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1, const ImVec2& uv2, const ImVec2& uv3, const ImVec2& uv4, ImU32 col);
void(*ImDrawList_AddImageRounded)(ImDrawList *_this, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags);
void(*ImDrawList_PathArcTo)(ImDrawList *_this, const ImVec2& center, float radius, float a_min, float a_max, int num_segments);
void(*ImDrawList_PathArcToFast)(ImDrawList *_this, const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12);
void(*ImDrawList_PathBezierCubicCurveTo)(ImDrawList *_this, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments);
void(*ImDrawList_PathBezierQuadraticCurveTo)(ImDrawList *_this, const ImVec2& p2, const ImVec2& p3, int num_segments);
void(*ImDrawList_PathRect)(ImDrawList *_this, const ImVec2& rect_min, const ImVec2& rect_max, float rounding, ImDrawFlags flags);
void(*ImDrawList_AddCallback)(ImDrawList *_this, ImDrawCallback callback, void* callback_data);
void(*ImDrawList_AddDrawCmd)(ImDrawList *_this);
ImDrawList*(*ImDrawList_CloneOutput)(const ImDrawList *_this);
void(*ImDrawList_PrimReserve)(ImDrawList *_this, int idx_count, int vtx_count);
void(*ImDrawList_PrimUnreserve)(ImDrawList *_this, int idx_count, int vtx_count);
void(*ImDrawList_PrimRect)(ImDrawList *_this, const ImVec2& a, const ImVec2& b, ImU32 col);
void(*ImDrawList_PrimRectUV)(ImDrawList *_this, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col);
void(*ImDrawList_PrimQuadUV)(ImDrawList *_this, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col);
void(*ConstructImFont)(ImFont *_this);
void(*DestructImFont)(ImFont *_this);
const ImFontGlyph*(*ImFont_FindGlyph)(const ImFont *_this, ImWchar c);
const ImFontGlyph*(*ImFont_FindGlyphNoFallback)(const ImFont *_this, ImWchar c);
ImVec2(*ImFont_CalcTextSizeA)(const ImFont *_this, float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining);
const char*(*ImFont_CalcWordWrapPositionA)(const ImFont *_this, float scale, const char* text, const char* text_end, float wrap_width);
void(*ImFont_RenderChar)(const ImFont *_this, ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c);
void(*ImFont_RenderText)(const ImFont *_this, ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip);
};
using imgui_function_table = imgui_function_table_18971;
inline const imgui_function_table *&imgui_function_table_instance()
{
static const imgui_function_table *instance = nullptr;
return instance;
}
#ifndef RESHADE_API_LIBRARY_EXPORT
namespace ImGui
{
inline ImGuiIO& GetIO() { return imgui_function_table_instance()->GetIO(); }
inline ImGuiStyle& GetStyle() { return imgui_function_table_instance()->GetStyle(); }
inline const char* GetVersion() { return imgui_function_table_instance()->GetVersion(); }
inline bool Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { return imgui_function_table_instance()->Begin(name, p_open, flags); }
inline void End() { imgui_function_table_instance()->End(); }
inline bool BeginChild(const char* str_id, const ImVec2& size, bool border, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginChild(str_id, size, border, flags); }
inline bool BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginChild2(id, size, border, flags); }
inline void EndChild() { imgui_function_table_instance()->EndChild(); }
inline bool IsWindowAppearing() { return imgui_function_table_instance()->IsWindowAppearing(); }
inline bool IsWindowCollapsed() { return imgui_function_table_instance()->IsWindowCollapsed(); }
inline bool IsWindowFocused(ImGuiFocusedFlags flags) { return imgui_function_table_instance()->IsWindowFocused(flags); }
inline bool IsWindowHovered(ImGuiHoveredFlags flags) { return imgui_function_table_instance()->IsWindowHovered(flags); }
inline ImDrawList* GetWindowDrawList() { return imgui_function_table_instance()->GetWindowDrawList(); }
inline float GetWindowDpiScale() { return imgui_function_table_instance()->GetWindowDpiScale(); }
inline ImVec2 GetWindowPos() { return imgui_function_table_instance()->GetWindowPos(); }
inline ImVec2 GetWindowSize() { return imgui_function_table_instance()->GetWindowSize(); }
inline float GetWindowWidth() { return imgui_function_table_instance()->GetWindowWidth(); }
inline float GetWindowHeight() { return imgui_function_table_instance()->GetWindowHeight(); }
inline void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { imgui_function_table_instance()->SetNextWindowPos(pos, cond, pivot); }
inline void SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { imgui_function_table_instance()->SetNextWindowSize(size, cond); }
inline void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_data) { imgui_function_table_instance()->SetNextWindowSizeConstraints(size_min, size_max, custom_callback, custom_callback_data); }
inline void SetNextWindowContentSize(const ImVec2& size) { imgui_function_table_instance()->SetNextWindowContentSize(size); }
inline void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { imgui_function_table_instance()->SetNextWindowCollapsed(collapsed, cond); }
inline void SetNextWindowFocus() { imgui_function_table_instance()->SetNextWindowFocus(); }
inline void SetNextWindowScroll(const ImVec2& scroll) { imgui_function_table_instance()->SetNextWindowScroll(scroll); }
inline void SetNextWindowBgAlpha(float alpha) { imgui_function_table_instance()->SetNextWindowBgAlpha(alpha); }
inline void SetWindowPos(const ImVec2& pos, ImGuiCond cond) { imgui_function_table_instance()->SetWindowPos(pos, cond); }
inline void SetWindowSize(const ImVec2& size, ImGuiCond cond) { imgui_function_table_instance()->SetWindowSize(size, cond); }
inline void SetWindowCollapsed(bool collapsed, ImGuiCond cond) { imgui_function_table_instance()->SetWindowCollapsed(collapsed, cond); }
inline void SetWindowFocus() { imgui_function_table_instance()->SetWindowFocus(); }
inline void SetWindowFontScale(float scale) { imgui_function_table_instance()->SetWindowFontScale(scale); }
inline void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond) { imgui_function_table_instance()->SetWindowPos2(name, pos, cond); }
inline void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond) { imgui_function_table_instance()->SetWindowSize2(name, size, cond); }
inline void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) { imgui_function_table_instance()->SetWindowCollapsed2(name, collapsed, cond); }
inline void SetWindowFocus(const char* name) { imgui_function_table_instance()->SetWindowFocus2(name); }
inline ImVec2 GetContentRegionAvail() { return imgui_function_table_instance()->GetContentRegionAvail(); }
inline ImVec2 GetContentRegionMax() { return imgui_function_table_instance()->GetContentRegionMax(); }
inline ImVec2 GetWindowContentRegionMin() { return imgui_function_table_instance()->GetWindowContentRegionMin(); }
inline ImVec2 GetWindowContentRegionMax() { return imgui_function_table_instance()->GetWindowContentRegionMax(); }
inline float GetScrollX() { return imgui_function_table_instance()->GetScrollX(); }
inline float GetScrollY() { return imgui_function_table_instance()->GetScrollY(); }
inline void SetScrollX(float scroll_x) { imgui_function_table_instance()->SetScrollX(scroll_x); }
inline void SetScrollY(float scroll_y) { imgui_function_table_instance()->SetScrollY(scroll_y); }
inline float GetScrollMaxX() { return imgui_function_table_instance()->GetScrollMaxX(); }
inline float GetScrollMaxY() { return imgui_function_table_instance()->GetScrollMaxY(); }
inline void SetScrollHereX(float center_x_ratio) { imgui_function_table_instance()->SetScrollHereX(center_x_ratio); }
inline void SetScrollHereY(float center_y_ratio) { imgui_function_table_instance()->SetScrollHereY(center_y_ratio); }
inline void SetScrollFromPosX(float local_x, float center_x_ratio) { imgui_function_table_instance()->SetScrollFromPosX(local_x, center_x_ratio); }
inline void SetScrollFromPosY(float local_y, float center_y_ratio) { imgui_function_table_instance()->SetScrollFromPosY(local_y, center_y_ratio); }
inline void PushFont(ImFont* font) { imgui_function_table_instance()->PushFont(font); }
inline void PopFont() { imgui_function_table_instance()->PopFont(); }
inline void PushStyleColor(ImGuiCol idx, ImU32 col) { imgui_function_table_instance()->PushStyleColor(idx, col); }
inline void PushStyleColor(ImGuiCol idx, const ImVec4& col) { imgui_function_table_instance()->PushStyleColor2(idx, col); }
inline void PopStyleColor(int count) { imgui_function_table_instance()->PopStyleColor(count); }
inline void PushStyleVar(ImGuiStyleVar idx, float val) { imgui_function_table_instance()->PushStyleVar(idx, val); }
inline void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) { imgui_function_table_instance()->PushStyleVar2(idx, val); }
inline void PopStyleVar(int count) { imgui_function_table_instance()->PopStyleVar(count); }
inline void PushTabStop(bool tab_stop) { imgui_function_table_instance()->PushTabStop(tab_stop); }
inline void PopTabStop() { imgui_function_table_instance()->PopTabStop(); }
inline void PushButtonRepeat(bool repeat) { imgui_function_table_instance()->PushButtonRepeat(repeat); }
inline void PopButtonRepeat() { imgui_function_table_instance()->PopButtonRepeat(); }
inline void PushItemWidth(float item_width) { imgui_function_table_instance()->PushItemWidth(item_width); }
inline void PopItemWidth() { imgui_function_table_instance()->PopItemWidth(); }
inline void SetNextItemWidth(float item_width) { imgui_function_table_instance()->SetNextItemWidth(item_width); }
inline float CalcItemWidth() { return imgui_function_table_instance()->CalcItemWidth(); }
inline void PushTextWrapPos(float wrap_local_pos_x) { imgui_function_table_instance()->PushTextWrapPos(wrap_local_pos_x); }
inline void PopTextWrapPos() { imgui_function_table_instance()->PopTextWrapPos(); }
inline ImFont* GetFont() { return imgui_function_table_instance()->GetFont(); }
inline float GetFontSize() { return imgui_function_table_instance()->GetFontSize(); }
inline ImVec2 GetFontTexUvWhitePixel() { return imgui_function_table_instance()->GetFontTexUvWhitePixel(); }
inline ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { return imgui_function_table_instance()->GetColorU32(idx, alpha_mul); }
inline ImU32 GetColorU32(const ImVec4& col) { return imgui_function_table_instance()->GetColorU322(col); }
inline ImU32 GetColorU32(ImU32 col) { return imgui_function_table_instance()->GetColorU323(col); }
inline const ImVec4& GetStyleColorVec4(ImGuiCol idx) { return imgui_function_table_instance()->GetStyleColorVec4(idx); }
inline void Separator() { imgui_function_table_instance()->Separator(); }
inline void SameLine(float offset_from_start_x, float spacing) { imgui_function_table_instance()->SameLine(offset_from_start_x, spacing); }
inline void NewLine() { imgui_function_table_instance()->NewLine(); }
inline void Spacing() { imgui_function_table_instance()->Spacing(); }
inline void Dummy(const ImVec2& size) { imgui_function_table_instance()->Dummy(size); }
inline void Indent(float indent_w) { imgui_function_table_instance()->Indent(indent_w); }
inline void Unindent(float indent_w) { imgui_function_table_instance()->Unindent(indent_w); }
inline void BeginGroup() { imgui_function_table_instance()->BeginGroup(); }
inline void EndGroup() { imgui_function_table_instance()->EndGroup(); }
inline ImVec2 GetCursorPos() { return imgui_function_table_instance()->GetCursorPos(); }
inline float GetCursorPosX() { return imgui_function_table_instance()->GetCursorPosX(); }
inline float GetCursorPosY() { return imgui_function_table_instance()->GetCursorPosY(); }
inline void SetCursorPos(const ImVec2& local_pos) { imgui_function_table_instance()->SetCursorPos(local_pos); }
inline void SetCursorPosX(float local_x) { imgui_function_table_instance()->SetCursorPosX(local_x); }
inline void SetCursorPosY(float local_y) { imgui_function_table_instance()->SetCursorPosY(local_y); }
inline ImVec2 GetCursorStartPos() { return imgui_function_table_instance()->GetCursorStartPos(); }
inline ImVec2 GetCursorScreenPos() { return imgui_function_table_instance()->GetCursorScreenPos(); }
inline void SetCursorScreenPos(const ImVec2& pos) { imgui_function_table_instance()->SetCursorScreenPos(pos); }
inline void AlignTextToFramePadding() { imgui_function_table_instance()->AlignTextToFramePadding(); }
inline float GetTextLineHeight() { return imgui_function_table_instance()->GetTextLineHeight(); }
inline float GetTextLineHeightWithSpacing() { return imgui_function_table_instance()->GetTextLineHeightWithSpacing(); }
inline float GetFrameHeight() { return imgui_function_table_instance()->GetFrameHeight(); }
inline float GetFrameHeightWithSpacing() { return imgui_function_table_instance()->GetFrameHeightWithSpacing(); }
inline void PushID(const char* str_id) { imgui_function_table_instance()->PushID(str_id); }
inline void PushID(const char* str_id_begin, const char* str_id_end) { imgui_function_table_instance()->PushID2(str_id_begin, str_id_end); }
inline void PushID(const void* ptr_id) { imgui_function_table_instance()->PushID3(ptr_id); }
inline void PushID(int int_id) { imgui_function_table_instance()->PushID4(int_id); }
inline void PopID() { imgui_function_table_instance()->PopID(); }
inline ImGuiID GetID(const char* str_id) { return imgui_function_table_instance()->GetID(str_id); }
inline ImGuiID GetID(const char* str_id_begin, const char* str_id_end) { return imgui_function_table_instance()->GetID2(str_id_begin, str_id_end); }
inline ImGuiID GetID(const void* ptr_id) { return imgui_function_table_instance()->GetID3(ptr_id); }
inline void TextUnformatted(const char* text, const char* text_end) { imgui_function_table_instance()->TextUnformatted(text, text_end); }
inline void Text(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextV(fmt, args); va_end(args); }
inline void TextV(const char* fmt, va_list args) { imgui_function_table_instance()->TextV(fmt, args); }
inline void TextColored(const ImVec4& col, const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextColoredV(col, fmt, args); va_end(args); }
inline void TextColoredV(const ImVec4& col, const char* fmt, va_list args) { imgui_function_table_instance()->TextColoredV(col, fmt, args); }
inline void TextDisabled(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextDisabledV(fmt, args); va_end(args); }
inline void TextDisabledV(const char* fmt, va_list args) { imgui_function_table_instance()->TextDisabledV(fmt, args); }
inline void TextWrapped(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextWrappedV(fmt, args); va_end(args); }
inline void TextWrappedV(const char* fmt, va_list args) { imgui_function_table_instance()->TextWrappedV(fmt, args); }
inline void LabelText(const char* label, const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->LabelTextV(label, fmt, args); va_end(args); }
inline void LabelTextV(const char* label, const char* fmt, va_list args) { imgui_function_table_instance()->LabelTextV(label, fmt, args); }
inline void BulletText(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->BulletTextV(fmt, args); va_end(args); }
inline void BulletTextV(const char* fmt, va_list args) { imgui_function_table_instance()->BulletTextV(fmt, args); }
inline void SeparatorText(const char* label) { imgui_function_table_instance()->SeparatorText(label); }
inline bool Button(const char* label, const ImVec2& size) { return imgui_function_table_instance()->Button(label, size); }
inline bool SmallButton(const char* label) { return imgui_function_table_instance()->SmallButton(label); }
inline bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags) { return imgui_function_table_instance()->InvisibleButton(str_id, size, flags); }
inline bool ArrowButton(const char* str_id, ImGuiDir dir) { return imgui_function_table_instance()->ArrowButton(str_id, dir); }
inline bool Checkbox(const char* label, bool* v) { return imgui_function_table_instance()->Checkbox(label, v); }
inline bool CheckboxFlags(const char* label, int* flags, int flags_value) { return imgui_function_table_instance()->CheckboxFlags(label, flags, flags_value); }
inline bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) { return imgui_function_table_instance()->CheckboxFlags2(label, flags, flags_value); }
inline bool RadioButton(const char* label, bool active) { return imgui_function_table_instance()->RadioButton(label, active); }
inline bool RadioButton(const char* label, int* v, int v_button) { return imgui_function_table_instance()->RadioButton2(label, v, v_button); }
inline void ProgressBar(float fraction, const ImVec2& size_arg, const char* overlay) { imgui_function_table_instance()->ProgressBar(fraction, size_arg, overlay); }
inline void Bullet() { imgui_function_table_instance()->Bullet(); }
inline void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) { imgui_function_table_instance()->Image(user_texture_id, size, uv0, uv1, tint_col, border_col); }
inline bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col) { return imgui_function_table_instance()->ImageButton(str_id, user_texture_id, size, uv0, uv1, bg_col, tint_col); }
inline bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags) { return imgui_function_table_instance()->BeginCombo(label, preview_value, flags); }
inline void EndCombo() { imgui_function_table_instance()->EndCombo(); }
inline bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items) { return imgui_function_table_instance()->Combo(label, current_item, items, items_count, popup_max_height_in_items); }
inline bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items) { return imgui_function_table_instance()->Combo2(label, current_item, items_separated_by_zeros, popup_max_height_in_items); }
inline bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items) { return imgui_function_table_instance()->Combo3(label, current_item, items_getter, data, items_count, popup_max_height_in_items); }
inline bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat2(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat3(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat4(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloatRange2(label, v_current_min, v_current_max, v_speed, v_min, v_max, format, format_max, flags); }
inline bool DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt2(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt3(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt4(label, v, v_speed, v_min, v_max, format, flags); }
inline bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragIntRange2(label, v_current_min, v_current_max, v_speed, v_min, v_max, format, format_max, flags); }
inline bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragScalar(label, data_type, p_data, v_speed, p_min, p_max, format, flags); }
inline bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragScalarN(label, data_type, p_data, components, v_speed, p_min, p_max, format, flags); }
inline bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat(label, v, v_min, v_max, format, flags); }
inline bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat2(label, v, v_min, v_max, format, flags); }
inline bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat3(label, v, v_min, v_max, format, flags); }
inline bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat4(label, v, v_min, v_max, format, flags); }
inline bool SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderAngle(label, v_rad, v_degrees_min, v_degrees_max, format, flags); }
inline bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt(label, v, v_min, v_max, format, flags); }
inline bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt2(label, v, v_min, v_max, format, flags); }
inline bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt3(label, v, v_min, v_max, format, flags); }
inline bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt4(label, v, v_min, v_max, format, flags); }
inline bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderScalar(label, data_type, p_data, p_min, p_max, format, flags); }
inline bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderScalarN(label, data_type, p_data, components, p_min, p_max, format, flags); }
inline bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->VSliderFloat(label, size, v, v_min, v_max, format, flags); }
inline bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->VSliderInt(label, size, v, v_min, v_max, format, flags); }
inline bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->VSliderScalar(label, size, data_type, p_data, p_min, p_max, format, flags); }
inline bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { return imgui_function_table_instance()->InputText(label, buf, buf_size, flags, callback, user_data); }
inline bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { return imgui_function_table_instance()->InputTextMultiline(label, buf, buf_size, size, flags, callback, user_data); }
inline bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { return imgui_function_table_instance()->InputTextWithHint(label, hint, buf, buf_size, flags, callback, user_data); }
inline bool InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat(label, v, step, step_fast, format, flags); }
inline bool InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat2(label, v, format, flags); }
inline bool InputFloat3(const char* label, float v[3], const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat3(label, v, format, flags); }
inline bool InputFloat4(const char* label, float v[4], const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat4(label, v, format, flags); }
inline bool InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt(label, v, step, step_fast, flags); }
inline bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt2(label, v, flags); }
inline bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt3(label, v, flags); }
inline bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt4(label, v, flags); }
inline bool InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputDouble(label, v, step, step_fast, format, flags); }
inline bool InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputScalar(label, data_type, p_data, p_step, p_step_fast, format, flags); }
inline bool InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputScalarN(label, data_type, p_data, components, p_step, p_step_fast, format, flags); }
inline bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) { return imgui_function_table_instance()->ColorEdit3(label, col, flags); }
inline bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { return imgui_function_table_instance()->ColorEdit4(label, col, flags); }
inline bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) { return imgui_function_table_instance()->ColorPicker3(label, col, flags); }
inline bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col) { return imgui_function_table_instance()->ColorPicker4(label, col, flags, ref_col); }
inline bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, const ImVec2& size) { return imgui_function_table_instance()->ColorButton(desc_id, col, flags, size); }
inline void SetColorEditOptions(ImGuiColorEditFlags flags) { imgui_function_table_instance()->SetColorEditOptions(flags); }
inline bool TreeNode(const char* label) { return imgui_function_table_instance()->TreeNode(label); }
inline bool TreeNode(const char* str_id, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeV(str_id, fmt, args); va_end(args); }
inline bool TreeNode(const void* ptr_id, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeV2(ptr_id, fmt, args); va_end(args); }
inline bool TreeNodeV(const char* str_id, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeV(str_id, fmt, args); }
inline bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeV2(ptr_id, fmt, args); }
inline bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) { return imgui_function_table_instance()->TreeNodeEx(label, flags); }
inline bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeExV(str_id, flags, fmt, args); va_end(args); }
inline bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeExV2(ptr_id, flags, fmt, args); va_end(args); }
inline bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeExV(str_id, flags, fmt, args); }
inline bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeExV2(ptr_id, flags, fmt, args); }
inline void TreePush(const char* str_id) { imgui_function_table_instance()->TreePush(str_id); }
inline void TreePush(const void* ptr_id) { imgui_function_table_instance()->TreePush2(ptr_id); }
inline void TreePop() { imgui_function_table_instance()->TreePop(); }
inline float GetTreeNodeToLabelSpacing() { return imgui_function_table_instance()->GetTreeNodeToLabelSpacing(); }
inline bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) { return imgui_function_table_instance()->CollapsingHeader(label, flags); }
inline bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags) { return imgui_function_table_instance()->CollapsingHeader2(label, p_visible, flags); }
inline void SetNextItemOpen(bool is_open, ImGuiCond cond) { imgui_function_table_instance()->SetNextItemOpen(is_open, cond); }
inline bool Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size) { return imgui_function_table_instance()->Selectable(label, selected, flags, size); }
inline bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size) { return imgui_function_table_instance()->Selectable2(label, p_selected, flags, size); }
inline bool BeginListBox(const char* label, const ImVec2& size) { return imgui_function_table_instance()->BeginListBox(label, size); }
inline void EndListBox() { imgui_function_table_instance()->EndListBox(); }
inline bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items) { return imgui_function_table_instance()->ListBox(label, current_item, items, items_count, height_in_items); }
inline bool ListBox(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items) { return imgui_function_table_instance()->ListBox2(label, current_item, items_getter, data, items_count, height_in_items); }
inline void PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { imgui_function_table_instance()->PlotLines(label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride); }
inline void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { imgui_function_table_instance()->PlotLines2(label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); }
inline void PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { imgui_function_table_instance()->PlotHistogram(label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride); }
inline void PlotHistogram(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { imgui_function_table_instance()->PlotHistogram2(label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); }
inline void Value(const char* prefix, bool b) { imgui_function_table_instance()->Value(prefix, b); }
inline void Value(const char* prefix, int v) { imgui_function_table_instance()->Value2(prefix, v); }
inline void Value(const char* prefix, unsigned int v) { imgui_function_table_instance()->Value3(prefix, v); }
inline void Value(const char* prefix, float v, const char* float_format) { imgui_function_table_instance()->Value4(prefix, v, float_format); }
inline bool BeginMenuBar() { return imgui_function_table_instance()->BeginMenuBar(); }
inline void EndMenuBar() { imgui_function_table_instance()->EndMenuBar(); }
inline bool BeginMainMenuBar() { return imgui_function_table_instance()->BeginMainMenuBar(); }
inline void EndMainMenuBar() { imgui_function_table_instance()->EndMainMenuBar(); }
inline bool BeginMenu(const char* label, bool enabled) { return imgui_function_table_instance()->BeginMenu(label, enabled); }
inline void EndMenu() { imgui_function_table_instance()->EndMenu(); }
inline bool MenuItem(const char* label, const char* shortcut, bool selected, bool enabled) { return imgui_function_table_instance()->MenuItem(label, shortcut, selected, enabled); }
inline bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled) { return imgui_function_table_instance()->MenuItem2(label, shortcut, p_selected, enabled); }
inline bool BeginTooltip() { return imgui_function_table_instance()->BeginTooltip(); }
inline void EndTooltip() { imgui_function_table_instance()->EndTooltip(); }
inline void SetTooltip(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->SetTooltipV(fmt, args); va_end(args); }
inline void SetTooltipV(const char* fmt, va_list args) { imgui_function_table_instance()->SetTooltipV(fmt, args); }
inline bool BeginItemTooltip() { return imgui_function_table_instance()->BeginItemTooltip(); }
inline void SetItemTooltip(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->SetItemTooltipV(fmt, args); va_end(args); }
inline void SetItemTooltipV(const char* fmt, va_list args) { imgui_function_table_instance()->SetItemTooltipV(fmt, args); }
inline bool BeginPopup(const char* str_id, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginPopup(str_id, flags); }
inline bool BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginPopupModal(name, p_open, flags); }
inline void EndPopup() { imgui_function_table_instance()->EndPopup(); }
inline void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) { imgui_function_table_instance()->OpenPopup(str_id, popup_flags); }
inline void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags) { imgui_function_table_instance()->OpenPopup2(id, popup_flags); }
inline void OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags) { imgui_function_table_instance()->OpenPopupOnItemClick(str_id, popup_flags); }
inline void CloseCurrentPopup() { imgui_function_table_instance()->CloseCurrentPopup(); }
inline bool BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags) { return imgui_function_table_instance()->BeginPopupContextItem(str_id, popup_flags); }
inline bool BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_flags) { return imgui_function_table_instance()->BeginPopupContextWindow(str_id, popup_flags); }
inline bool BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flags) { return imgui_function_table_instance()->BeginPopupContextVoid(str_id, popup_flags); }
inline bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags) { return imgui_function_table_instance()->IsPopupOpen(str_id, flags); }
inline bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width) { return imgui_function_table_instance()->BeginTable(str_id, column, flags, outer_size, inner_width); }
inline void EndTable() { imgui_function_table_instance()->EndTable(); }
inline void TableNextRow(ImGuiTableRowFlags row_flags, float min_row_height) { imgui_function_table_instance()->TableNextRow(row_flags, min_row_height); }
inline bool TableNextColumn() { return imgui_function_table_instance()->TableNextColumn(); }
inline bool TableSetColumnIndex(int column_n) { return imgui_function_table_instance()->TableSetColumnIndex(column_n); }
inline void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) { imgui_function_table_instance()->TableSetupColumn(label, flags, init_width_or_weight, user_id); }
inline void TableSetupScrollFreeze(int cols, int rows) { imgui_function_table_instance()->TableSetupScrollFreeze(cols, rows); }
inline void TableHeadersRow() { imgui_function_table_instance()->TableHeadersRow(); }
inline void TableHeader(const char* label) { imgui_function_table_instance()->TableHeader(label); }
inline ImGuiTableSortSpecs* TableGetSortSpecs() { return imgui_function_table_instance()->TableGetSortSpecs(); }
inline int TableGetColumnCount() { return imgui_function_table_instance()->TableGetColumnCount(); }
inline int TableGetColumnIndex() { return imgui_function_table_instance()->TableGetColumnIndex(); }
inline int TableGetRowIndex() { return imgui_function_table_instance()->TableGetRowIndex(); }
inline const char* TableGetColumnName(int column_n) { return imgui_function_table_instance()->TableGetColumnName(column_n); }
inline ImGuiTableColumnFlags TableGetColumnFlags(int column_n) { return imgui_function_table_instance()->TableGetColumnFlags(column_n); }
inline void TableSetColumnEnabled(int column_n, bool v) { imgui_function_table_instance()->TableSetColumnEnabled(column_n, v); }
inline void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n) { imgui_function_table_instance()->TableSetBgColor(target, color, column_n); }
inline void Columns(int count, const char* id, bool border) { imgui_function_table_instance()->Columns(count, id, border); }
inline void NextColumn() { imgui_function_table_instance()->NextColumn(); }
inline int GetColumnIndex() { return imgui_function_table_instance()->GetColumnIndex(); }
inline float GetColumnWidth(int column_index) { return imgui_function_table_instance()->GetColumnWidth(column_index); }
inline void SetColumnWidth(int column_index, float width) { imgui_function_table_instance()->SetColumnWidth(column_index, width); }
inline float GetColumnOffset(int column_index) { return imgui_function_table_instance()->GetColumnOffset(column_index); }
inline void SetColumnOffset(int column_index, float offset_x) { imgui_function_table_instance()->SetColumnOffset(column_index, offset_x); }
inline int GetColumnsCount() { return imgui_function_table_instance()->GetColumnsCount(); }
inline bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) { return imgui_function_table_instance()->BeginTabBar(str_id, flags); }
inline void EndTabBar() { imgui_function_table_instance()->EndTabBar(); }
inline bool BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags flags) { return imgui_function_table_instance()->BeginTabItem(label, p_open, flags); }
inline void EndTabItem() { imgui_function_table_instance()->EndTabItem(); }
inline bool TabItemButton(const char* label, ImGuiTabItemFlags flags) { return imgui_function_table_instance()->TabItemButton(label, flags); }
inline void SetTabItemClosed(const char* tab_or_docked_window_label) { imgui_function_table_instance()->SetTabItemClosed(tab_or_docked_window_label); }
inline ImGuiID DockSpace(ImGuiID id, const ImVec2& size, ImGuiDockNodeFlags flags, const ImGuiWindowClass* window_class) { return imgui_function_table_instance()->DockSpace(id, size, flags, window_class); }
inline void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond) { imgui_function_table_instance()->SetNextWindowDockID(dock_id, cond); }
inline void SetNextWindowClass(const ImGuiWindowClass* window_class) { imgui_function_table_instance()->SetNextWindowClass(window_class); }
inline ImGuiID GetWindowDockID() { return imgui_function_table_instance()->GetWindowDockID(); }
inline bool IsWindowDocked() { return imgui_function_table_instance()->IsWindowDocked(); }
inline bool BeginDragDropSource(ImGuiDragDropFlags flags) { return imgui_function_table_instance()->BeginDragDropSource(flags); }
inline bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond) { return imgui_function_table_instance()->SetDragDropPayload(type, data, sz, cond); }
inline void EndDragDropSource() { imgui_function_table_instance()->EndDragDropSource(); }
inline bool BeginDragDropTarget() { return imgui_function_table_instance()->BeginDragDropTarget(); }
inline const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) { return imgui_function_table_instance()->AcceptDragDropPayload(type, flags); }
inline void EndDragDropTarget() { imgui_function_table_instance()->EndDragDropTarget(); }
inline const ImGuiPayload* GetDragDropPayload() { return imgui_function_table_instance()->GetDragDropPayload(); }
inline void BeginDisabled(bool disabled) { imgui_function_table_instance()->BeginDisabled(disabled); }
inline void EndDisabled() { imgui_function_table_instance()->EndDisabled(); }
inline void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { imgui_function_table_instance()->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); }
inline void PopClipRect() { imgui_function_table_instance()->PopClipRect(); }
inline void SetItemDefaultFocus() { imgui_function_table_instance()->SetItemDefaultFocus(); }
inline void SetKeyboardFocusHere(int offset) { imgui_function_table_instance()->SetKeyboardFocusHere(offset); }
inline void SetNextItemAllowOverlap() { imgui_function_table_instance()->SetNextItemAllowOverlap(); }
inline bool IsItemHovered(ImGuiHoveredFlags flags) { return imgui_function_table_instance()->IsItemHovered(flags); }
inline bool IsItemActive() { return imgui_function_table_instance()->IsItemActive(); }
inline bool IsItemFocused() { return imgui_function_table_instance()->IsItemFocused(); }
inline bool IsItemClicked(ImGuiMouseButton mouse_button) { return imgui_function_table_instance()->IsItemClicked(mouse_button); }
inline bool IsItemVisible() { return imgui_function_table_instance()->IsItemVisible(); }
inline bool IsItemEdited() { return imgui_function_table_instance()->IsItemEdited(); }
inline bool IsItemActivated() { return imgui_function_table_instance()->IsItemActivated(); }
inline bool IsItemDeactivated() { return imgui_function_table_instance()->IsItemDeactivated(); }
inline bool IsItemDeactivatedAfterEdit() { return imgui_function_table_instance()->IsItemDeactivatedAfterEdit(); }
inline bool IsItemToggledOpen() { return imgui_function_table_instance()->IsItemToggledOpen(); }
inline bool IsAnyItemHovered() { return imgui_function_table_instance()->IsAnyItemHovered(); }
inline bool IsAnyItemActive() { return imgui_function_table_instance()->IsAnyItemActive(); }
inline bool IsAnyItemFocused() { return imgui_function_table_instance()->IsAnyItemFocused(); }
inline ImGuiID GetItemID() { return imgui_function_table_instance()->GetItemID(); }
inline ImVec2 GetItemRectMin() { return imgui_function_table_instance()->GetItemRectMin(); }
inline ImVec2 GetItemRectMax() { return imgui_function_table_instance()->GetItemRectMax(); }
inline ImVec2 GetItemRectSize() { return imgui_function_table_instance()->GetItemRectSize(); }
inline ImDrawList* GetBackgroundDrawList() { return imgui_function_table_instance()->GetBackgroundDrawList(); }
inline ImDrawList* GetForegroundDrawList() { return imgui_function_table_instance()->GetForegroundDrawList(); }
inline ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport) { return imgui_function_table_instance()->GetBackgroundDrawList2(viewport); }
inline ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport) { return imgui_function_table_instance()->GetForegroundDrawList2(viewport); }
inline bool IsRectVisible(const ImVec2& size) { return imgui_function_table_instance()->IsRectVisible(size); }
inline bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) { return imgui_function_table_instance()->IsRectVisible2(rect_min, rect_max); }
inline double GetTime() { return imgui_function_table_instance()->GetTime(); }
inline int GetFrameCount() { return imgui_function_table_instance()->GetFrameCount(); }
inline ImDrawListSharedData* GetDrawListSharedData() { return imgui_function_table_instance()->GetDrawListSharedData(); }
inline const char* GetStyleColorName(ImGuiCol idx) { return imgui_function_table_instance()->GetStyleColorName(idx); }
inline void SetStateStorage(ImGuiStorage* storage) { imgui_function_table_instance()->SetStateStorage(storage); }
inline ImGuiStorage* GetStateStorage() { return imgui_function_table_instance()->GetStateStorage(); }
inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginChildFrame(id, size, flags); }
inline void EndChildFrame() { imgui_function_table_instance()->EndChildFrame(); }
inline ImVec2 CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) { return imgui_function_table_instance()->CalcTextSize(text, text_end, hide_text_after_double_hash, wrap_width); }
inline ImVec4 ColorConvertU32ToFloat4(ImU32 in) { return imgui_function_table_instance()->ColorConvertU32ToFloat4(in); }
inline ImU32 ColorConvertFloat4ToU32(const ImVec4& in) { return imgui_function_table_instance()->ColorConvertFloat4ToU32(in); }
inline void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) { imgui_function_table_instance()->ColorConvertRGBtoHSV(r, g, b, out_h, out_s, out_v); }
inline void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b) { imgui_function_table_instance()->ColorConvertHSVtoRGB(h, s, v, out_r, out_g, out_b); }
inline bool IsKeyDown(ImGuiKey key) { return imgui_function_table_instance()->IsKeyDown(key); }
inline bool IsKeyPressed(ImGuiKey key, bool repeat) { return imgui_function_table_instance()->IsKeyPressed(key, repeat); }
inline bool IsKeyReleased(ImGuiKey key) { return imgui_function_table_instance()->IsKeyReleased(key); }
inline int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate) { return imgui_function_table_instance()->GetKeyPressedAmount(key, repeat_delay, rate); }
inline const char* GetKeyName(ImGuiKey key) { return imgui_function_table_instance()->GetKeyName(key); }
inline void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard) { imgui_function_table_instance()->SetNextFrameWantCaptureKeyboard(want_capture_keyboard); }
inline bool IsMouseDown(ImGuiMouseButton button) { return imgui_function_table_instance()->IsMouseDown(button); }
inline bool IsMouseClicked(ImGuiMouseButton button, bool repeat) { return imgui_function_table_instance()->IsMouseClicked(button, repeat); }
inline bool IsMouseReleased(ImGuiMouseButton button) { return imgui_function_table_instance()->IsMouseReleased(button); }
inline bool IsMouseDoubleClicked(ImGuiMouseButton button) { return imgui_function_table_instance()->IsMouseDoubleClicked(button); }
inline int GetMouseClickedCount(ImGuiMouseButton button) { return imgui_function_table_instance()->GetMouseClickedCount(button); }
inline bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) { return imgui_function_table_instance()->IsMouseHoveringRect(r_min, r_max, clip); }
inline bool IsMousePosValid(const ImVec2* mouse_pos) { return imgui_function_table_instance()->IsMousePosValid(mouse_pos); }
inline bool IsAnyMouseDown() { return imgui_function_table_instance()->IsAnyMouseDown(); }
inline ImVec2 GetMousePos() { return imgui_function_table_instance()->GetMousePos(); }
inline ImVec2 GetMousePosOnOpeningCurrentPopup() { return imgui_function_table_instance()->GetMousePosOnOpeningCurrentPopup(); }
inline bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold) { return imgui_function_table_instance()->IsMouseDragging(button, lock_threshold); }
inline ImVec2 GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold) { return imgui_function_table_instance()->GetMouseDragDelta(button, lock_threshold); }
inline void ResetMouseDragDelta(ImGuiMouseButton button) { imgui_function_table_instance()->ResetMouseDragDelta(button); }
inline ImGuiMouseCursor GetMouseCursor() { return imgui_function_table_instance()->GetMouseCursor(); }
inline void SetMouseCursor(ImGuiMouseCursor cursor_type) { imgui_function_table_instance()->SetMouseCursor(cursor_type); }
inline void SetNextFrameWantCaptureMouse(bool want_capture_mouse) { imgui_function_table_instance()->SetNextFrameWantCaptureMouse(want_capture_mouse); }
inline const char* GetClipboardText() { return imgui_function_table_instance()->GetClipboardText(); }
inline void SetClipboardText(const char* text) { imgui_function_table_instance()->SetClipboardText(text); }
inline void SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data) { imgui_function_table_instance()->SetAllocatorFunctions(alloc_func, free_func, user_data); }
inline void GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data) { imgui_function_table_instance()->GetAllocatorFunctions(p_alloc_func, p_free_func, p_user_data); }
inline void* MemAlloc(size_t size) { return imgui_function_table_instance()->MemAlloc(size); }
inline void MemFree(void* ptr) { imgui_function_table_instance()->MemFree(ptr); }
}
inline int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { return imgui_function_table_instance()->ImGuiStorage_GetInt(this, key, default_val); }
inline void ImGuiStorage::SetInt(ImGuiID key, int val) { imgui_function_table_instance()->ImGuiStorage_SetInt(this, key, val); }
inline bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const { return imgui_function_table_instance()->ImGuiStorage_GetBool(this, key, default_val); }
inline void ImGuiStorage::SetBool(ImGuiID key, bool val) { imgui_function_table_instance()->ImGuiStorage_SetBool(this, key, val); }
inline float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { return imgui_function_table_instance()->ImGuiStorage_GetFloat(this, key, default_val); }
inline void ImGuiStorage::SetFloat(ImGuiID key, float val) { imgui_function_table_instance()->ImGuiStorage_SetFloat(this, key, val); }
inline void* ImGuiStorage::GetVoidPtr(ImGuiID key) const { return imgui_function_table_instance()->ImGuiStorage_GetVoidPtr(this, key); }
inline void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { imgui_function_table_instance()->ImGuiStorage_SetVoidPtr(this, key, val); }
inline int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) { return imgui_function_table_instance()->ImGuiStorage_GetIntRef(this, key, default_val); }
inline bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) { return imgui_function_table_instance()->ImGuiStorage_GetBoolRef(this, key, default_val); }
inline float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) { return imgui_function_table_instance()->ImGuiStorage_GetFloatRef(this, key, default_val); }
inline void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) { return imgui_function_table_instance()->ImGuiStorage_GetVoidPtrRef(this, key, default_val); }
inline void ImGuiStorage::SetAllInt(int val) { imgui_function_table_instance()->ImGuiStorage_SetAllInt(this, val); }
inline void ImGuiStorage::BuildSortByKey() { imgui_function_table_instance()->ImGuiStorage_BuildSortByKey(this); }
inline ImGuiListClipper::ImGuiListClipper() { imgui_function_table_instance()->ConstructImGuiListClipper(this); }
inline ImGuiListClipper::~ImGuiListClipper() { imgui_function_table_instance()->DestructImGuiListClipper(this); }
inline void ImGuiListClipper::Begin(int items_count, float items_height) { imgui_function_table_instance()->ImGuiListClipper_Begin(this, items_count, items_height); }
inline void ImGuiListClipper::End() { imgui_function_table_instance()->ImGuiListClipper_End(this); }
inline bool ImGuiListClipper::Step() { return imgui_function_table_instance()->ImGuiListClipper_Step(this); }
inline void ImGuiListClipper::IncludeRangeByIndices(int item_begin, int item_end) { imgui_function_table_instance()->ImGuiListClipper_IncludeRangeByIndices(this, item_begin, item_end); }
inline void ImDrawList::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { imgui_function_table_instance()->ImDrawList_PushClipRect(this, clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); }
inline void ImDrawList::PushClipRectFullScreen() { imgui_function_table_instance()->ImDrawList_PushClipRectFullScreen(this); }
inline void ImDrawList::PopClipRect() { imgui_function_table_instance()->ImDrawList_PopClipRect(this); }
inline void ImDrawList::PushTextureID(ImTextureID texture_id) { imgui_function_table_instance()->ImDrawList_PushTextureID(this, texture_id); }
inline void ImDrawList::PopTextureID() { imgui_function_table_instance()->ImDrawList_PopTextureID(this); }
inline void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness) { imgui_function_table_instance()->ImDrawList_AddLine(this, p1, p2, col, thickness); }
inline void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) { imgui_function_table_instance()->ImDrawList_AddRect(this, p_min, p_max, col, rounding, flags, thickness); }
inline void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags) { imgui_function_table_instance()->ImDrawList_AddRectFilled(this, p_min, p_max, col, rounding, flags); }
inline void ImDrawList::AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left) { imgui_function_table_instance()->ImDrawList_AddRectFilledMultiColor(this, p_min, p_max, col_upr_left, col_upr_right, col_bot_right, col_bot_left); }
inline void ImDrawList::AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness) { imgui_function_table_instance()->ImDrawList_AddQuad(this, p1, p2, p3, p4, col, thickness); }
inline void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddQuadFilled(this, p1, p2, p3, p4, col); }
inline void ImDrawList::AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness) { imgui_function_table_instance()->ImDrawList_AddTriangle(this, p1, p2, p3, col, thickness); }
inline void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddTriangleFilled(this, p1, p2, p3, col); }
inline void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) { imgui_function_table_instance()->ImDrawList_AddCircle(this, center, radius, col, num_segments, thickness); }
inline void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) { imgui_function_table_instance()->ImDrawList_AddCircleFilled(this, center, radius, col, num_segments); }
inline void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) { imgui_function_table_instance()->ImDrawList_AddNgon(this, center, radius, col, num_segments, thickness); }
inline void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) { imgui_function_table_instance()->ImDrawList_AddNgonFilled(this, center, radius, col, num_segments); }
inline void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) { imgui_function_table_instance()->ImDrawList_AddText(this, pos, col, text_begin, text_end); }
inline void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) { imgui_function_table_instance()->ImDrawList_AddText2(this, font, font_size, pos, col, text_begin, text_end, wrap_width, cpu_fine_clip_rect); }
inline void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness) { imgui_function_table_instance()->ImDrawList_AddPolyline(this, points, num_points, col, flags, thickness); }
inline void ImDrawList::AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddConvexPolyFilled(this, points, num_points, col); }
inline void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) { imgui_function_table_instance()->ImDrawList_AddBezierCubic(this, p1, p2, p3, p4, col, thickness, num_segments); }
inline void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments) { imgui_function_table_instance()->ImDrawList_AddBezierQuadratic(this, p1, p2, p3, col, thickness, num_segments); }
inline void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddImage(this, user_texture_id, p_min, p_max, uv_min, uv_max, col); }
inline void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1, const ImVec2& uv2, const ImVec2& uv3, const ImVec2& uv4, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddImageQuad(this, user_texture_id, p1, p2, p3, p4, uv1, uv2, uv3, uv4, col); }
inline void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags) { imgui_function_table_instance()->ImDrawList_AddImageRounded(this, user_texture_id, p_min, p_max, uv_min, uv_max, col, rounding, flags); }
inline void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) { imgui_function_table_instance()->ImDrawList_PathArcTo(this, center, radius, a_min, a_max, num_segments); }
inline void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12) { imgui_function_table_instance()->ImDrawList_PathArcToFast(this, center, radius, a_min_of_12, a_max_of_12); }
inline void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) { imgui_function_table_instance()->ImDrawList_PathBezierCubicCurveTo(this, p2, p3, p4, num_segments); }
inline void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments) { imgui_function_table_instance()->ImDrawList_PathBezierQuadraticCurveTo(this, p2, p3, num_segments); }
inline void ImDrawList::PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding, ImDrawFlags flags) { imgui_function_table_instance()->ImDrawList_PathRect(this, rect_min, rect_max, rounding, flags); }
inline void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { imgui_function_table_instance()->ImDrawList_AddCallback(this, callback, callback_data); }
inline void ImDrawList::AddDrawCmd() { imgui_function_table_instance()->ImDrawList_AddDrawCmd(this); }
inline ImDrawList* ImDrawList::CloneOutput() const { return imgui_function_table_instance()->ImDrawList_CloneOutput(this); }
inline void ImDrawList::PrimReserve(int idx_count, int vtx_count) { imgui_function_table_instance()->ImDrawList_PrimReserve(this, idx_count, vtx_count); }
inline void ImDrawList::PrimUnreserve(int idx_count, int vtx_count) { imgui_function_table_instance()->ImDrawList_PrimUnreserve(this, idx_count, vtx_count); }
inline void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col) { imgui_function_table_instance()->ImDrawList_PrimRect(this, a, b, col); }
inline void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col) { imgui_function_table_instance()->ImDrawList_PrimRectUV(this, a, b, uv_a, uv_b, col); }
inline void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) { imgui_function_table_instance()->ImDrawList_PrimQuadUV(this, a, b, c, d, uv_a, uv_b, uv_c, uv_d, col); }
inline ImFont::ImFont() { imgui_function_table_instance()->ConstructImFont(this); }
inline ImFont::~ImFont() { imgui_function_table_instance()->DestructImFont(this); }
inline const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const { return imgui_function_table_instance()->ImFont_FindGlyph(this, c); }
inline const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const { return imgui_function_table_instance()->ImFont_FindGlyphNoFallback(this, c); }
inline ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const { return imgui_function_table_instance()->ImFont_CalcTextSizeA(this, size, max_width, wrap_width, text_begin, text_end, remaining); }
inline const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const { return imgui_function_table_instance()->ImFont_CalcWordWrapPositionA(this, scale, text, text_end, wrap_width); }
inline void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const { imgui_function_table_instance()->ImFont_RenderChar(this, draw_list, size, pos, col, c); }
inline void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const { imgui_function_table_instance()->ImFont_RenderText(this, draw_list, size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip); }
#endif
#endif