void LateUpdate() { last_start = stopwatch.Elapsed.TotalSeconds; if (drawDebugWindow) { DrawDebugWindow(); } ImGui.EndFrame(); if (queue_font_rebuild) { RebuildFonts(); queue_font_rebuild = false; } // custom cursors if (enableCustomCursors) { ImGuiMouseCursor cursor = ImGui.GetMouseCursor(); Texture2D cursorTex = null; Vector2 hotspot = cursorHotspot; switch (cursor) { case ImGuiMouseCursor.Arrow: cursorTex = customCursorArrow; break; case ImGuiMouseCursor.TextInput: cursorTex = customCursorTextInput; break; case ImGuiMouseCursor.ResizeEW: cursorTex = customCursorResizeEW; break; case ImGuiMouseCursor.ResizeNESW: cursorTex = customCursorResizeNESW; hotspot.x += 5; hotspot.y += 5; break; case ImGuiMouseCursor.ResizeNS: cursorTex = customCursorResizeNS; break; case ImGuiMouseCursor.ResizeNWSE: cursorTex = customCursorResizeNWSE; hotspot.x += 5; hotspot.y += 5; break; default: break; } // Don't set cursor if it has not actually changed if (currentCursorTex != cursorTex) { if (cursorTex != null) { Cursor.SetCursor(cursorTex, hotspot, CursorMode.Auto); } else { Cursor.SetCursor(null, cursorHotspot, CursorMode.Auto); } currentCursorTex = cursorTex; } } ImGui.Render(); // render ImGui ImDrawDataPtr data = ImGui.GetDrawData(); if (commandBuffer != null) { // Clear buffer regardless of whether we have something to render or not commandBuffer.Clear(); } // Don't update meshes and Command Buffers if there is nothing to render if (data.CmdListsCount > 0) { // resize meshes array int numDrawCommands = 0; for (int i = 0; i < data.CmdListsCount; i++) { ImDrawListPtr cmdList = data.getDrawListPtr(i); var cmdBuffer = cmdList.CmdBuffer; numDrawCommands += cmdBuffer.Size; } if (meshes == null) { meshes = new List <ImGuiMesh>(); } if (meshes.Count != numDrawCommands) { // add new meshes to list if needed for (int i = meshes.Count; i < numDrawCommands; i++) { ImGuiMesh mesh = new ImGuiMesh(); meshes.Add(mesh); } // delete extra meshes if needed for (int i = meshes.Count - 1; i >= numDrawCommands; i--) { Destroy(meshes[i].mesh); meshes.RemoveAt(i); } } if (commandBuffer == null) { commandBuffer = new CommandBuffer(); commandBuffer.name = "ImGui Renderer"; commandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); guiCamera.AddCommandBuffer(CameraEvent.AfterEverything, commandBuffer); } commandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); // orthogonal projection of GUI mesh to camera space Matrix4x4 matrix = Matrix4x4.Ortho(0, Screen.width, 0, Screen.height, 0, 0.1f); // negate world to camera transform and projection which Unity applies itself matrix = guiCamera.cameraToWorldMatrix * guiCamera.projectionMatrix.inverse * matrix; // update Command Buffers int count = 0; for (int i = 0; i < data.CmdListsCount; i++) { ImDrawListPtr cmdList = data.getDrawListPtr(i); var cmdBuffer = cmdList.CmdBuffer; uint startElement = 0; for (int j = 0; j < cmdBuffer.Size; j++) { ImDrawCmd cmd = cmdBuffer[j]; Rect rect = new Rect { min = new Vector2(cmd.ClipRect.x, Screen.height - cmd.ClipRect.y), max = new Vector2(cmd.ClipRect.z, Screen.height - cmd.ClipRect.w) }; commandBuffer.EnableScissorRect(rect); meshes[count].UpdateMesh(cmd, cmdList.IdxBuffer, cmdList.VtxBuffer, (int)startElement); if (cmd.TextureId == fontTexturePtr) { mpb.SetTexture(main_tex_id, fontTexture); commandBuffer.DrawMesh(meshes[count].mesh, matrix, material, 0, 0, mpb); } else if (textures.ContainsKey(cmd.TextureId)) { mpb.SetTexture(main_tex_id, textures[cmd.TextureId]); commandBuffer.DrawMesh(meshes[count].mesh, matrix, material, 0, 0, mpb); } else { Debug.LogWarning("Image texture missing!"); } startElement += cmd.ElemCount; count++; } } } else if (commandBuffer != null) { // Remove Command Buffer if there is nothing to render guiCamera.RemoveCommandBuffer(CameraEvent.AfterEverything, commandBuffer); commandBuffer = null; } textures.Clear(); last_end = stopwatch.Elapsed.TotalSeconds; }