[Interest] Usage of QAbstractOpenGLFunctions and derived classes

Yves Bailly yves.bailly at sescoi.fr
Tue Dec 17 09:49:48 CET 2013


Greetings all,

Using the just released Qt 5.2.0 with QtCreator 3.0, compiler Visual C++ 2012 64bits on Windows 7 64bits.

I'm trying to use the QtGui/QOpenGLFunctions_3_3_Core class to get access to
OpenGL 3.3 Core functions (desktop obviously), by subclassing QGLWidget like
this:

class Gl_Widget: public QGLWidget, protected QOpenGLFunctions_3_3_Core
{
   virtual void initializeGL() override;
   /*...*/
};

The first lines of "initializeGL()" are:

void Gl_Widget::initializeGL()
{
   if ( not this->isInitialized() )
     this->initializeOpenGLFunctions();
   /*...*/
}

A few questions now.


(1)
When I try to build this program, I get a link error:
gl_widget.obj : error LNK2019: symbole externe non résolu "protected: bool __cdecl 
QAbstractOpenGLFunctions::isInitialized(void)const " 
(?isInitialized at QAbstractOpenGLFunctions@@IEBA_NXZ) référencé dans la fonction "protected: virtual 
void __cdecl Gl_Widget::initializeGL(void)" (?initializeGL at Gl_Widget@@MEAAXXZ)

...which basically says the external symbol QAbstractOpenGLFunctions::isInitialized() could not be 
resolved.
If I remove the "if" line, thus not calling isInitialized(), everything works fine. I even tried to force
name resolution with "if (not this->QOpenGLFunctions_3_3_Core::isInitialized())", but no luck.

Any idea about what can go wrong?



(2)
For what I see, the QOpenGLFunctions_* classes are storing a bunch of function pointers, which are
dynamically resolved at runtime. If I want to use those functions, I can either:
- ask a pointer from the context by QOpenGLContext::versionFunctions(), which makes then a code looking
   like:
   gl_funcs->glGenBuffer(...);
   gl_funcs->glBindBuffer(...);
   gl_funcs->glDrawElements(...);
   ...where the "gl_funcs->" prefix is quite cumbersome, to say the least.
- or subclass from QOpenGLFunctions_* when needed for a more direct access to the function. But in
   this case, what if I need access to OpenGL functions in hundreds or thousands of instances?
   resolving and storing function pointers in each of them would be overkill.

To alleviate those points, I tried something like this (with various variations and more sanity checks):
class My_Class: public Some_Other_Super, protected QOpenGLFunctions_3_3_Core
{
   void some_init_method()
   {
     QOpenGLContext* ctx = QOpenGLContext::currentContext();
     QOpenGLFunctions_3_3_Core* funcs = ctx->versionFunctions<QOpenGLFunctions_3_3_Core>();
     dynamic_cast<QOpenGLFunctions_3_3_Core&>(*this) = *funcs;
   }
}
...in the hope to be able to reuse already resolved function pointers, hoping QOpenGLFunctions_*
classes are using implicit sharing or something like that... but of course it doesn't work, I
get crashes when destroying instances, double-deletes, and so on.

I tried to fallback to Glew, but for whatever reason it refuses to resolve e.g. glCopyBufferSubData(),
whereas it's resolved fine by QOpenGLFunctions_3_3_Core...


I searched the doc, but couldn't find any hint on the "right way" to easily use those QOpenGLFunctions_*
classes in non-trivial cases. Has others had more ideas?

Thanks in advance.

-- 
      /- Yves Bailly - Software developer   -\
      \- Sescoi R&D  - http://www.sescoi.fr -/
"The possible is done. The impossible is being done. For miracles,
thanks to allow a little delay."



More information about the Interest mailing list