xtuzy / Veldrid.Maui.Controls

use Gpu by Veldrid in MAUI
MIT License
5 stars 1 forks source link

Is it possible to use ImGui with VeldridView? #1

Closed SergeyLipskiy-Qonic closed 8 months ago

SergeyLipskiy-Qonic commented 8 months ago

Hello @xtuzy. I'm working on an experimental MAUI app, which manipulates with 3D models. The only option I found to add a 3D view to MAUI app is your Veldrid.Maui.Controls.VeldridView It works. I'd like to display some debug info in the 3D view. Is it possible to use Veldrid.ImGuiRenderer with VeldridView somehow? I found this example, which explains how to use ImGui with Veldrid in general: https://github.com/veldrid/veldrid/issues/91 It says, that ImGuiRenderer should be updated every frame, and "it needs a new InputSnapshot, which you get from the window.". I don't see, how to get InputSnapshot with VeldridView. I tried to use ImGui without it, like

protected override void Draw(float deltaSeconds)
{
        ImGui.Begin("Test Window");
        ImGui.Text("Hello");
        ImGui.End();

        _commandList.Begin();
        _commandList.SetFramebuffer(MainSwapchain.Framebuffer);
        _commandList.ClearColorTarget(0, BackgroundColor);
        _imguiRenderer.Render(GraphicsDevice, _commandList);
        _commandList.End();
        GraphicsDevice?.SubmitCommands(_commandList);
        GraphicsDevice?.SwapBuffers(MainSwapchain);
}

but no text displayed.

xtuzy commented 8 months ago
  1. when VeldridView.AutoReDraw = true;, VeldridView will every "frame" update, notice, it is not precise every frame, i use platform method update it.
  2. VeldridView is view, not window, so we need custom InputSnapshot, MAUI control have gesture, so you can according to gesture custom InputeSnapshot.

I try use a empty InputSnapshot in Demo, it will show image

protected unsafe override void CreateResources(ResourceFactory factory)
{
...
    // [1]
    imguiRenderer = new ImGuiRenderer(
        GraphicsDevice,
        GraphicsDevice.MainSwapchain.Framebuffer.OutputDescription,
        (int)PlatformInterface.Width,
        (int)PlatformInterface.Height);
}
class MyInputSnapshot : InputSnapshot
{
    public IReadOnlyList<KeyEvent> KeyEvents { get; set; } = new List<KeyEvent>();
    public IReadOnlyList<MouseEvent> MouseEvents { get; set; } = new List<MouseEvent>();
    public IReadOnlyList<char> KeyCharPresses { get; set; } = new List<char>();
    public Vector2 MousePosition { get; set;  }= new Vector2 { };
    public float WheelDelta { get; }
    public bool IsMouseDown(MouseButton button){return false;}
}
InputSnapshot inputSnapshot = new MyInputSnapshot();
ImGuiRenderer imguiRenderer;
protected override void Draw(float deltaSeconds)
{
    imguiRenderer.Update(1f / 60f, inputSnapshot);
    ImGui.Begin("Test Window");
    ImGui.ColorButton("hello", new Vector4(20, 20, 20, 0));
    ImGui.Text("Hello");
    ImGui.End();
    // Begin() must be called before commands can be issued.
    _commandList.Begin();

    _commandList.SetFramebuffer(MainSwapchain.Framebuffer);
    _commandList.ClearColorTarget(0, RgbaFloat.Black);
    imguiRenderer.Render(GraphicsDevice, _commandList);
...
}
SergeyLipskiy-Qonic commented 8 months ago

The dummy class MyInputSnapshot does the trick - ImGui graphics started to display in my app too. Thanks! You're right, now I need to create MAUI gestures based InputSnapshot class to make ImGui controls work correctly.