Это работает путем захвата всех команд и вершин, добавленных ImGUI между ними. вызывает Canvas.Begin() и Canvas.End() и преобразует их из локального пространства холста в пространство экрана. По сути, это означает, что внутри блока между Canvas.Begin() и Canvas.End() все позиции экрана фактически являются позициями внутри холста.
проблема в том, что по какой-то причине, если я устанавливаю элементы для рендеринга в (0, 0), они отказываются рендериться, если координата y родительского окна не является отрицательной, а также происходит какое-то странное поведение маскировки.
Я демонстрирую это в этом видео: https://files.catbox.moe/uxex96.mp4
Пожалуйста, найдите мой код ниже:
Код: Выделить всё
private Vector2 _widgetPos;
private Vector2 _widgetSize;
private ImDrawListPtr _drawList;
private Vector2 _offset;
private float _scale = 1f;
private int _vtxBufferStart;
private int _cmdBufferStart;
private const float GridStep = 64f;
public void Begin()
{
_widgetPos = ImGui.GetCursorScreenPos();
_widgetSize = ImGui.GetContentRegionAvail();
_drawList = ImGui.GetWindowDrawList();
// Draw Grid (Grid jumps a bit when scaling - TODO: fix this)
var localMin = WidgetToLocal(Vector2.Zero);
var localMax = WidgetToLocal(_widgetSize);
var gridColour = ImGui.ColorConvertFloat4ToU32(new Vector4(220, 220, 220, 50) / 255);
for (float x = localMin.X % GridStep; x < localMax.X - localMin.X; x += GridStep)
_drawList.AddLine(LocalToScreen(new Vector2(localMax.X - x, localMin.Y)),
LocalToScreen(new Vector2(localMax.X - x, localMax.Y)), gridColour);
for (float y = localMin.Y % GridStep; y < localMax.Y - localMin.Y; y += GridStep)
_drawList.AddLine(LocalToScreen(new Vector2(localMin.X, localMax.Y - y)),
LocalToScreen(new Vector2(localMax.X, localMax.Y - y)), gridColour);
// Clip to control
_drawList.PushClipRect(ScreenToLocal(_widgetPos), ScreenToLocal(_widgetPos + _widgetSize), false);
// Any UI drawn past this point will be in canvas space
_vtxBufferStart = _drawList.VtxBuffer.Size;
_cmdBufferStart = _drawList.CmdBuffer.Size;
// Start Drawing from (0, 0) in the canvas
ImGui.SetCursorScreenPos(Vector2.Zero);
}
public Vector2 ScreenToLocal(Vector2 screen) => WidgetToLocal(screen - _widgetPos);
public Vector2 LocalToScreen(Vector2 local) => LocalToWidget(local) + _widgetPos;
public Vector2 LocalToWidget(Vector2 local) => (local + _offset) * _scale;
public Vector2 WidgetToLocal(Vector2 widget) => widget / _scale - _offset;
public void End()
{
// Any UI drawn past this point is in screen space
var vtxBufferEnd = _drawList.VtxBuffer.Size;
var cmdBufferEnd = _drawList.CmdBuffer.Size;
for (int idx = _vtxBufferStart; idx < vtxBufferEnd; idx++) // Update vertices
{
var vtx = _drawList.VtxBuffer[idx];
vtx.pos = LocalToScreen(vtx.pos);
}
for (int idx = _cmdBufferStart; idx < cmdBufferEnd; idx++) // Update clipping
{
var cmd = _drawList.CmdBuffer[idx];
var (min, max) = Util.SplitVector4(cmd.ClipRect);
cmd.ClipRect = Util.MergeVector2s(LocalToScreen(min), LocalToScreen(max));
}
_drawList.PopClipRect(); // We are done with clipping now
// Zooming
var io = ImGui.GetIO();
_scale += io.MouseWheel * _scale * 0.1f;
// Draw Invisible Button to capture click and focus events
ImGui.SetCursorScreenPos(_widgetPos);
ImGui.InvisibleButton("Canvas", _widgetSize);
bool isHovered = ImGui.IsItemHovered();
bool isClicked = ImGui.IsItemActive();
if (isClicked)
{
_offset += WidgetToLocal(io.MousePos) - WidgetToLocal(io.MousePosPrev);
}
}
Код: Выделить всё
ImGui.Begin("StoryGraph", ref _open);
_canvas.Begin();
ImGui.Button("Example Button!");
_canvas.End();
ImGui.End();
- Удалить весь обтравочный код
< /li>
Сделать обтравочную маску размером всего экрана - Сделать обтравочную маску из (- от 9999, -9999) до (9999, 9999)
- Всегда сохранять обтравочную маску в координатах экранного пространства
Код: Выделить всё
ImGui.SetCursorScreenPos(_widgetPos)Я также был бы рад принять альтернативное решение для холста в ImGUI, при условии, что я могу масштабировать и перемещать бесконечный холст, на котором я могу рисовать обычные элементы ImGUI (с возможностью событий мыши). ).
Подробнее здесь: https://stackoverflow.com/questions/791 ... n-in-imgui
Мобильная версия