private unsafe void UpdateMonitors() { if (p_sdl_GetNumVideoDisplays == null) { p_sdl_GetNumVideoDisplays = Sdl2Native.LoadFunction <SDL_GetNumVideoDisplays_t>("SDL_GetNumVideoDisplays"); } if (p_sdl_GetDisplayUsableBounds_t == null) { p_sdl_GetDisplayUsableBounds_t = Sdl2Native.LoadFunction <SDL_GetDisplayUsableBounds_t>("SDL_GetDisplayUsableBounds"); } ImGuiPlatformIOPtr plIo = ImGui.GetPlatformIO(); Marshal.FreeHGlobal(plIo.NativePtr->Monitors.Data); int numMonitors = p_sdl_GetNumVideoDisplays(); IntPtr data = Marshal.AllocHGlobal(Unsafe.SizeOf <ImGuiPlatformMonitor>() * numMonitors); plIo.NativePtr->Monitors = new ImVector(numMonitors, numMonitors, data); for (int i = 0; i < numMonitors; i++) { Rectangle r; p_sdl_GetDisplayUsableBounds_t(i, &r); ImGuiPlatformMonitorPtr monitor = plIo.Monitors[i]; monitor.DpiScale = 1f; monitor.MainPos = new Vector2(r.X, r.Y); monitor.MainSize = new Vector2(r.Width, r.Height); monitor.WorkPos = new Vector2(r.X, r.Y); monitor.WorkSize = new Vector2(r.Width, r.Height); } }
public void SwapExtraWindows(GraphicsDevice gd) { ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO(); for (int i = 1; i < platformIO.Viewports.Size; i++) { ImGuiViewportPtr vp = platformIO.Viewports[i]; VeldridImGuiWindow window = (VeldridImGuiWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target; gd.SwapBuffers(window.Swapchain); } }
/// <summary> /// Sets per-frame data based on the associated window. /// This is called by Update(float). /// </summary> private void SetPerFrameImGuiData(float deltaSeconds) { ImGuiIOPtr io = ImGui.GetIO(); io.DisplaySize = new Vector2( _windowWidth / _scaleFactor.X, _windowHeight / _scaleFactor.Y); io.DisplayFramebufferScale = _scaleFactor; io.DeltaTime = deltaSeconds; // DeltaTime is in seconds. ImGuiPlatformIOPtr platformIo = ImGui.GetPlatformIO(); platformIo.MainViewport.Pos = new Vector2(_window.X, _window.Y); platformIo.MainViewport.Size = new Vector2(_window.Width, _window.Height); }
/// <summary> /// Renders the ImGui draw list data. /// This method requires a <see cref="GraphicsDevice"/> because it may create new DeviceBuffers if the size of vertex /// or index data has increased beyond the capacity of the existing buffers. /// A <see cref="CommandList"/> is needed to submit drawing and resource update commands. /// </summary> public void Render(GraphicsDevice gd, CommandList cl) { if (_frameBegun) { _frameBegun = false; ImGui.Render(); RenderImDrawData(ImGui.GetDrawData(), gd, cl); // Update and Render additional Platform Windows if ((ImGui.GetIO().ConfigFlags & ImGuiConfigFlags.ViewportsEnable) != 0) { ImGui.UpdatePlatformWindows(); ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO(); for (int i = 1; i < platformIO.Viewports.Size; i++) { ImGuiViewportPtr vp = platformIO.Viewports[i]; VeldridImGuiWindow window = (VeldridImGuiWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target; cl.SetFramebuffer(window.Swapchain.Framebuffer); RenderImDrawData(vp.DrawData, gd, cl); } } } }
/// <summary> /// Constructs a new ImGuiController. /// </summary> public ImGuiController(GraphicsDevice gd, Sdl2Window window, OutputDescription outputDescription, int width, int height) { _gd = gd; _window = window; _windowWidth = width; _windowHeight = height; IntPtr context = ImGui.CreateContext(); ImGui.SetCurrentContext(context); ImGuiIOPtr io = ImGui.GetIO(); io.ConfigFlags |= ImGuiConfigFlags.DockingEnable; io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable; ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO(); ImGuiViewportPtr mainViewport = platformIO.MainViewport; _mainViewportWindow = new VeldridImGuiWindow(gd, mainViewport, _window); mainViewport.PlatformHandle = window.Handle; _createWindow = CreateWindow; _destroyWindow = DestroyWindow; _getWindowPos = GetWindowPos; _showWindow = ShowWindow; _setWindowPos = SetWindowPos; _setWindowSize = SetWindowSize; _getWindowSize = GetWindowSize; _setWindowFocus = SetWindowFocus; _getWindowFocus = GetWindowFocus; _getWindowMinimized = GetWindowMinimized; _setWindowTitle = SetWindowTitle; platformIO.Platform_CreateWindow = Marshal.GetFunctionPointerForDelegate(_createWindow); platformIO.Platform_DestroyWindow = Marshal.GetFunctionPointerForDelegate(_destroyWindow); platformIO.Platform_ShowWindow = Marshal.GetFunctionPointerForDelegate(_showWindow); platformIO.Platform_SetWindowPos = Marshal.GetFunctionPointerForDelegate(_setWindowPos); platformIO.Platform_SetWindowSize = Marshal.GetFunctionPointerForDelegate(_setWindowSize); platformIO.Platform_SetWindowFocus = Marshal.GetFunctionPointerForDelegate(_setWindowFocus); platformIO.Platform_GetWindowFocus = Marshal.GetFunctionPointerForDelegate(_getWindowFocus); platformIO.Platform_GetWindowMinimized = Marshal.GetFunctionPointerForDelegate(_getWindowMinimized); platformIO.Platform_SetWindowTitle = Marshal.GetFunctionPointerForDelegate(_setWindowTitle); platformIO.Platform_GetWindowPos = Marshal.GetFunctionPointerForDelegate(_getWindowPos); platformIO.Platform_GetWindowSize = Marshal.GetFunctionPointerForDelegate(_getWindowSize); unsafe { io.NativePtr->BackendPlatformName = (byte *)new FixedAsciiString("Veldrid.SDL2 Backend").DataPtr; } io.BackendFlags |= ImGuiBackendFlags.HasMouseCursors; io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos; io.BackendFlags |= ImGuiBackendFlags.PlatformHasViewports; io.BackendFlags |= ImGuiBackendFlags.RendererHasViewports; io.Fonts.AddFontDefault(); CreateDeviceResources(gd, outputDescription); SetKeyMappings(); SetPerFrameImGuiData(1f / 60f); UpdateMonitors(); ImGui.NewFrame(); _frameBegun = true; }