求Qt4中使用QGLWidget的建议

Posted

技术标签:

【中文标题】求Qt4中使用QGLWidget的建议【英文标题】:Seeking advice on using QGLWidget in Qt4 【发布时间】:2010-01-26 14:21:02 【问题描述】:

我是新来的,有一个关于 Qt4 中的 opengl 的问题,这是我过去几个月一直在学习的。

特别是,我正在寻求有关使用 QGLWidget 以良好的面向对象方式组成场景的最佳方式的建议。理想情况下,我希望场景中的每个项目都是超级“实体”类的子类。然后在我的主 QGLWidget 中,我可以对实体进行排序并相应地呈现它们。

我注意到虽然某些 openGL 函数(如 bindTexture)需要从 QGLWidget(或小部件的 QGLContext)中调用。目前,我正在传递一个指向 QGLWidget 的指针,该指针控制每个实体的主视口并将其存储,以便我可以访问这些函数。这是个好主意吗?

我们将不胜感激地收到任何建议,甚至是对可能有帮助的好网站/书籍的指导。我有 Blanchette/Summerfield 的书,但是 OpenGL 部分很短,而且 Qt 网站上的大多数示例都非常简单。

谢谢, 丹

【问题讨论】:

【参考方案1】:

我同意 Vime 的观点:您正在构建一个场景图,并且有许多经典的方法来设计它的对象层次结构。查看 Dave Eberly 的“3D 游戏引擎设计”,了解有关此类引擎的详细信息,并查看 OGRE 以获取另一个示例。

由于在特定线程上一次只能激活一个 GL 上下文,请考虑将 QGLWidget 指针存储为静态类成员以节省工作量:

class MyGLWidget : public QGLWidget 
    // ...
public:
    static inline MyGLWidget *GetActiveWidget() 
        return ms_activeWidget;
    
protected:
    static __declspec(thread) MyGLWidget *ms_activeWidget = 0; // uses MSVC extension
    inline void SetActiveWidget() 
        ms_activeWidget = this;
    
;

void MyGLWidget::paintGL() 
    SetActiveWidget();
    // ...

然后在您的实体类中,您可以在需要调用 QGLWidget 成员函数的少数情况下简单地调用 MyGLWidget::GetActiveWidget(),而无需到处复制(可能是不变的)指针。

【讨论】:

感谢 ChrisV,您的静态类成员示例非常有意义,我已经完成了。我确实有 Eberly 的书,但没有详细阅读,不过我现在已经开始查看有关场景图的部分。 OpenSceneGraph 怎么样?听说了一点,下载下来看看,有经验吗? 有一次我使用 OSG 并没有给我留下太深刻的印象,但那是 a) 几年前 b) 作为一个普遍糟糕的代码库的一部分。对象层次结构设计对我没有吸引力。因为我记得它试图将许多 OpenGL 概念直接映射到类中,所以你当然可以看一下它。不过,我对选择场景图库的建议是什么?看看出口商。如果您无法轻松地将几何图形放入库中,那么库的其余部分设计得多么好都没关系。【参考方案2】:

您正在构建通常称为“场景图”的东西。在我们的引擎场景图中,对象不需要访问 QGLWidget。如果您在 void initializeGL() 中创建 OpenGL 对象并在 void paintGL() 中渲染所有内容,这就足够了。

有一个更高级别的 Qt/OpenGL 示例,称为 Boxes。它可以在 Qt 4.6 安装中的qt/demos/boxes 文件夹中找到。

【讨论】:

感谢您的帮助。这个例子很方便,我以前没有遇到过。我之前读过一些关于场景图的文章,但从未完全实现过。我肯定需要一些简单的截锥体剔除,所以会进一步调查,但可能不想深入研究任何太高级的东西。这是一个大学项目,所以除了我自己和导师之外没有最终用户。只要它相对稳定并且我能够证明我的其他概念,这才是最重要的。

以上是关于求Qt4中使用QGLWidget的建议的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt 4.8.0 中使用 QGlWidget 更改 QWidget

QGLWidget RenderText() 崩溃和文本混乱

从 QGLWidget 迁移到 QWindow

分离线程中的 Qt4/Opengl bindTexture

是否可以在 QtDesginer 中编辑单个 Widget?

Qt4 插槽和信号:Qt4 无法找到信号