private void RenderCommandLists(ImDrawDataPtr drawData) { // TODO Pass in the game window to get the screen width and height var m_Ortho = Monorail.Mathlib.Matrix4.CreateOrthographicOffCenter(0, 1280, 800, 0, -1, 1); m_GraphicsDevice.BindVertexArrayObject(m_VertexArrayObject.VaoId); var drawcount = 0; int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi]; var texId = drawCmd.TextureId; OpenGL.GlBindings.Enable(OpenGL.Enable.GL_SCISSOR_TEST); OpenGL.GlBindings.glScissor((int)drawCmd.ClipRect.X, (int)drawCmd.ClipRect.Y, (uint)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X), (uint)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y)); // TODO If textureId not loaded? // m_GraphicsDevice.ScissorRect(); m_GraphicsDevice.BindShaderProgram(m_ShaderProgram.ShaderProgramId); m_GraphicsDevice.BindVertexArrayObject(m_VertexArrayObject.VaoId); m_GraphicsDevice.BindTexture(m_Texture.TextureId, OpenGL.TextureType.GL_TEXTURE_2D); m_ShaderProgram.SetUniform("projection_matrix", m_Ortho); m_ShaderProgram.SetUniform("FontTexture", 0); m_GraphicsDevice.DrawElements(PrimitiveType.TriangleList, (int)drawCmd.ElemCount, DrawElementsType.UnsignedInt, idxOffset); drawcount++; idxOffset += (int)drawCmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } OpenGL.GlBindings.Disable(OpenGL.Enable.GL_SCISSOR_TEST); }
private unsafe void UpdateBuffers(ImDrawDataPtr drawData) { if (drawData.TotalVtxCount == 0) { return; } // Expand buffers if we need more room if (drawData.TotalVtxCount > _vertexBufferSize) { _vertexBuffer?.Dispose(); _vertexBufferSize = (int)(drawData.TotalVtxCount * 1.5f); _vertexBuffer = new VertexBuffer(_graphicsDevice, DrawVertDeclaration.Declaration, _vertexBufferSize, BufferUsage.None); _vertexData = new byte[_vertexBufferSize * DrawVertDeclaration.Size]; } if (drawData.TotalIdxCount > _indexBufferSize) { _indexBuffer?.Dispose(); _indexBufferSize = (int)(drawData.TotalIdxCount * 1.5f); _indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, _indexBufferSize, BufferUsage.None); _indexData = new byte[_indexBufferSize * sizeof(ushort)]; } // Copy ImGui's vertices and indices to a set of managed byte arrays int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; fixed(void *vtxDstPtr = &_vertexData[vtxOffset *DrawVertDeclaration.Size]) fixed(void *idxDstPtr = &_indexData[idxOffset * sizeof(ushort)]) { Buffer.MemoryCopy((void *)cmdList.VtxBuffer.Data, vtxDstPtr, _vertexData.Length, cmdList.VtxBuffer.Size * DrawVertDeclaration.Size); Buffer.MemoryCopy((void *)cmdList.IdxBuffer.Data, idxDstPtr, _indexData.Length, cmdList.IdxBuffer.Size * sizeof(ushort)); } vtxOffset += cmdList.VtxBuffer.Size; idxOffset += cmdList.IdxBuffer.Size; } // Copy the managed byte arrays to the gpu vertex- and index buffers _vertexBuffer.SetData(_vertexData, 0, drawData.TotalVtxCount * DrawVertDeclaration.Size); _indexBuffer.SetData(_indexData, 0, drawData.TotalIdxCount * sizeof(ushort)); }
void UpdateBuffers(ImDrawDataPtr drawData) { // copy de dators int vtxOffsetBytes = 0; int idxOffsetBytes = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; vertexBinding.Buffer.SetData(commandList, new DataPointer(cmdList.VtxBuffer.Data, cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()), vtxOffsetBytes); indexBinding.Buffer.SetData(commandList, new DataPointer(cmdList.IdxBuffer.Data, cmdList.IdxBuffer.Size * sizeof(ushort)), idxOffsetBytes); vtxOffsetBytes += cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); idxOffsetBytes += cmdList.IdxBuffer.Size * sizeof(ushort); } }
public static bool ButtonGradient(string strId, Vector2 buttonSizeVector) { String[] strIdArray = strId.Split("###"); Vector2 p = ImGuiNET.ImGui.GetCursorScreenPos(); Vector2 sizeText = ImGui.CalcTextSize(strIdArray[0]); ImDrawListPtr drawList = ImGuiNET.ImGui.GetWindowDrawList(); //ButtonHeight += ImGuiNET.ImGui.GetFrameHeight(); //Dynamically Allocated Height //float ButtonWidth = sizeText.X + ButtonHeight; //Dynamically Allocated Width float buttonHeight = buttonSizeVector.Y; //Fixed Height float buttonWidth = buttonSizeVector.X; //Dynamically Allocated Width if (buttonWidth < sizeText.X) { buttonWidth = sizeText.X + sizeText.X * 0.20f; } Vector2 buttonSize = new Vector2(p.X + buttonWidth, p.Y + buttonHeight); uint colTop; uint colBottom; if (strIdArray.Length > 1) { if (ImGuiNET.ImGui.InvisibleButton(strIdArray[1], new Vector2(buttonWidth, buttonHeight))) { return(true); } } else { if (ImGuiNET.ImGui.InvisibleButton(strIdArray[0], new Vector2(buttonWidth, buttonHeight))) { return(true); } } if (ImGuiNET.ImGui.IsItemHovered()) { colTop = ImGuiNET.ImGui.GetColorU32(ImGuiCol.ButtonActive); colBottom = ImGuiNET.ImGui.GetColorU32(ImGuiCol.ButtonHovered); } else { colTop = ImGuiNET.ImGui.GetColorU32(ImGuiCol.ButtonHovered); colBottom = ImGuiNET.ImGui.GetColorU32(ImGuiCol.Button); } drawList.AddRectFilledMultiColor(p, buttonSize, colTop, colTop, colBottom, colBottom); drawList.AddRect(p, buttonSize, ImGuiNET.ImGui.GetColorU32(ImGuiCol.ButtonActive)); drawList.AddText(new Vector2(p.X + (buttonWidth / 2) - (sizeText.X / 2), p.Y + (buttonHeight / 2) - (sizeText.Y / 2)), ImGui.GetColorU32(ImGuiCol.Text), strIdArray[0]); return(false); }
private unsafe void RenderCommandLists(ImDrawDataPtr ptr) { GraphicsDevice.SetVertexBuffer(VertexBuffer); GraphicsDevice.Indices = IndexBuffer; int vtxOffset = 0; int idxOffset = 0; for (int i = 0; i < ptr.CmdListsCount; i++) { ImDrawListPtr cmdList = ptr.CmdListsRange[i]; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmdPtr cmd = cmdList.CmdBuffer[cmdi]; if (!Textures.ContainsKey(cmd.TextureId)) { throw new InvalidOperationException($"Could not find ImGUI texture with ID {cmd.TextureId}"); } GraphicsDevice.ScissorRectangle = new Rectangle( (int)cmd.ClipRect.X, (int)cmd.ClipRect.Y, (int)(cmd.ClipRect.Z - cmd.ClipRect.X), (int)(cmd.ClipRect.W - cmd.ClipRect.Y) ); Effect e = UpdateEffect(Textures[cmd.TextureId]); for (int passIndex = 0; passIndex < e.CurrentTechnique.Passes.Count; passIndex++) { EffectPass pass = e.CurrentTechnique.Passes[passIndex]; pass.Apply(); GraphicsDevice.DrawIndexedPrimitives( primitiveType: PrimitiveType.TriangleList, baseVertex: vtxOffset, minVertexIndex: 0, numVertices: cmdList.VtxBuffer.Size, startIndex: idxOffset, primitiveCount: (int)cmd.ElemCount / 3 ); } idxOffset += (int)cmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } }
public static void EndBoarder() { Vector2 size = new Vector2(ImGui.GetContentRegionAvail().X, ImGui.GetCursorScreenPos().Y - _startPos.Y); //ImGui.get ImDrawListPtr wdl = ImGui.GetWindowDrawList(); Vector2[] pts = new Vector2[6]; pts[0] = new Vector2(_startPos.X + 2, _startPos.Y); pts[1] = _startPos; //top left pts[2] = new Vector2(_startPos.X, _startPos.Y + size.Y); //bottom left pts[3] = new Vector2(_startPos.X + size.X + 3, _startPos.Y + size.Y); //bottom right pts[4] = new Vector2(_startPos.X + size.X + 3, _startPos.Y); pts[5] = new Vector2(_startPos.X + _labelSize.X + 3, _startPos.Y); wdl.AddPolyline(ref pts[0], pts.Length, _colour, false, 1.0f); ImGui.PopID(); }
private unsafe void RenderCommandLists(ImDrawDataPtr drawData) { _graphicsDevice.SetVertexBuffer(_vertexBuffer); _graphicsDevice.Indices = _indexBuffer; int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi]; if (!_loadedTextures.ContainsKey(drawCmd.TextureId)) { throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings"); } _graphicsDevice.ScissorRectangle = new Rectangle( (int)drawCmd.ClipRect.X, (int)drawCmd.ClipRect.Y, (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X), (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y) ); var effect = UpdateEffect(_loadedTextures[drawCmd.TextureId]); foreach (var pass in effect.CurrentTechnique.Passes) { pass.Apply(); _graphicsDevice.DrawIndexedPrimitives( PrimitiveType.TriangleList, vtxOffset, idxOffset, (int)drawCmd.ElemCount / 3); } idxOffset += (int)drawCmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } }
private void DrawExperience(ImDrawListPtr drawList, int experience, int maxExp) { int size = (int)Math.Ceiling(256 * Ui.Configuration.Scale); var drawPosition = ImGui.GetItemRectMin() + new Vector2(0, (int)HealthY); ExperienceRingBg.Draw(drawList, 1, drawPosition, 4, Ui.Configuration.Scale); ExperienceRing.Draw(drawList, experience / (float)maxExp, drawPosition, 4, Ui.Configuration.Scale); drawList.PushClipRect(drawPosition, drawPosition + new Vector2(size, size)); drawList.AddImage(RingExperienceBgTexture.ImGuiHandle, drawPosition, drawPosition + new Vector2(size, size)); drawList.PopClipRect(); int iconSize = 64; ImageDrawing.DrawIcon(Pi, drawList, (ushort)(62000 + Pi.ClientState.LocalPlayer.ClassJob.Id), new Vector2(iconSize, iconSize), new Vector2((int)(size / 2f - iconSize / 2f), (int)(size / 2f - iconSize / 2f)) + new Vector2(0, (int)HealthY)); }
private unsafe void UpdateBuffers(ImDrawDataPtr drawData) { if (drawData.TotalVtxCount == 0) { return; } if (drawData.TotalVtxCount > vertexBufferSize) { vertexBuffer?.Dispose(); vertexBufferSize = (int)(drawData.TotalVtxCount * 1.5f); vertexBuffer = new VertexBuffer(GraphicsDevice, DrawVertexDeclaration.Declaration, vertexBufferSize, BufferUsage.None); vertexData = new byte[vertexBufferSize * DrawVertexDeclaration.Size]; } if (drawData.TotalIdxCount > indexBufferSize) { indexBuffer?.Dispose(); indexBufferSize = (int)(drawData.TotalIdxCount * 1.5f); indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, indexBufferSize, BufferUsage.None); indexData = new byte[indexBufferSize * sizeof(ushort)]; } int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; fixed(void *vtxDstPtr = &vertexData[vtxOffset *DrawVertexDeclaration.Size]) fixed(void *idxDstPtr = &indexData[idxOffset * sizeof(ushort)]) { Buffer.MemoryCopy((void *)cmdList.VtxBuffer.Data, vtxDstPtr, vertexData.Length, cmdList.VtxBuffer.Size * DrawVertexDeclaration.Size); Buffer.MemoryCopy((void *)cmdList.IdxBuffer.Data, idxDstPtr, indexData.Length, cmdList.IdxBuffer.Size * sizeof(ushort)); } vtxOffset += cmdList.VtxBuffer.Size; idxOffset += cmdList.IdxBuffer.Size; } vertexBuffer.SetData(vertexData, 0, drawData.TotalVtxCount * DrawVertexDeclaration.Size); indexBuffer.SetData(indexData, 0, drawData.TotalIdxCount * sizeof(ushort)); }
public void Render() { ImGui.BeginChild("Log", Vector2.Zero, false); ReadOnlySpan <LogEvent> logEvents = _logEventRecorder.LogEvents; ImDrawListPtr drawList = ImGui.GetWindowDrawList(); foreach (LogEvent logEvent in logEvents) { Vector4 color = logEvent.LogLevel switch { LogLevel.Information => Vector4.One, LogLevel.Warning => new Vector4(1, 1, 0, 1), LogLevel.Error => new Vector4(1, 0, 0, 1), _ => ThrowHelper.Unreachable <Vector4>() }; Vector2 topLeft = ImGui.GetCursorScreenPos(); Vector2 textSize = ImGui.CalcTextSize(logEvent.Message); ImGui.TextColored(color, logEvent.Message); if (ImGui.IsItemHovered()) { ImGui.BeginTooltip(); ImGui.Text("Copy to clipboard"); ImGui.EndTooltip(); drawList.AddRectFilled( a: topLeft, b: topLeft + textSize, ImGui.GetColorU32(ImGuiCol.FrameBgHovered) ); } if (ImGui.IsItemClicked()) { ImGui.SetClipboardText(logEvent.Message); } } if (logEvents.Length > _prevEventCount) { ImGui.SetScrollHereY(); } _prevEventCount = logEvents.Length; ImGui.EndChild(); } }
private static bool SequencerAddDelButton(ImDrawListPtr draw_list, Vector2 pos, bool add = true) { var io = ImGui.GetIO(); var delRect = new ImRect(pos, new Vector2(pos.X + ButtonSize, pos.Y + ButtonSize)); var overDel = delRect.Contains(io.MousePos); var delColor = overDel ? 0xFFAAAAAAu : 0x50000000u; var midy = pos.Y + 16 / 2 - 0.5f; var midx = pos.X + 16 / 2 - 0.5f; draw_list.AddRect(delRect.Min, delRect.Max, delColor, 4); draw_list.AddLine(new Vector2(delRect.Min.X + 3, midy), new Vector2(delRect.Max.X - 3, midy), delColor, 2); if (add) { draw_list.AddLine(new Vector2(midx, delRect.Min.Y + 3), new Vector2(midx, delRect.Max.Y - 3), delColor, 2); } return(overDel); }
private void DrawLongHealthBar(ImDrawListPtr drawList, Vector2 position, int hp, int maxHp) { var barHeight = 37f; var outlineHeight = 42f; var healthLength = (int)Math.Ceiling((HpTemp * HpLengthMultiplier - Ui.Configuration.HpForFullRing) / Ui.Configuration.HpPerPixelLongBar); var damagedHealthLength = (int)Math.Ceiling((HpBeforeDamaged * HpLengthMultiplier - Ui.Configuration.HpForFullRing) / Ui.Configuration.HpPerPixelLongBar); var restoredHealthLength = (int)Math.Ceiling((hp * HpLengthMultiplier - Ui.Configuration.HpForFullRing) / Ui.Configuration.HpPerPixelLongBar); var maxHealthLength = (int)Math.Ceiling((maxHp * HpLengthMultiplier - Ui.Configuration.HpForFullRing) / Ui.Configuration.HpPerPixelLongBar); var outlineSize = new Vector2(maxHealthLength, outlineHeight); var edgeSize = new Vector2(5, 42); var maxHealthSize = new Vector2(maxHealthLength, barHeight); var barOffset = new Vector2(128, 216) + new Vector2(0, (int)HealthY); var outlineOffset = new Vector2(128, 213) + new Vector2(0, (int)HealthY); if (maxHealthLength > 0) { DrawBar(drawList, position, barOffset, maxHealthSize, new Vector4(10, 1, 1, 37f), ImGui.GetColorU32(new Vector4(0.07843f, 0.07843f, 0.0745f, 1))); } if (damagedHealthLength > 0) { DrawBar(drawList, position, barOffset, new Vector2(damagedHealthLength, barHeight), new Vector4(10, 1, 1, 37f), ImGui.GetColorU32(new Vector4(1f, 0f, 0f, DamagedHealthAlpha))); } if (restoredHealthLength > 0) { DrawBar(drawList, position, barOffset, new Vector2(restoredHealthLength, barHeight), new Vector4(14, 1, 1, 37f)); } if (healthLength > 0) { DrawBar(drawList, position, barOffset, new Vector2(healthLength, barHeight), new Vector4(6, 1, 1, 37f)); } if (maxHealthLength > 0) { DrawBar(drawList, position, outlineOffset, outlineSize, new Vector4(2, 1, 1, 42f)); var edgeOffset = new Vector2(-maxHealthLength - 5, 0); drawList.PushClipRect(position + outlineOffset + edgeOffset, position + outlineOffset + edgeOffset + edgeSize); ImageDrawing.DrawImage(drawList, BarTextures, edgeSize, outlineOffset + edgeOffset, new Vector4(17, 1, 5, 42f)); drawList.PopClipRect(); } }
void CreateDrawCommands(CommandBuffer cmd, ImDrawDataPtr drawData, Vector2 fbSize) { var prevTextureId = System.IntPtr.Zero; var clipOffst = new Vector4(drawData.DisplayPos.x, drawData.DisplayPos.y, drawData.DisplayPos.x, drawData.DisplayPos.y); var clipScale = new Vector4(drawData.FramebufferScale.x, drawData.FramebufferScale.y, drawData.FramebufferScale.x, drawData.FramebufferScale.y); _material.SetBuffer(_verticesID, _vtxBuf); // bind vertex buffer cmd.SetViewport(new Rect(0f, 0f, fbSize.x, fbSize.y)); cmd.SetViewProjectionMatrices( Matrix4x4.Translate(new Vector3(0.5f / fbSize.x, 0.5f / fbSize.y, 0f)), // small adjustment to improve text Matrix4x4.Ortho(0f, fbSize.x, fbSize.y, 0f, 0f, 1f)); int vtxOf = 0; int argOf = 0; for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n) { ImDrawListPtr drawList = drawData.CmdListsRange[n]; for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i, argOf += 5 * 4) { ImDrawCmdPtr drawCmd = drawList.CmdBuffer[i]; // TODO: user callback in drawCmd.UserCallback & drawCmd.UserCallbackData // project scissor rectangle into framebuffer space and skip if fully outside var clip = Vector4.Scale(drawCmd.ClipRect - clipOffst, clipScale); if (clip.x >= fbSize.x || clip.y >= fbSize.y || clip.z < 0f || clip.w < 0f) { continue; } if (prevTextureId != drawCmd.TextureId) { _properties.SetTexture(_texID, _texManager.GetTexture((int)(prevTextureId = drawCmd.TextureId))); } _properties.SetInt(_baseVertexID, vtxOf + (int)drawCmd.VtxOffset); // base vertex location not automatically added to SV_VertexID cmd.EnableScissorRect(new Rect(clip.x, fbSize.y - clip.w, clip.z - clip.x, clip.w - clip.y)); // invert y cmd.DrawProceduralIndirect(_idxBuf, Matrix4x4.identity, _material, -1, MeshTopology.Triangles, _argBuf, argOf, _properties); } vtxOf += drawList.VtxBuffer.Size; } cmd.DisableScissorRect(); }
private static void DrawPreviewZoomEnvelope(PlottedGraph plot, Vector2 subGraphPosition) { ImDrawListPtr imdp = ImGui.GetWindowDrawList(); float previewBaseY = subGraphPosition.Y + EachGraphHeight; plot.GetPreviewVisibleRegion(new Vector2(EachGraphWidth, EachGraphHeight), PreviewProjection, out Vector2 TopLeft, out Vector2 BaseRight); float C1Y = previewBaseY - TopLeft.Y; float C2Y = previewBaseY - BaseRight.Y; bool verySmall = Math.Abs(C1Y - C2Y) < 20; uint colour = verySmall ? Themes.GetThemeColourUINT(Themes.eThemeColour.Emphasis1) : Themes.GetThemeColourUINT(Themes.eThemeColour.PreviewZoomEnvelope); float C1X = Math.Max(subGraphPosition.X + TopLeft.X, subGraphPosition.X); float C2X = Math.Min(subGraphPosition.X + BaseRight.X, subGraphPosition.X + EachGraphWidth - 1); C1Y = Math.Min(previewBaseY - 1, C1Y); C2Y = Math.Max(subGraphPosition.Y, C2Y); if (C1Y > subGraphPosition.Y && C1Y < previewBaseY && C2X > subGraphPosition.X) { imdp.AddLine(new Vector2(C1X, C1Y), new Vector2(C2X, C1Y), colour); } if (C2Y > subGraphPosition.Y && C2Y < previewBaseY) { imdp.AddLine(new Vector2(C2X, C2Y), new Vector2(C1X, C2Y), colour); } if (C2Y < previewBaseY && C1Y > subGraphPosition.Y) { C2Y = Math.Max(C2Y, subGraphPosition.Y); if (C2X > subGraphPosition.X && C2X < subGraphPosition.X + EachGraphWidth) { imdp.AddLine(new Vector2(C2X, C1Y), new Vector2(C2X, C2Y), colour); } if (C1X > subGraphPosition.X && C1X < subGraphPosition.X + EachGraphWidth) { imdp.AddLine(new Vector2(C1X, C2Y), new Vector2(C1X, C1Y), colour); } } }
/// <summary> /// Draws font to ImGui. /// </summary> /// <param name="drawListPtr">Target ImDrawList.</param> /// <param name="pos">Position.</param> /// <param name="col">Color.</param> public void Draw(ImDrawListPtr drawListPtr, Vector2 pos, uint col) { foreach (var element in this.Elements) { if (element.IsControl) { continue; } this.ImFontPtr.RenderChar( drawListPtr, this.Size, new Vector2( this.X + pos.X + element.X, pos.Y + element.Y), col, element.Glyph.Char); } }
public static unsafe void RenderArrowPointingAt(ImDrawListPtr draw_list, Vector2 pos, Vector2 half_sz, ImGuiDir direction, Vector4 col) { uint testcol = v4_to_uint(col); switch (direction) { case ImGuiDir.Left: draw_list.AddTriangleFilled(new Vector2(pos.X + half_sz.X, pos.Y - half_sz.Y), new Vector2(pos.X + half_sz.X, pos.Y + half_sz.Y), pos, v4_to_uint(col)); return; case ImGuiDir.Right: draw_list.AddTriangleFilled(new Vector2(pos.X - half_sz.X, pos.Y + half_sz.Y), new Vector2(pos.X - half_sz.X, pos.Y - half_sz.Y), pos, v4_to_uint(col)); return; case ImGuiDir.Up: draw_list.AddTriangleFilled(new Vector2(pos.X + half_sz.X, pos.Y + half_sz.Y), new Vector2(pos.X - half_sz.X, pos.Y + half_sz.Y), pos, v4_to_uint(col)); return; case ImGuiDir.Down: draw_list.AddTriangleFilled(new Vector2(pos.X - half_sz.X, pos.Y - half_sz.Y), new Vector2(pos.X + half_sz.X, pos.Y - half_sz.Y), pos, v4_to_uint(col)); return; case ImGuiDir.None: case ImGuiDir.COUNT: break; // Fix warnings } }
public static bool ButtonGradient(string strId) { String[] strIdArray = strId.Split("##"); Vector2 p = ImGuiNET.ImGui.GetCursorScreenPos(); Vector2 sizeText = ImGui.CalcTextSize(strIdArray[0]); ImDrawListPtr drawList = ImGuiNET.ImGui.GetWindowDrawList(); float buttonHeight = ImGuiNET.ImGui.GetFrameHeight(); float buttonWidth = sizeText.X + sizeText.X * 0.20f; Vector2 buttonSize = new Vector2(p.X + buttonWidth, p.Y + buttonHeight); uint colTop; uint colBottom; if (strIdArray.Length > 1) { if (ImGuiNET.ImGui.InvisibleButton(strIdArray[1], new Vector2(buttonWidth, buttonHeight))) { return(true); } } else { if (ImGuiNET.ImGui.InvisibleButton(strIdArray[0], new Vector2(buttonWidth, buttonHeight))) { return(true); } } if (ImGuiNET.ImGui.IsItemHovered()) { colTop = ImGuiNET.ImGui.GetColorU32(ImGuiCol.ButtonHovered, 1.50f); colBottom = ImGuiNET.ImGui.GetColorU32(ImGuiCol.Button, 0.50f); } else { colTop = ImGuiNET.ImGui.GetColorU32(ImGuiCol.ButtonHovered); colBottom = ImGuiNET.ImGui.GetColorU32(ImGuiCol.Button, 0.20f); } drawList.AddRectFilledMultiColor(p, buttonSize, colTop, colTop, colBottom, colBottom); drawList.AddRect(p, buttonSize, ImGuiNET.ImGui.GetColorU32(ImGuiCol.Separator)); drawList.AddText(new Vector2(p.X + (buttonWidth / 2) - (sizeText.X / 2), p.Y + (buttonHeight / 2) - (sizeText.Y / 2)), ImGui.GetColorU32(ImGuiCol.Text), strIdArray[0]); return(false); }
private void UpdateBuffers(ImDrawDataPtr data) { GL.BindVertexArray(vao); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer); int totalVBSize = (data.TotalVtxCount * Marshal.SizeOf <ImDrawVert>()); if (totalVBSize > sizeVertex) { sizeVertex = (int)(totalVBSize * 1.5f); GL.BufferData(BufferTarget.ArrayBuffer, sizeVertex, IntPtr.Zero, BufferUsageHint.DynamicDraw); } uint totalIBSize = (uint)(data.TotalIdxCount * sizeof(ushort)); if (totalIBSize > sizeIndex) { sizeIndex = (int)(totalIBSize * 1.5f); GL.BufferData(BufferTarget.ElementArrayBuffer, sizeIndex, IntPtr.Zero, BufferUsageHint.DynamicDraw); } int vertexOffsetInVertices = 0; int indexOffsetInElements = 0; for (int i = 0; i < data.CmdListsCount; i++) { ImDrawListPtr cmd_list = data.CmdListsRange[i]; GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(vertexOffsetInVertices * Marshal.SizeOf <ImDrawVert>()), cmd_list.VtxBuffer.Size * Marshal.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)(indexOffsetInElements * sizeof(ushort)), cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); vertexOffsetInVertices += cmd_list.VtxBuffer.Size; indexOffsetInElements += cmd_list.IdxBuffer.Size; } }
public static void RenderSpinner(Vector2 position, float radius, int thickness) { float time = (float)ImGui.GetTime(); uint color = ImGui.ColorConvertFloat4ToU32(new Vector4(0.5f, 0.5f, 0.5f, 1)); ImDrawListPtr drawList = ImGui.GetWindowDrawList(); int num_segments = 30; int start = (int)MathF.Abs(MathF.Sin(time * 1.8f) * (num_segments - 5)); float a_min = MathF.PI * 2.0f * (start) / num_segments; float a_max = MathF.PI * 2.0f * ((float)num_segments - 3) / num_segments; var centre = new Vector2(position.X + radius, position.Y + radius + ImGui.GetStyle().FramePadding.Y); drawList.PathClear(); for (int i = 0; i < num_segments; i++) { float a = a_min + (i / (float)num_segments) * (a_max - a_min); var location = new Vector2(centre.X + MathF.Cos(a + time * 8) * radius, centre.Y + MathF.Sin(a + time * 8) * radius); drawList.PathLineTo(location); } drawList.PathStroke(color, false, thickness); }
public static void DrawCube(ImDrawListPtr drawList, UIViewport viewport) { for (int i = 0; i < 4; i++) { float signY = ((i & 2) - 1); float signZ = (((i << 1) & 2) - 1); Draw3DLine(drawList, new Vector3(1, signY, signZ), new Vector3(-1, signY, signZ), viewport, 0xffffffff); } for (int i = 0; i < 4; i++) { float signX = ((i & 2) - 1); float signZ = (((i << 1) & 2) - 1); Draw3DLine(drawList, new Vector3(signX, 1, signZ), new Vector3(signX, -1, signZ), viewport, 0xffffffff); } for (int i = 0; i < 4; i++) { float signX = ((i & 2) - 1); float signY = (((i << 1) & 2) - 1); Draw3DLine(drawList, new Vector3(signX, signY, 1), new Vector3(signX, signY, -1), viewport, 0xffffffff); } }
private static bool SequencerButton( ImDrawListPtr draw_list, Vector2 pos, char ch, bool isSelected = false, uint color = ColorWhite) { var io = ImGui.GetIO(); var rect = new ImRect(pos, new Vector2(pos.X + 16, pos.Y + 16)); var isMouseOver = rect.Contains(io.MousePos); if (!isSelected) { color = isMouseOver ? 0xFFFFFFFFu : 0x50FFFFFFu; } draw_list.AddRect(rect.Min, rect.Max, color, 4); draw_list.AddText(new Vector2(pos.X + 4, pos.Y - 1), color, $"{ch}"); return(isMouseOver); }
private void RenderIMGui(Renderer renderer) { ImGui.Render(); ImDrawDataPtr drawData = ImGui.GetDrawData(); for (int i = 0; i < drawData.CmdListsCount; i++) { ImDrawListPtr cmdList = drawData.CmdListsRange[i]; IVertexBuffer vertexBuffer = CreateVertexBuffer(cmdList); int IndexOffset = 0; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmdPtr DrawCommand = cmdList.CmdBuffer[cmdi]; using (RenderingCommand cmd = renderer.RendererResourceFactory.CreateRenderCommand()) { cmd.WithVertexBuffer(vertexBuffer) .WithMaterial(Renderer.DefaultMaterialPtr.Get <Watertight.Rendering.Materials.Material>()) .WithCamera(UICamera); if (_ImGUITextureMap.ContainsKey(DrawCommand.TextureId)) { cmd.WithTexture(_ImGUITextureMap[DrawCommand.TextureId]); } cmd.WithStartIndex(IndexOffset) .WithPrimitveCount((int)DrawCommand.ElemCount / 3) .WithDebugName("IMGUI Renderer"); renderer.ExecuteRenderCommand(cmd); } IndexOffset += (int)DrawCommand.ElemCount; } } }
public static void ImageRotated(ImDrawListPtr d, IntPtr tex_id, Vector2 position, Vector2 size, float angle, uint col = UInt32.MaxValue) { float cos_a = (float)Math.Cos(angle); float sin_a = (float)Math.Sin(angle); Vector2[] pos = { position + ImRotate(new Vector2(-size.X * 0.5f, -size.Y * 0.5f), cos_a, sin_a), position + ImRotate(new Vector2(+size.X * 0.5f, -size.Y * 0.5f), cos_a, sin_a), position + ImRotate(new Vector2(+size.X * 0.5f, +size.Y * 0.5f), cos_a, sin_a), position + ImRotate(new Vector2(-size.X * 0.5f, +size.Y * 0.5f), cos_a, sin_a) }; Vector2[] uvs = { new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f) }; d.AddImageQuad(tex_id, pos[0], pos[1], pos[2], pos[3], uvs[0], uvs[1], uvs[2], uvs[3], col); }
private void CreateDrawCommands(CommandBuffer cmd, ImDrawDataPtr drawData, Vector2 fbSize) { System.IntPtr prevTextureId = System.IntPtr.Zero; Vector4 clipOffst = new Vector4(drawData.DisplayPos.X, drawData.DisplayPos.Y, drawData.DisplayPos.X, drawData.DisplayPos.Y); Vector4 clipScale = new Vector4(drawData.FramebufferScale.X, drawData.FramebufferScale.Y, drawData.FramebufferScale.X, drawData.FramebufferScale.Y); cmd.SetViewport(new Rect(0f, 0f, fbSize.x, fbSize.y)); cmd.SetViewProjectionMatrices( Matrix4x4.Translate(new Vector3(0.5f / fbSize.x, 0.5f / fbSize.y, 0f)), // small adjustment to improve text Matrix4x4.Ortho(0f, fbSize.x, fbSize.y, 0f, 0f, 1f)); int subOf = 0; for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n) { ImDrawListPtr drawList = drawData.CmdListsRange[n]; for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i, ++subOf) { ImDrawCmdPtr drawCmd = drawList.CmdBuffer[i]; // TODO: user callback in drawCmd.UserCallback & drawCmd.UserCallbackData // project scissor rectangle into framebuffer space and skip if fully outside Vector4 clip = Vector4.Scale(Helper.V4f(drawCmd.ClipRect) - clipOffst, clipScale); if (clip.x >= fbSize.x || clip.y >= fbSize.y || clip.z < 0f || clip.w < 0f) { continue; } if (prevTextureId != drawCmd.TextureId) { _properties.SetTexture(_texID, _texManager.GetTexture((int)(prevTextureId = drawCmd.TextureId))); } cmd.EnableScissorRect(new Rect(clip.x, fbSize.y - clip.w, clip.z - clip.x, clip.w - clip.y)); // invert y cmd.DrawMesh(_mesh, Matrix4x4.identity, _material, subOf, -1, _properties); } } cmd.DisableScissorRect(); }
private void RenderCommandLists(ImDrawDataPtr drawData) { this.GraphicsDevice.SetVertexBuffer(this.vertexBuffer); this.GraphicsDevice.Indices = this.indexBuffer; int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) { ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi]; if (!this.LoadedTextures.ContainsKey(drawCmd.TextureId)) { throw new InvalidOperationException($"Could not find a texture with id '{drawCmd.TextureId}', please check your bindings"); } this.GraphicsDevice.ScissorRectangle = new Rectangle( (int)drawCmd.ClipRect.X, (int)drawCmd.ClipRect.Y, (int)(drawCmd.ClipRect.Z - drawCmd.ClipRect.X), (int)(drawCmd.ClipRect.W - drawCmd.ClipRect.Y) ); this.UpdateEffect(drawCmd.TextureId); this.Effect.Apply(); this.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, vtxOffset, idxOffset, (int)drawCmd.ElemCount / 3); idxOffset += (int)drawCmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } }
/* * public static void Begin(string id, ref int selected, string[] list) * { * Begin(id, list, ref selected, ImGui.GetColorU32(ImGuiCol.Border)); * } * * public static void Begin(string id, string[] list, ref int selected, ImGuiCol colorIdx) * { * Begin(id, list, ref selected, ImGui.GetColorU32(colorIdx)); * } */ public static void End(Vector2 sizeRight) { ImGui.Unindent(_dentMulitpier * _nestIndex); _nestIndex--; var state = _states[_nestIndex]; var winpos = ImGui.GetCursorPos(); var rgnSize = ImGui.GetContentRegionAvail(); ImGui.NextColumn(); ImGui.Columns(1); var scpos = ImGui.GetCursorScreenPos(); ImGui.Unindent(_dentMulitpier); state._xright = state._xcentr + sizeRight.X; float boty = Math.Max(state._ybot, state._ytop + sizeRight.Y); //is the list bigger, or the items drawn after it. ImDrawListPtr wdl = ImGui.GetWindowDrawList(); Vector2[] pts = new Vector2[9]; pts[0] = new Vector2(state._xleft, state._yctr1); //topleft of the selected item pts[1] = new Vector2(state._xleft, state._yctr2); //botomleft of the selected item pts[2] = new Vector2(state._xcentr, state._yctr2); //bottom rigth of selected item pts[3] = new Vector2(state._xcentr, boty); //bottom left of rh colomn pts[4] = new Vector2(state._xright, boty); //bottom Right pts[5] = new Vector2(state._xright, state._ytop); //top righht pts[6] = new Vector2(state._xcentr, state._ytop); //top mid pts[7] = new Vector2(state._xcentr, state._yctr1); //selected top right pts[8] = pts[0]; //selected top left wdl.AddPolyline(ref pts[0], pts.Length, state._colour, false, 1.0f); ImGui.PopID(); }
public static void End(float width) { ImGui.Unindent(_dentMulitpier * _nestIndex); _nestIndex--; var pos = ImGui.GetCursorScreenPos(); _size[_nestIndex] = new Vector2(width, pos.Y - _startPos[_nestIndex].Y); ImDrawListPtr wdl = ImGui.GetWindowDrawList(); float by = _startPos[_nestIndex].Y + _size[_nestIndex].Y + _dentMulitpier - _dentMulitpier * _nestIndex; float rx = _startPos[_nestIndex].X + _size[_nestIndex].X - _dentMulitpier * _nestIndex; Vector2[] pts = new Vector2[6]; pts[0] = new Vector2(_startPos[_nestIndex].X + _dentMulitpier, _startPos[_nestIndex].Y); pts[1] = _startPos[_nestIndex]; //top left pts[2] = new Vector2(_startPos[_nestIndex].X, by); //bottom left pts[3] = new Vector2(rx, by); //bottom right pts[4] = new Vector2(rx, _startPos[_nestIndex].Y); //top right pts[5] = new Vector2(_startPos[_nestIndex].X + _labelSize[_nestIndex].X + _dentMulitpier, _startPos[_nestIndex].Y); wdl.AddPolyline(ref pts[0], pts.Length, _colour[_nestIndex], false, 1.0f); ImGui.PopID(); }
private void RenderImDrawData(ImDrawDataPtr drawData, GraphicsDevice gd, CommandList cl) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (drawData.CmdListsCount == 0) { return; } uint totalVbSize = (uint)(drawData.TotalVtxCount * Unsafe.SizeOf <ImDrawVert>()); if (totalVbSize > _vertexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_vertexBuffer); _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVbSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); } uint totalIbSize = (uint)(drawData.TotalIdxCount * sizeof(ushort)); if (totalIbSize > _indexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_indexBuffer); _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIbSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); } for (int i = 0; i < drawData.CmdListsCount; i++) { ImDrawListPtr cmdList = drawData.CmdListsRange[i]; cl.UpdateBuffer( _vertexBuffer, vertexOffsetInVertices * (uint)Unsafe.SizeOf <ImDrawVert>(), cmdList.VtxBuffer.Data, (uint)(cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>())); cl.UpdateBuffer( _indexBuffer, indexOffsetInElements * sizeof(ushort), cmdList.IdxBuffer.Data, (uint)(cmdList.IdxBuffer.Size * sizeof(ushort))); vertexOffsetInVertices += (uint)cmdList.VtxBuffer.Size; indexOffsetInElements += (uint)cmdList.IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp); cl.SetVertexBuffer(0, _vertexBuffer); cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16); cl.SetPipeline(_pipeline); cl.SetGraphicsResourceSet(0, _mainResourceSet); drawData.ScaleClipRects(io.DisplayFramebufferScale); // Render command lists int vtxOffset = 0; int idxOffset = 0; for (int n = 0; n < drawData.CmdListsCount; n++) { ImDrawListPtr cmdList = drawData.CmdListsRange[n]; for (int cmdI = 0; cmdI < cmdList.CmdBuffer.Size; cmdI++) { ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdI]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { if (pcmd.TextureId != IntPtr.Zero) { if (pcmd.TextureId == _fontAtlasID) { cl.SetGraphicsResourceSet(1, _fontTextureResourceSet); } else { cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId)); } } cl.SetScissorRect( 0, (uint)pcmd.ClipRect.X, (uint)pcmd.ClipRect.Y, (uint)(pcmd.ClipRect.Z - pcmd.ClipRect.X), (uint)(pcmd.ClipRect.W - pcmd.ClipRect.Y)); cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idxOffset, vtxOffset, 0); } idxOffset += (int)pcmd.ElemCount; } vtxOffset += cmdList.VtxBuffer.Size; } }
private void RenderImDrawData(ImDrawDataPtr draw_data) { if (draw_data.CmdListsCount == 0) { return; } for (int i = 0; i < draw_data.CmdListsCount; i++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(); if (vertexSize > _vertexBufferSize) { int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize); GL.NamedBufferData(_vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _vertexBufferSize = newSize; Console.WriteLine($"Resized dear imgui vertex buffer to new size {_vertexBufferSize}"); } int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort); if (indexSize > _indexBufferSize) { int newSize = (int)Math.Max(_indexBufferSize * 1.5f, indexSize); GL.NamedBufferData(_indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); _indexBufferSize = newSize; Console.WriteLine($"Resized dear imgui index buffer to new size {_indexBufferSize}"); } } // Setup orthographic projection matrix into our constant buffer ImGuiIOPtr io = ImGui.GetIO(); Matrix4 mvp = Matrix4.CreateOrthographicOffCenter( 0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); _shaderLoader.UseShader(); GL.UniformMatrix4(_shaderLoader.GetUniformLocation("projection_matrix"), false, ref mvp); GL.Uniform1(_shaderLoader.GetUniformLocation("in_fontTexture"), 0); Util.CheckGLError("Projection"); GL.BindVertexArray(_vertexArray); Util.CheckGLError("VAO"); draw_data.ScaleClipRects(io.DisplayFramebufferScale); GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); // Render command lists for (int n = 0; n < draw_data.CmdListsCount; n++) { ImDrawListPtr cmd_list = draw_data.CmdListsRange[n]; GL.NamedBufferSubData(_vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data); Util.CheckGLError($"Data Vert {n}"); GL.NamedBufferSubData(_indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data); Util.CheckGLError($"Data Idx {n}"); int vtx_offset = 0; int idx_offset = 0; for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i]; if (pcmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId); Util.CheckGLError("Texture"); // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates var clip = pcmd.ClipRect; GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y)); Util.CheckGLError("Scissor"); if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0) { GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset); } else { GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort)); } Util.CheckGLError("Draw"); } idx_offset += (int)pcmd.ElemCount; } vtx_offset += cmd_list.VtxBuffer.Size; } GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ScissorTest); }
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; }