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 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(); }