Простой OpenGL GUI Framework Советы по взаимодействию с пользователем?

Я проектирую простую структуру графического интерфейса с нуля как проект, используя OpenGL и ничего более внешнего, и мне нужен совет о том, как я могу реализовать взаимодействие с пользователем.

В основном, у меня есть базовый класс GUIItem от которого наследуются все элементы. Это дает каждому элементу некоторые основные переменные, такие как положение, вектор для дочерних элементов, а также некоторые базовые функции для перемещения мыши и щелчка.

Все элементы настроены, как указано выше, с соответствующими переменными-членами.

То, с чем я борюсь, это как правильно реализовать взаимодействие с пользователем. В моем оконном менеджере я бы создал новый экземпляр элемента, скажем, GUIButton и назовите это button1, При возникновении щелчка оконный менеджер будет перебирать свой список элементов и любые дочерние элементы, которые они могут иметь, вычисляя прямоугольную область вокруг объекта на основе его координат, высоты и ширины, а затем запускать любую функцию «по нажатию», связанную с указанный пункт, как изменить значение textlabel1,

Во-первых, есть ли лучший способ сделать этот расчет? Это будет работать для прямоугольных элементов, но сферические объекты и другие будут иметь гораздо большую ошибочную область, по которой можно щелкнуть. В идеале я бы проверял пиксели, но я не представляю, как это будет достигнуто. Я слышал об этом, но никогда не использовал GLUT (мой проект позволяет использовать его только для обработки взаимодействия мыши и клавиатуры). Предоставляет ли GLUT что-нибудь для помощи в этом случае?

Моя главная проблема связана с обработкой того, что может произойти, когда действительно происходит событие «при нажатии». В данный момент GUIButton например, имеет встроенную функцию «при нажатии», поэтому, насколько я вижу, мне нужно сделать что-то вроде виртуальной функции, то есть каждая новая кнопка, которую я создал, должна иметь свой собственный класс перезаписать функцию «по нажатию», и каждый экземпляр кнопки будет экземпляром уникального класса, который просто наследуется от GUIButton, Это кажется мне грязным, так как я понятия не имею, где я буду хранить все эти классы, и, похоже, много лишнего кода. Буду ли я создавать файл button1.cpp и button1.h?

Любой совет по этому поводу будет приветствоваться, так как я новичок в C ++, OpenGL, и я впервые знакомлюсь с программированием GUI, и не так много, чтобы продолжить, когда существующая среда GUI является обычным выбором.

2

Решение

если ты хочешь что-то тупо просто и быстро тогда вы могли бы:

  1. создать буфер теневого экрана, содержащий ID/index/pointer вместо цвета
  2. предварительно визуализировать этот буфер

    Просто визуализируйте каждый из ваших визуальных компонентов, но вместо этого раскрасьте / текстурируйте, просто заполните ID/index/pointer визуализированного компонента. Не забудьте очистить это с некоторыми NULL сначала … После этого у вас должна быть маска ваших компонентов. Вам нужно сделать это только один раз …

  3. На событиях мыши

    вы просто конвертируете координаты мыши в пространство экрана тени и выбираете значение. Если это NULL Затем вы нажали или что-нибудь в пустой области. Если он содержит ID вместо этого обновите или вызовите обратные вызовы для компонента ID, если у вас есть список всех компонентов, то ID может быть индексом списка, в противном случае используйте его фактический указатель или кодируйте в стиле (component_type, component_index), Как видите, это довольно быстро O(1) выбор элемента независимо от того, сколько у вас компонентов … Разрешение теневого экрана может отличаться от фактического экрана (для сохранения памяти).

Это обеспечивает идеальную точность выбора мыши с точностью до пикселя независимо от формы ваших компонентов без необходимости во вложенных циклах поиска компонентов.

[Заметки]

Как я это сделал, вот несколько советов:

создать window учебный класс содержащий конфигурацию ваших компонентов для одного экрана. Программы обычно имеют больше экранов с различным набором компонентов и выполняют динамические экраны снова и снова только потому, что вы переключаете страницы / экраны экрана.

использовать отдельный список компонентов по одному списку для каждого типа компонента.

Создайте IDE редактор для ваших окон см тащить, тянуть & падение примера в C ++ это может пригодиться для этого. добавлять get,set функции контролируются string/enum or flag легко получить / изменить свойства, чтобы сделать возможным инспектор объектов. Также вот как выглядит моя IDE:

Vcl Ide

Окно сохраняется из IDE напрямую как код C ++, который я могу просто скопировать в свое приложение. Это приведенный выше пример без ручки (забыл ее сохранить):

//---------------------------------------------------------------------------
// OpenGL VCL window beg: win
win.grid.allocate(0);
win.grid.num=0;
win.scale.allocate(0);
win.scale.num=0;
win.button.allocate(0);
win.button.num=0;
win.knob.allocate(0);
win.knob.num=0;
win.scrollbar.allocate(3);
win.scrollbar.num=3;
win.scrollbar[0].x0=200.0;
win.scrollbar[0].y0=19.0;
win.scrollbar[0].xs=256.0;
win.scrollbar[0].ys=16.0;
win.scrollbar[0].fxs=8.0;
win.scrollbar[0].fys=19.0;
win.scrollbar[0].name="_vcl_scrollbar0";
win.scrollbar[0].hint="";
win.scrollbar[0].min=0.000;
win.scrollbar[0].max=1.000;
win.scrollbar[0].pos=0.000;
win.scrollbar[0].dpos=0.100;
win.scrollbar[0].horizontal=1;
win.scrollbar[0].style=0;
win.scrollbar[0].resize();
win.scrollbar[1].x0=200.0;
win.scrollbar[1].y0=45.0;
win.scrollbar[1].xs=256.0;
win.scrollbar[1].ys=16.0;
win.scrollbar[1].fxs=8.0;
win.scrollbar[1].fys=19.0;
win.scrollbar[1].name="_vcl_scrollbar1";
win.scrollbar[1].hint="";
win.scrollbar[1].min=0.000;
win.scrollbar[1].max=1.000;
win.scrollbar[1].pos=0.000;
win.scrollbar[1].dpos=0.100;
win.scrollbar[1].horizontal=1;
win.scrollbar[1].style=0;
win.scrollbar[1].resize();
win.scrollbar[2].x0=200.0;
win.scrollbar[2].y0=70.0;
win.scrollbar[2].xs=256.0;
win.scrollbar[2].ys=16.0;
win.scrollbar[2].fxs=8.0;
win.scrollbar[2].fys=19.0;
win.scrollbar[2].name="_vcl_scrollbar2";
win.scrollbar[2].hint="";
win.scrollbar[2].min=0.000;
win.scrollbar[2].max=1.000;
win.scrollbar[2].pos=0.000;
win.scrollbar[2].dpos=0.100;
win.scrollbar[2].horizontal=1;
win.scrollbar[2].style=0;
win.scrollbar[2].resize();
win.interpbox.allocate(0);
win.interpbox.num=0;
win.dblist.allocate(0);
win.dblist.num=0;
// OpenGL VCL window end: win
//---------------------------------------------------------------------------

Посмотрите на изображения здесь отображение данных в реальном времени на осциллографе для некоторых идей (у меня это работает как для GDI, так и для OpenGL)

Лучше использовать пиксельные единицы вместо OpenGL <-1,+1> единицы экрана для лучшего визуального качества и комфорта редактирования.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]