views:

319

answers:

2

Hi all,

I'm new here, and have a question about opengl in Qt4, which I've been learning over the last few months.

Particularly, I'm seeking advice on the best way to compose a scene in a good object-oriented fashion using the QGLWidget. I'd ideally like every item in my scene to be sub-classes of a super 'Entity' class. Then in my main QGLWidget I can sort the entities and render them accordingly.

I noticed though that certain openGL functions (like bindTexture) need to be called from the QGLWidget (or the widget's QGLContext). At the moment I'm passing a pointer to the QGLWidget that controls my main viewport to each entity and storing it so that I can gain access to those functions. Is this a good idea?

Any advice would be gratefully received, or even directions to good websites/books that might be of help. I've got the Blanchette/ Summerfield book but the OpenGL section is quite short and most of the examples on the Qt website are pretty simplistic.

Thanks, Dan

A: 

You are building something that is usually called "scene graph". In our engine scene graph objects need no access to QGLWidget. It's enough if you create your OpenGL objects inside void initializeGL() and render everything inside void paintGL().

There is a slightly higher level Qt/OpenGL example called Boxes. It can be found from qt/demos/boxes folder in Qt 4.6 installation.

Virne
Thanks for your help. That example is very handy, and I hadn't come across it before.I've read a little about scene-graphs before, but never fully implemented one. I definitely need some simple frustrum culling so will investigate further but probably don't want to delve into anything too advanced. This is for a university project, so no end users other than myself and tutors. As long as it's relatively stable and I'm able to prove my other concepts, that's what counts.
talldan
+1  A: 

I agree with Vime: You're building a scene graph, and there are a number of classical approaches for designing its object hierarchy. Check out "3D Game Engine Design," by Dave Eberly, for details on one such engine, and look at OGRE for another example.

Since only one GL context can be active at a time on a particular thread, consider storing the QGLWidget pointer as a static class member to save effort:

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();
    // ...
}

Then in your entity classes you can simply call MyGLWidget::GetActiveWidget() on the few occasions when you need to call QGLWidget member functions, and not need to copy a (probably invariant) pointer all over the place.

ChrisV
Thanks ChrisV, your static class member example makes an awful lot of sense and I've got that working.I do have the Eberly book but haven't read it in detail, I've started looking at the section on Scene Graphs now though. How about OpenSceneGraph? I've heard a bit about that and have downloaded it to take a look, had any experience with it?
talldan
The one time I used OSG I wasn't too impressed, but that was a) several years ago and b) as part of a generally awful codebase. The object hierarchy design just didn't appeal to me. Since as I recall it tried to map a lot of OpenGL concepts directly into classes you can certainly take a look at it.My advice for choosing a scene graph library, though? Look at the exporters. If you can't get your geometry into the library easily, it doesn't matter how well-designed the rest of the library is.
ChrisV