WidgetCanvas и координаты точек


photo

Recommended Posts

Задумал на экране отобразить длинную прямоугольную шкалу показывающую, например, здоровье. Я так понял что для этого можно использовать WidgetCanvas, ибо он позволяет отображать самые произвольные фигуры из точек и даже текстурные полигоны. Для начала я добавил сам WidgetCanvas и задал ему размер (в пикселях), и определенный цвет:

auto pGui = Gui::get();
static auto pCanvas = WidgetCanvas::create(pGui);
pCanvas->setPosition(10,10);
pCanvas->setWidth(200);
pCanvas->setHeight(200);
pCanvas->setColor({1.0f,1.0f,1.0f,0.5f});

pGui->addChild(pCanvas, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED);

В итоге я получил нечто вот такое:
2021-01-10_19-50-53.png.fd9d73ba1416b863ee6eae71e228c786.png

То есть, я так понимаю, WidgetCanvas заданного размера был успешно добавлен на GUI. Далее я попытался отобразить на этом canvas хотя-бы один треугольник, и заметил что там используются 3D координаты точек (то есть подразумевается что у canvas по умолчанию стоит какая-то матрица проекции или что-то вроде того). Предположив что ось Z (либо -Z) уходит вдаль, ось X идет вправо, а Y вверх, я решил добавить треугольник со следующими точками: нижняя левая, верхняя левая, верхняя правая:

auto pid = pCanvas->addPolygon();
pCanvas->setPolygonColor(pid, {0.8f,0.4f,0.0f,1.0f});
pCanvas->addPolygonPoint(pid,{-1.0f,-1.0f,0.0f});
pCanvas->addPolygonPoint(pid,{-1.0f,1.0f,0.0f});
pCanvas->addPolygonPoint(pid,{1.0f,1.0f,0.0f});

В итоге у меня ничего не отобразилось. Как был белый полупрозрачный квадрат, так и остался. Я подумал что вероятно не хватает той самой матрицы проекции. Я решил добавить просто перспективную проекцию:

pCanvas->setTransform(Math::perspective(45.0f,1.0f,0.0f,100.0f));

И в итоге я получил вот это:
2021-01-10_20-06-06.png.46ac457e22382692f2f0704a8dae3a53.png

Треугольник как-то отобразился, но почему-то в качестве вью-порта использовался не квадратик canvas'а, а основной вью-порт, и треугольник вылез за пределы canvas'а.
В чем вообще дело? В каких координатах необходимо задавать точки? Какая там проекция по умолчанию? Я попробовал использовать ортогональную проекцию:

pCanvas->setTransform(Math::ortho(-1.0f,1.0f,-1.0f,1.0f,0.0f,100.0f));

Но тогда треугольник вовсе исчезает. Можете подсказать в каких координатах нужно работать? Как, например, просто отобразить прямоугольник, который бы покрывал полностью весь canvas?

Заранее спасибо.

Link to post

Здравствуйте, DarkWolf.

Координаты точек задаются в пикселях от левого верхнего угла canvas’a. Например, можно использовать следующий код, чтобы отобразить прямоугольник, покрывающий весь canvas.

pCanvas->setPosition(10,10);
pCanvas->setWidth(200);
pCanvas->setHeight(200);
pCanvas->setColor({ 1.0f,1.0f,1.0f,0.5f });

auto pid = pCanvas->addPolygon();
pCanvas->setPolygonColor(pid, { 0.8f, 0.4f,0.0f,1.0f });
pCanvas->addPolygonPoint(pid, { 0.0f, 0.0f, 0.0f });
pCanvas->addPolygonPoint(pid, { 200.0f, 0.0f, 0.0f });
pCanvas->addPolygonPoint(pid, { 200.0f, 200.0f, 0.0f });
pCanvas->addPolygonPoint(pid, { 0.0f, 200.0f, 0.0f });

image.png

  • Like 2
Link to post

Благодарю. Только не совсем понятно как тогда работают эти проекции (setTransform), если координаты в пикселях..

Link to post

Элементы canvas'а позиционируются в трехмерном пространстве. Позиция каждой вершины полиогна умножается на индивидуальную матрицу get/setPolygonTransform, затем на общую для всех элементов canvas'а матрицу get/setTransform, а затем на матрицу родителя canvas'а.
Используя матрицы get/setPolygonTransform и get/setTransform можно крутить, перемещать, изменять размер как отдельных, так и всех элементов canvas'а.

Почему для задания координат вершин использутся пиксели? Потому что в конце преобразований применятся ортогональная проекция с размерами (ширина экрана в пикселях, высота экрана в пикселях), которая трансформирует координаты в пространство от (-1.0, -1.0, 0.0) до (1.0, 1.0, 0.0) для отрисовки.

Также можно посмотреть семлы в SDK Browser/Samples/UnigineScript/Widgets/canvas_00-03.

Link to post