mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Use ImGuiWindow from gen, support AddCallback
This commit is contained in:
parent
f7749237ee
commit
1a15600a8f
9 changed files with 91 additions and 87 deletions
|
|
@ -1,3 +1,3 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interface_005Cfontawesome/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Int64 x:Key="/Default/PerformanceThreshold/AnalysisFileSizeThreshold/=CSHARP/@EntryIndexedValue">300000</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interface_005Cfontawesome/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interface_005Ctextures_005Ctexturewraps_005Cinternal_005Cdrawlisttexturewrap/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
|
|
|||
|
|
@ -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<ImDrawCmd>(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*<ImDrawListPtr, ref ImDrawCmd, void>)cmd.UserCallback;
|
||||
cb(cmdList, ref cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
|||
/// <inheritdoc/>
|
||||
public void ResizeAndDrawWindow(ReadOnlySpan<char> 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<char> 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<nint> ChildWindows;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
imgui/Dalamud.Bindings.ImGui/Custom/ImDrawCallbackEnum.cs
Normal file
15
imgui/Dalamud.Bindings.ImGui/Custom/ImDrawCallbackEnum.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace Dalamud.Bindings.ImGui;
|
||||
|
||||
public enum ImDrawCallbackEnum
|
||||
{
|
||||
Empty,
|
||||
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
ResetRenderState = -1,
|
||||
}
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Dalamud.Bindings.ImGui;
|
||||
|
||||
public unsafe partial class ImGui
|
||||
|
|
|
|||
|
|
@ -6,6 +6,26 @@ namespace Dalamud.Bindings.ImGui;
|
|||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public static unsafe partial class ImGui
|
||||
{
|
||||
public static void AddCallback(
|
||||
ImDrawListPtr self, delegate*<ImDrawList*, ImDrawCmd*, void> callback, void* callbackData = null) =>
|
||||
((delegate* unmanaged[Cdecl]<ImDrawList*, delegate*<ImDrawList*, ImDrawCmd*, void>, void*, void>)funcTable
|
||||
[540])(self, callback, callbackData);
|
||||
|
||||
public static void AddCallback(
|
||||
ImDrawListPtr self, delegate*<ImDrawListPtr, ImDrawCmdPtr, void> callback, void* callbackData = null) =>
|
||||
AddCallback(self, (delegate*<ImDrawList*, ImDrawCmd*, void>)callback, callbackData);
|
||||
|
||||
public static void AddCallback(
|
||||
ImDrawListPtr self, delegate*<ref ImDrawList, ref ImDrawCmd, void> callback, void* callbackData = null) =>
|
||||
AddCallback(self, (delegate*<ImDrawList*, ImDrawCmd*, void>)callback, callbackData);
|
||||
|
||||
public static void AddCallback(ImDrawListPtr self, ImDrawCallbackEnum presetCallback)
|
||||
{
|
||||
if (!Enum.IsDefined(presetCallback))
|
||||
throw new ArgumentOutOfRangeException(nameof(presetCallback), presetCallback, null);
|
||||
AddCallback(self, (delegate*<ImDrawList*, ImDrawCmd*, void>)(nint)presetCallback);
|
||||
}
|
||||
|
||||
public static ImGuiPayloadPtr AcceptDragDropPayload(
|
||||
ImU8String type, ImGuiDragDropFlags flags = ImGuiDragDropFlags.None)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=custom/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue