简单的OpenGL GUI框架用户交互建议?

时间:2015-12-13 03:41:06

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

我正在设计一个简单的GUI框架作为一个项目,使用OpenGL而不是外部的东西,需要一些关于如何实现用户交互的建议。

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

所有元素都按照上面的设置及其相关成员变量进行设置。

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

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

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

对于这方面的任何建议真的很受欢迎,因为我是C ++,OpenGL的新手,这是我第一次接触到GUI编程,并且当现有的GUI框架是通常的选择时,没有太多的事情要做

1 个答案:

答案 0 :(得分:1)

如果您想要愚蠢简单和快速,那么您可以:

  1. 创建包含ID/index/pointer而非彩色
  2. 的影子屏幕缓冲区
  3. 预渲染此缓冲区

    只需将每个可视组件渲染到它,而是着色/纹理只需填充渲染组件的ID/index/pointer。不要忘记首先用一些NULL来清除它...在此之后你应该有你的组件的掩码。你只需要做一次......

  4. 关于鼠标事件

    您只需将鼠标坐标转换为阴影屏幕空间并选择值即可。如果它是NULL,那么你点击或空白区域。如果它包含ID,则更新或调用组件ID的回调。如果你有一个所有组件的列表,那么ID可以是列表索引,否则使用其实际指针或以样式(component_type, component_index)编码。正如您所看到的,无论您拥有多少组件,这都是相当快的O(1)项目选择...阴影屏幕可以具有与您的实际屏幕不同的分辨率(以保留内存)。

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

    <强> [注释]

    正如我所做的那样,这里有一些提示:

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

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

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

    在这里查看图片plotting real time Data on Oscillocope以获取一些想法(我让它适用于GDI和OpenGL)

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