QT for OpenglEs on Desktop

时间:2015-06-26 09:40:46

标签: qt opengl opengl-es

I have an existing project which uses openglEs library (libGLESv2.lib) on DESKTOP platform.

Now I want to use QT as its user interface by using QGLwidget. However after calling any OpenGL function in QGLwidget::initializeGL function I get Access violation executing location 0x00000000 error at the code below,

   void MyGLWidget::initializeGL()
    {


        if (!context()->create())
            throw std::exception("no context :)");
        context()->makeCurrent();

        glViewport(0, 0, 640, 480);
    }

If I also include the library opengl32.lib then glviewport function works but when I hit to glGenFramebuffers then I get the same error.

Could you please let me know how can I configure my project to use QT with opengles on desktop platform.

1 个答案:

答案 0 :(得分:0)

If I also include the library opengl32.lib then glviewport function works but when I hit to glGenFramebuffers then I get the same error.

glViewport is a OpenGL function found in every OpenGL version and profile since version 1. As such it's immediately available simply by linking against the basic OpenGL interface library.

glGenFramebuffers is a function introduced only with OpenGL-3 (OpenGL-ES 2, BTW, OpenGL-ES is not natively supported on Windows) and before you can use it, you have to

  1. check that it is actually supported
  2. load the OpenGL context dependent function pointer at runtime into the variable symbol you're actually calling

Failing to do the second step will give you the error you encounter. Failing to do the first step you try to load it, but loading may fail leading to the same result as if you didn't do (2) at all.

Qt provides all the function loading checks and executions for you, so I suggest you use it: http://doc.qt.io/qt-4.8/qglfunctions.html

It's not perfect, but it gets the job done.

Update (from comments)

Most likely you already have some OpenGL loader library in your project, that actually resolves everything, but before using Qt you did properly initialize it. Now using Qt you've got a mix of statically resolved symbols through opengl32.lib and symbols provided by that loader, yet the loader is not initialized. Look through the code as it was before integrating Qt and look for some initializing call (called after creating the OpenGL context/window but before doing any OpenGL work).

My best guest would be, that the EGL bindings you use also implement the OpenGL-ES wrapper/loader. As I already explained, Windows doesn't natively support OpenGL-ES (only regular OpenGL) and some kind of compatibility layer is required. It is most likely this layer that's getting in your way now. The good news is, that since you're on Windows you can use regular native OpenGL-3 instead; for the most part OpenGL-ES is a subset of OpenGL-3. You'll still need to runtime load GL-3 functions, but as already said, Qt can do that for you.

What to do:

  • Replace all occurrences of #include <EGL/egl.h> with #include <GL/gl.h> – that should get rid of the symbol shadowing.
  • Next, for all classes in which use of OpenGL functions is made, add an inheritance of QGLFunctions so that in the classes' namespaces the dynamically loaded functions are used.

Note that every class that inherits QGLFunctions must be instanced only when the target OpenGL context is made current OR you call initializeFunctions on the instances from QGLWidget::initializeGL (or its derivatives). you have to do the function initialization once for each instance of the class inheriting QGLFunctions and the initialization function must be called when the OpenGL context that's to be used is currently active. Like I said, Qt's QGLFunctions is not perfect; if it were it would do the necessary function pointer loading on demand, cache the result and in case of a OpenGL context switch automatically reinitialize.