diff --git a/Dalamud/Dalamud.csproj.DotSettings b/Dalamud/Dalamud.csproj.DotSettings
index 9089754a3..e723e4da1 100644
--- a/Dalamud/Dalamud.csproj.DotSettings
+++ b/Dalamud/Dalamud.csproj.DotSettings
@@ -1,3 +1,3 @@
-True
-300000
+True
+ True
diff --git a/Dalamud/Interface/ImGuiBackend/Renderers/Dx11Renderer.cs b/Dalamud/Interface/ImGuiBackend/Renderers/Dx11Renderer.cs
index 080b52427..9e97a11b8 100644
--- a/Dalamud/Interface/ImGuiBackend/Renderers/Dx11Renderer.cs
+++ b/Dalamud/Interface/ImGuiBackend/Renderers/Dx11Renderer.cs
@@ -343,31 +343,50 @@ internal unsafe partial class Dx11Renderer : IImGuiRenderer
var vertexOffset = 0;
var indexOffset = 0;
var clipOff = new Vector4(drawData.DisplayPos, drawData.DisplayPos.X, drawData.DisplayPos.Y);
+ this.context.Get()->PSSetShader(this.pixelShader, null, 0);
+ this.context.Get()->PSSetSamplers(0, 1, this.sampler.GetAddressOf());
foreach (ref var cmdList in cmdLists)
{
var cmds = new ImVectorWrapper(cmdList.Handle->CmdBuffer.ToUntyped());
foreach (ref var cmd in cmds.DataSpan)
{
- var clipV4 = cmd.ClipRect - clipOff;
- var clipRect = new RECT((int)clipV4.X, (int)clipV4.Y, (int)clipV4.Z, (int)clipV4.W);
-
- // Skip the draw if nothing would be visible
- if (clipRect.left >= clipRect.right || clipRect.top >= clipRect.bottom)
- continue;
-
- this.context.Get()->RSSetScissorRects(1, &clipRect);
-
- if (cmd.UserCallback == null)
+ switch ((ImDrawCallbackEnum)(nint)cmd.UserCallback)
{
- // Bind texture and draw
- var srv = (ID3D11ShaderResourceView*)cmd.TextureId.Handle;
- this.context.Get()->PSSetShader(this.pixelShader, null, 0);
- this.context.Get()->PSSetSamplers(0, 1, this.sampler.GetAddressOf());
- this.context.Get()->PSSetShaderResources(0, 1, &srv);
- this.context.Get()->DrawIndexed(
- cmd.ElemCount,
- (uint)(cmd.IdxOffset + indexOffset),
- (int)(cmd.VtxOffset + vertexOffset));
+ case ImDrawCallbackEnum.Empty:
+ {
+ var clipV4 = cmd.ClipRect - clipOff;
+ var clipRect = new RECT((int)clipV4.X, (int)clipV4.Y, (int)clipV4.Z, (int)clipV4.W);
+
+ // Skip the draw if nothing would be visible
+ if (clipRect.left >= clipRect.right || clipRect.top >= clipRect.bottom)
+ continue;
+
+ this.context.Get()->RSSetScissorRects(1, &clipRect);
+
+ // Bind texture and draw
+ var srv = (ID3D11ShaderResourceView*)cmd.TextureId.Handle;
+ this.context.Get()->PSSetShaderResources(0, 1, &srv);
+ this.context.Get()->DrawIndexed(
+ cmd.ElemCount,
+ (uint)(cmd.IdxOffset + indexOffset),
+ (int)(cmd.VtxOffset + vertexOffset));
+ break;
+ }
+
+ case ImDrawCallbackEnum.ResetRenderState:
+ {
+ // Special callback value used by the user to request the renderer to reset render state.
+ this.SetupRenderState(drawData);
+ break;
+ }
+
+ default:
+ {
+ // User callback, registered via ImDrawList::AddCallback()
+ var cb = (delegate*)cmd.UserCallback;
+ cb(cmdList, ref cmd);
+ break;
+ }
}
}
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
index 34403fd16..1ebd681d9 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
@@ -71,7 +71,7 @@ internal class TexWidget : IDataWindowWidget
private enum DrawBlameTableColumnUserId
{
- NativeAddress,
+ NativeAddress = 1,
Actions,
Name,
Width,
@@ -231,7 +231,7 @@ internal class TexWidget : IDataWindowWidget
ImGui.PopID();
}
- if (ImGui.CollapsingHeader($"CropCopy##{this.DrawExistingTextureModificationArgs}"))
+ if (ImGui.CollapsingHeader($"CropCopy##{nameof(this.DrawExistingTextureModificationArgs)}"))
{
ImGui.PushID(nameof(this.DrawExistingTextureModificationArgs));
this.DrawExistingTextureModificationArgs();
diff --git a/Dalamud/Interface/Textures/TextureWraps/Internal/DrawListTextureWrap/WindowPrinter.cs b/Dalamud/Interface/Textures/TextureWraps/Internal/DrawListTextureWrap/WindowPrinter.cs
index e9a786a8c..18eaab37c 100644
--- a/Dalamud/Interface/Textures/TextureWraps/Internal/DrawListTextureWrap/WindowPrinter.cs
+++ b/Dalamud/Interface/Textures/TextureWraps/Internal/DrawListTextureWrap/WindowPrinter.cs
@@ -1,9 +1,4 @@
-using System.Diagnostics;
-using System.Linq;
using System.Numerics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
using Dalamud.Bindings.ImGui;
@@ -15,13 +10,13 @@ internal sealed unsafe partial class DrawListTextureWrap
///
public void ResizeAndDrawWindow(ReadOnlySpan windowName, Vector2 scale)
{
- ref var window = ref ImGuiWindow.FindWindowByName(windowName);
- if (Unsafe.IsNullRef(ref window))
+ var window = ImGuiP.FindWindowByName(windowName);
+ if (window.IsNull)
throw new ArgumentException("Window not found", nameof(windowName));
this.Size = window.Size;
- var numDrawList = CountDrawList(ref window);
+ var numDrawList = CountDrawList(window);
var drawLists = stackalloc ImDrawList*[numDrawList];
var drawData = new ImDrawData
{
@@ -34,7 +29,7 @@ internal sealed unsafe partial class DrawListTextureWrap
DisplaySize = window.Size,
FramebufferScale = scale,
};
- AddWindowToDrawData(ref window, ref drawLists);
+ AddWindowToDrawData(window, ref drawLists);
for (var i = 0; i < numDrawList; i++)
{
drawData.TotalVtxCount += drawData.CmdLists[i]->VtxBuffer.Size;
@@ -45,10 +40,9 @@ internal sealed unsafe partial class DrawListTextureWrap
return;
- static bool IsWindowActiveAndVisible(scoped in ImGuiWindow window) =>
- window.Active != 0 && window.Hidden == 0;
+ static bool IsWindowActiveAndVisible(ImGuiWindowPtr window) => window is { Active: true, Hidden: false };
- static void AddWindowToDrawData(scoped ref ImGuiWindow window, ref ImDrawList** wptr)
+ static void AddWindowToDrawData(ImGuiWindowPtr window, ref ImDrawList** wptr)
{
switch (window.DrawList.CmdBuffer.Size)
{
@@ -63,13 +57,13 @@ internal sealed unsafe partial class DrawListTextureWrap
for (var i = 0; i < window.DC.ChildWindows.Size; i++)
{
- ref var child = ref *(ImGuiWindow*)window.DC.ChildWindows[i];
- if (IsWindowActiveAndVisible(in child)) // Clipped children may have been marked not active
- AddWindowToDrawData(ref child, ref wptr);
+ var child = window.DC.ChildWindows[i];
+ if (IsWindowActiveAndVisible(child)) // Clipped children may have been marked not active
+ AddWindowToDrawData(child, ref wptr);
}
}
- static int CountDrawList(scoped ref ImGuiWindow window)
+ static int CountDrawList(ImGuiWindowPtr window)
{
var res = window.DrawList.CmdBuffer.Size switch
{
@@ -79,51 +73,8 @@ internal sealed unsafe partial class DrawListTextureWrap
_ => 1,
};
for (var i = 0; i < window.DC.ChildWindows.Size; i++)
- res += CountDrawList(ref *(ImGuiWindow*)window.DC.ChildWindows[i]);
+ res += CountDrawList(window.DC.ChildWindows[i]);
return res;
}
}
-
- [StructLayout(LayoutKind.Explicit, Size = 0x448)]
- private struct ImGuiWindow
- {
- [FieldOffset(0x048)]
- public Vector2 Pos;
-
- [FieldOffset(0x050)]
- public Vector2 Size;
-
- [FieldOffset(0x0CB)]
- public byte Active;
-
- [FieldOffset(0x0D2)]
- public byte Hidden;
-
- [FieldOffset(0x118)]
- public ImGuiWindowTempData DC;
-
- [FieldOffset(0x2C0)]
- public ImDrawListPtr DrawList;
-
- [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
-#pragma warning disable SA1300
- public static extern ImGuiWindow* igCustom_FindWindowByName(byte* inherit);
-#pragma warning restore SA1300
-
- public static ref ImGuiWindow FindWindowByName(ReadOnlySpan name)
- {
- var nb = Encoding.UTF8.GetByteCount(name);
- var buf = stackalloc byte[nb + 1];
- buf[Encoding.UTF8.GetBytes(name, new(buf, nb))] = 0;
-
- return ref *igCustom_FindWindowByName(buf);
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 0xF0)]
- public struct ImGuiWindowTempData
- {
- [FieldOffset(0x98)]
- public ImVector ChildWindows;
- }
- }
}
diff --git a/imgui/Dalamud.Bindings.ImGui/Custom/ImDrawCallbackEnum.cs b/imgui/Dalamud.Bindings.ImGui/Custom/ImDrawCallbackEnum.cs
new file mode 100644
index 000000000..4865d903c
--- /dev/null
+++ b/imgui/Dalamud.Bindings.ImGui/Custom/ImDrawCallbackEnum.cs
@@ -0,0 +1,15 @@
+namespace Dalamud.Bindings.ImGui;
+
+public enum ImDrawCallbackEnum
+{
+ Empty,
+
+ ///
+ /// Special Draw callback value to request renderer backend to reset the graphics/render state.
+ /// The renderer backend needs to handle this special value, otherwise it will crash trying to call a function at
+ /// this address. This is useful for example if you submitted callbacks which you know have altered the render
+ /// state, and you want it to be restored. It is not done by default because they are many perfectly useful way of
+ /// altering render state for imgui contents (e.g. changing shader/blending settings before an Image call).
+ ///
+ ResetRenderState = -1,
+}
diff --git a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Custom.cs b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Custom.cs
index faf6859a3..6e3420f49 100644
--- a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Custom.cs
+++ b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Custom.cs
@@ -1,6 +1,3 @@
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
namespace Dalamud.Bindings.ImGui;
public unsafe partial class ImGui
diff --git a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Misc.cs b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Misc.cs
index a2a138626..64629ccfc 100644
--- a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Misc.cs
+++ b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Misc.cs
@@ -6,6 +6,26 @@ namespace Dalamud.Bindings.ImGui;
[SuppressMessage("ReSharper", "InconsistentNaming")]
public static unsafe partial class ImGui
{
+ public static void AddCallback(
+ ImDrawListPtr self, delegate* callback, void* callbackData = null) =>
+ ((delegate* unmanaged[Cdecl], void*, void>)funcTable
+ [540])(self, callback, callbackData);
+
+ public static void AddCallback(
+ ImDrawListPtr self, delegate* callback, void* callbackData = null) =>
+ AddCallback(self, (delegate*)callback, callbackData);
+
+ public static void AddCallback(
+ ImDrawListPtr self, delegate*[ callback, void* callbackData = null) =>
+ AddCallback(self, (delegate*)callback, callbackData);
+
+ public static void AddCallback(ImDrawListPtr self, ImDrawCallbackEnum presetCallback)
+ {
+ if (!Enum.IsDefined(presetCallback))
+ throw new ArgumentOutOfRangeException(nameof(presetCallback), presetCallback, null);
+ AddCallback(self, (delegate*)(nint)presetCallback);
+ }
+
public static ImGuiPayloadPtr AcceptDragDropPayload(
ImU8String type, ImGuiDragDropFlags flags = ImGuiDragDropFlags.None)
{
diff --git a/imgui/Dalamud.Bindings.ImGui/Dalamud.Bindings.ImGui.csproj.DotSettings b/imgui/Dalamud.Bindings.ImGui/Dalamud.Bindings.ImGui.csproj.DotSettings
new file mode 100644
index 000000000..06f483845
--- /dev/null
+++ b/imgui/Dalamud.Bindings.ImGui/Dalamud.Bindings.ImGui.csproj.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/imgui/Dalamud.Bindings.ImGui/ImTextureID.cs b/imgui/Dalamud.Bindings.ImGui/ImTextureID.cs
index 53643ab9f..7be18f2dc 100644
--- a/imgui/Dalamud.Bindings.ImGui/ImTextureID.cs
+++ b/imgui/Dalamud.Bindings.ImGui/ImTextureID.cs
@@ -28,7 +28,7 @@ namespace Dalamud.Bindings.ImGui
public ImTextureID(void* handle) { Handle = (ulong)handle; }
public ulong Handle { get; }
public bool IsNull => Handle == 0;
- public static ImTextureID Null => new ImTextureID(0);
+ public static ImTextureID Null => default;
public static implicit operator ImTextureID(ulong handle) => new ImTextureID(handle);
public static bool operator ==(ImTextureID left, ImTextureID right) => left.Handle == right.Handle;
public static bool operator !=(ImTextureID left, ImTextureID right) => left.Handle != right.Handle;
]