【问题标题】:Simple OpenGL GUI Framework User Interaction Advice? [closed]简单的 OpenGL GUI 框架用户交互建议? [关闭]
【发布时间】:2015-12-13 03:41:05
【问题描述】:

我正在从头开始设计一个简单的 GUI 框架作为一个项目,使用 OpenGL 而没有其他任何外部设备,并且需要一些关于如何实现用户交互的建议。

基本上,我有一个基类GUIItem,所有元素都从该基类继承。这为每个项目提供了一些基本变量,例如位置、包含子元素的向量以及一些用于鼠标移动和单击的基本函数。

所有元素都如上设置,以及它们的相关成员变量。

我正在努力解决的是如何正确实现用户交互。在我的窗口管理器中,我会创建一个项目的新实例,比如GUIButton 并将其命名为button1。窗口管理器将在单击发生时遍历其元素列表以及它们可能具有的任何子元素,根据其坐标、高度和宽度计算对象周围的矩形区域,然后运行与说项目,比如改变textlabel1的值。

首先,有没有更好的方法来做这个计算?它适用于矩形元素,但球形物体和其他物体会有更大的错误区域,可以点击。理想情况下,我会检查像素,但我不知道如何实现。我听说过但从未使用过 GLUT(我的项目只允许使用它来处理鼠标/键盘交互)。在这种情况下,GLUT 是否提供任何帮助?

我的主要问题是处理实际发生“点击”事件时会发生的情况。例如,目前GUIButton 内置了一个“点击时”功能,据我所知,我必须做一些事情,比如让它成为一个虚拟功能,这意味着我创建的每个新按钮都会有拥有自己的类只是为了覆盖“点击时”功能,并且按钮的每个实例都是一个唯一类的实例,它只是继承自GUIButton。这对我来说似乎很乱,因为我不知道将所有这些类存储在哪里,而且似乎有很多额外的代码。我会创建一个 button1.cpp 和 button1.h 文件吗?

如果我是 C++、OpenGL 的新手,我真的很欢迎任何关于这方面的建议,而且这是我第一次接触 GUI 编程,当现有的 GUI 框架是通常的选择时,没有太多可做的事情.

【问题讨论】:

  • 您的GUIItem 有一些问题。并非所有 GUI 元素都应该能够有子等。
  • 关于你的球形对象:在父级中,只需使用矩形检查,球形物体可以根据其形状自行检查更多。 ...不要遍历所有像素。对象中必须有一些规律性,还是没有?根据形状,它需要一些数学来检查它是否被点击,但仍然不要迭代像素。
  • 关于按钮应该做什么:你知道函数指针和仿函数吗?没有理由为每个按钮创建一个新类。
  • 最后,“如果”您使用 OpenGL 是因为您不知道其他内容,请立即停止。用于“无聊”普通窗口的 OpenGL 是过度杀伤和资源浪费。
  • @deviantfan 感谢您的建议。至于函数指针,不是我以前用过的东西,但我会看看。不幸的是,OpenGL 是我的项目规范的要求,但我同意。

标签: c++ user-interface opengl user-controls glut


【解决方案1】:

如果您想要简单而快速的东西,那么您可以:

  1. 创建包含 ID/index/pointer 而不是颜色的阴影屏幕缓冲区

  2. 预渲染此缓冲区

    只需将每个可视组件渲染给它,而不是着色/纹理只需填写渲染组件的ID/index/pointer。不要忘记先用NULL 清除它……在此之后,您应该拥有组件的掩码。您只需执行一次...

  3. 鼠标事件

    您只需将鼠标坐标转换为阴影屏幕空间并选择值。如果它是NULL,那么您单击了空白区域或任何其他内容。如果它包含ID,则更新或调用组件ID 的回调。如果您有所有组件的列表,则 ID 可以是列表索引,否则使用其实际指针或以样式 (component_type, component_index) 编码。如您所见,无论您有多少组件,这都非常快O(1) 项目选择...阴影屏幕可以具有与实际屏幕不同的分辨率(以节省内存)。

无论组件的形状如何,它都具有像素完美的鼠标选择精度,无需嵌套组件搜索循环。

[备注]

当我这样做时,这里有一些提示:

创建一个window ,其中包含单屏组件的配置。程序通常有更多的屏幕,其中包含不同的组件集,并且因为您切换页面/屏幕很糟糕而一遍又一遍地动态地执行屏幕。

使用单独的组件列表,每个组件类型一个列表。

为您的 Windows 创建 IDE 编辑器,请参阅 drag & drop example in C++ 它可能会派上用场。添加由string/enum or flag 控制的get,set 函数以轻松获取/更改属性以使对象检查器成为可能。这也是我的 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
//---------------------------------------------------------------------------

查看这里的图片plotting real time Data on Oscillocope 以获得一些想法(我得到了这个对 GDI 和 OpenGL 都有效)

最好使用像素单位而不是 OpenGL <-1,+1> 屏幕单位,以获得更好的视觉质量和编辑舒适度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-17
    • 2013-01-24
    • 2012-11-13
    • 2020-02-08
    • 2011-06-11
    • 2012-10-23
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多