简单的 OpenGL GUI 框架用户交互建议?
Simple OpenGL GUI Framework User Interaction Advice?
我正在作为一个项目从头开始设计一个简单的 GUI 框架,使用 OpenGL 而不使用任何其他外部工具,需要一些关于如何实现用户交互的建议。
基本上,我有一个基础 class GUIItem
,所有元素都从中继承。这为每个项目提供了一些基本变量,例如位置、包含子元素的向量以及鼠标移动和单击的一些基本功能。
所有元素的设置都如上,并带有相关的成员变量。
我苦恼的是如何正确地实现用户交互。在我的 window 管理器中,我会创建一个项目的新实例,比如 GUIButton
并将其命名为 button1
。 window 管理器将在单击发生时遍历其元素列表及其可能具有的任何子元素,根据对象的坐标、高度和宽度计算对象周围的矩形区域,然后 运行与所述项目关联的任何 "on click" 功能,例如更改 textlabel1
.
的值
首先,有没有更好的方法来做这个计算?它适用于矩形元素,但球形物体和其他物体会有更大的错误区域,可以点击。理想情况下,我会检查像素,但我不知道如何实现。我听说过但从未使用过 GLUT(虽然我的项目只允许使用它来处理 mouse/keyboard 交互)。在这种情况下,GLUT 是否提供任何帮助?
我的主要问题是处理 "On click" 事件实际发生时会发生什么。例如,目前 GUIButton
有一个内置的 "On click" 函数,据我所知,我必须做一些事情,比如使它成为一个虚函数,这意味着我的每个新按钮created 必须有自己的 class 来覆盖 "on click" 函数,并且按钮的每个实例都是唯一的 class 的实例,它简单地继承自 GUIButton
.这对我来说似乎很混乱,因为我不知道将所有这些 classes 存储在哪里,而且它似乎有很多额外的代码。我会创建 button1.cpp 和 button1.h 文件吗?
真的欢迎任何关于此的建议,因为我是 C++、OpenGL 的新手,这是我第一次接触 GUI 编程,当现有的 GUI 框架是通常的选择。
如果你想要一些东西非常简单和快速那么你可以:
创建包含 ID/index/pointer
而不是颜色的阴影屏幕缓冲区
预渲染此缓冲区
只需将每个视觉组件渲染到它,而不是 coloring/texturing 只需填写渲染组件的 ID/index/pointer
。不要忘记先用一些 NULL
清除它......之后你应该有你的组件的掩码。你只需要这样做一次...
鼠标事件
您只需将鼠标坐标转换为阴影屏幕 space 并选择值。如果它是 NULL
那么你点击了空白区域或其他任何内容。如果它包含 ID
,则更新或调用组件 ID
的回调。如果你有一个所有组件的列表,那么 ID 可以是列表索引,否则使用它的实际指针或以 (component_type, component_index)
风格编码。正如您所看到的,无论您有多少组件,这都非常快 O(1)
项目选择...阴影屏幕可以具有与实际屏幕不同的分辨率(以保留内存)。
无论组件的形状如何,这都具有像素完美的鼠标选择精度,无需嵌套组件搜索循环。
[备注]
我在做这些事情的时候有一些提示:
创建一个 window
class,其中包含您的单屏组件配置。程序通常有更多的屏幕和不同的组件集,并且一遍又一遍地动态显示屏幕只是因为你切换 page/screen 很烂。
使用单独的组件列表,每种组件类型一个列表。
为您的 windows 创建 IDE 编辑器请参阅 drag & drop example in C++ 它可能会派上用场。将 string/enum or flag
控制的 get,set
函数添加到简单的 obtain/change 属性,使对象检查器成为可能。这也是我的 IDE 的样子:
window 直接从 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
//---------------------------------------------------------------------------
查看此处的图像 plotting real time Data on Oscillocope 以获取一些想法(我已将其用于 GDI 和 OpenGL)
最好使用像素单位而不是 OpenGL <-1,+1>
屏幕单位以获得更好的视觉质量和编辑舒适度。
我正在作为一个项目从头开始设计一个简单的 GUI 框架,使用 OpenGL 而不使用任何其他外部工具,需要一些关于如何实现用户交互的建议。
基本上,我有一个基础 class GUIItem
,所有元素都从中继承。这为每个项目提供了一些基本变量,例如位置、包含子元素的向量以及鼠标移动和单击的一些基本功能。
所有元素的设置都如上,并带有相关的成员变量。
我苦恼的是如何正确地实现用户交互。在我的 window 管理器中,我会创建一个项目的新实例,比如 GUIButton
并将其命名为 button1
。 window 管理器将在单击发生时遍历其元素列表及其可能具有的任何子元素,根据对象的坐标、高度和宽度计算对象周围的矩形区域,然后 运行与所述项目关联的任何 "on click" 功能,例如更改 textlabel1
.
首先,有没有更好的方法来做这个计算?它适用于矩形元素,但球形物体和其他物体会有更大的错误区域,可以点击。理想情况下,我会检查像素,但我不知道如何实现。我听说过但从未使用过 GLUT(虽然我的项目只允许使用它来处理 mouse/keyboard 交互)。在这种情况下,GLUT 是否提供任何帮助?
我的主要问题是处理 "On click" 事件实际发生时会发生什么。例如,目前 GUIButton
有一个内置的 "On click" 函数,据我所知,我必须做一些事情,比如使它成为一个虚函数,这意味着我的每个新按钮created 必须有自己的 class 来覆盖 "on click" 函数,并且按钮的每个实例都是唯一的 class 的实例,它简单地继承自 GUIButton
.这对我来说似乎很混乱,因为我不知道将所有这些 classes 存储在哪里,而且它似乎有很多额外的代码。我会创建 button1.cpp 和 button1.h 文件吗?
真的欢迎任何关于此的建议,因为我是 C++、OpenGL 的新手,这是我第一次接触 GUI 编程,当现有的 GUI 框架是通常的选择。
如果你想要一些东西非常简单和快速那么你可以:
创建包含
ID/index/pointer
而不是颜色的阴影屏幕缓冲区预渲染此缓冲区
只需将每个视觉组件渲染到它,而不是 coloring/texturing 只需填写渲染组件的
ID/index/pointer
。不要忘记先用一些NULL
清除它......之后你应该有你的组件的掩码。你只需要这样做一次...鼠标事件
您只需将鼠标坐标转换为阴影屏幕 space 并选择值。如果它是
NULL
那么你点击了空白区域或其他任何内容。如果它包含ID
,则更新或调用组件ID
的回调。如果你有一个所有组件的列表,那么 ID 可以是列表索引,否则使用它的实际指针或以(component_type, component_index)
风格编码。正如您所看到的,无论您有多少组件,这都非常快O(1)
项目选择...阴影屏幕可以具有与实际屏幕不同的分辨率(以保留内存)。
无论组件的形状如何,这都具有像素完美的鼠标选择精度,无需嵌套组件搜索循环。
[备注]
我在做这些事情的时候有一些提示:
创建一个 window
class,其中包含您的单屏组件配置。程序通常有更多的屏幕和不同的组件集,并且一遍又一遍地动态显示屏幕只是因为你切换 page/screen 很烂。
使用单独的组件列表,每种组件类型一个列表。
为您的 windows 创建 IDE 编辑器请参阅 drag & drop example in C++ 它可能会派上用场。将 string/enum or flag
控制的 get,set
函数添加到简单的 obtain/change 属性,使对象检查器成为可能。这也是我的 IDE 的样子:
window 直接从 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
//---------------------------------------------------------------------------
查看此处的图像 plotting real time Data on Oscillocope 以获取一些想法(我已将其用于 GDI 和 OpenGL)
最好使用像素单位而不是 OpenGL <-1,+1>
屏幕单位以获得更好的视觉质量和编辑舒适度。