tags:

views:

596

answers:

3

I'm adding OpenGL support to a game that is based on Qt 3 (office politics). The basics (QGLWidget, etc) work fine.

To get to OpenGL extensions, I arbitrarily chose GLee (it compiled out of the box, GLew didn't).

GLee.h and qgl.h don't play nicely together. AFAICT, each must be included before the other.

I yanked the preprocessing checks [that make sure it's included first] out of GLee.h, inserted the preprocessing directives it uses before including the OpenGL headers, then included qgl.h first. On linux, it boils down to:

    #define __glext_h_  /* prevent glext.h from being included  */
    #define __glxext_h_ /* prevent glxext.h from being included */
    #define GLX_GLXEXT_PROTOTYPES
#include <qgl.h>
#include "GLee.h" // my hacked version

That builds (no idea whether my code will actually run yet...this question's pre-emptive [i.e. I'm procrastinating]), but it seems like a horrible kludge. Googling has turned up a lot of people asking this basic question (though most of them haven't bothered figuring out the bogus compiler errors so they can see the root problem), but I haven't seen any actual answers.

Is there a better (more elegant, portable, robust, etc) way to do this?

A: 

Short answer: use glew. it works just fine with QT.

shoosh
+1  A: 

I suspect that your patch won't work, since it prevents necessary headers from being included. This can cause all sorts of weird problems.

(Edit: I no longer suspect that, after reading one of your comments - if all you pulled out of GLee.h were the checks and #error directives, things should work... Probably.)

As far as I can tell, the problem stems from Qt trying to define enumerations that conflict with X preprocessor macros. Specifically, CursorShape is defined by X.h to be 0, and then by qnamespace.h to be an enumeration, resulting in the rather unhelpful error message "error: expected identifier before numeric constant"

A cleaner way to do what you're trying to do is to include the files in this order, and with these macros undefined:

#include "qgl.h"
#undef __glext_h_
#undef __glxext_h_
#undef __gl_h_
#include "GLee.h"

This doesn't require patching GLee.h, but may yield unexpected results, depending on why GLee.h wants to be included first.

A better solution would be to include GLee.h and qgl.h in separate compilation units, but that may not be possible.

By the way, a good debugging strategy for this sort of problem is to pass -E to gcc - this will give you the preprocessed source, which you can examine to find the offending line. In this case, the enum name was replaced by a 0 constant, which made it clear that the name was being defined elsewhere. Grepping for the enum name under /usr/include revealed the offending header to be X.h. Well, to be fair, the offending pary here is Qt - developers should know better than to use X11 constants as identifiers in a cross platform framework.

Ori Pessach
+1  A: 

This still isn't as clean as I'd like, but it at least builds and runs, without hacking GLee.h.

After everything else, #include qobject.h, GLee.h, and qgl.h (in that order).

So, the header file might look like

...blah...
...other #includes

#include <qobject.h>
#include "GLee.h"
#include <qgl.h>

class MyGlWidget : public QGLWidget
{
...
}

then the soure file would #include that file last.

James
What's wrong with that? Looks as good as you can hope for given the way Trolltech chose their identifier names... You might want to add a comment explaining the include order, but other than that it's fine.
Ori Pessach