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

C++ 简单OpenGL GUI框架用户交互建议?,c++,user-interface,opengl,user-controls,glut,C++,User Interface,Opengl,User Controls,Glut,我将从头开始设计一个简单的GUI框架,作为一个项目,使用OpenGL而不是其他外部工具,需要一些关于如何实现用户交互的建议 基本上,我有一个基类GUIItem,所有元素都从中继承。这为每个项目提供了一些基本变量,如位置、包含子元素的向量以及一些鼠标移动和单击的基本函数 所有元素的设置如上所述,并带有相关的成员变量 我正在努力解决的是如何正确地实现用户交互。在我的窗口管理器中,我会创建一个项目的新实例,比如说GUIButton,并将其称为button1。当点击发生时,窗口管理器将遍历其元素列表及其

我将从头开始设计一个简单的GUI框架,作为一个项目,使用OpenGL而不是其他外部工具,需要一些关于如何实现用户交互的建议

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

所有元素的设置如上所述,并带有相关的成员变量

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

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

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


<关于这个问题的任何建议都是受欢迎的,因为我是C++的新手,这是我第一次接触GUI编程,当现有的GUI框架是通常的选择时,没有太多的事情要做。

< P>如果你想要一个强的、愚蠢的、简单的、快速的< /强>,那么你可以:

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

  • 预渲染此缓冲区

    只需将每个视觉组件渲染到它,而只需填充渲染组件的
    ID/index/pointer
    ,即可进行着色/纹理处理。不要忘了先用一些
    NULL
    清除此项。。。在此之后,您应该有您的组件的掩码。你只需要做一次

  • 在鼠标事件上

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

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

    [Notes]

    在我做这件事时,这里有一些提示:

    创建一个
    窗口
    ,其中包含单个屏幕组件的配置。程序通常有更多的屏幕,这些屏幕包含不同的组件集,并且一次又一次地动态地显示屏幕,这仅仅是因为您切换页面/屏幕很糟糕

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

    为您的windows创建IDE编辑器,这可能会很方便。添加由
    string/enum或flag
    控制的
    get、set
    函数,以方便获取/更改属性,使对象检查器成为可能。这也是我的IDE的外观:

    < >窗口直接从IDE中保存为C++代码,我可以复制到我的应用程序。这是上面没有旋钮的示例(忘记保存):

    请看这里的图片,了解一些想法(我在GDI和OpenGL中都得到了这一点)


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

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