Using the latest OpenGL functions for classes in Qt 5.4

I previously asked a question on how to get OpenGL to work with Qt, but now I want to use the latest OpenGL features to use. Prior to Qt, I used glew; but Qt says glew contradicts its QtOpenGL header file. I looked at QGLWidget and QGLFunctions, but to be honest, I'm confused about what I have to do to just get access to the OpenGL features.

Now I got Qt 5.4 using Qt Creator 3.3.0 and use the new QOpenGLWidget; however, the lack of guidance on how to use it throws me off a bit: the Qt documentation is there and helps, but it only demonstrates how to create an instance and not use it elsewhere in the program. I understand that the functions of QOpenGLWidget are similar to QGLWidget. Qt details that I should inherit from him; however, I am not creating an OpenGL context in a class that wants to use OpenGL functions; this happens in the glWidget class, which inherits from QOpenGLWidget.

For example, take this excerpt from one of my classes using OpenGL code:

void Mesh::init() { pNumIndices = pIndices.size(); glGenVertexArrays(1, &pVAO); glGenBuffers(1, &pVertexBuffer); glGenBuffers(1, &pIndexBuffer); glBindVertexArray(pVAO); glBindBuffer(GL_ARRAY_BUFFER, pVertexBuffer); glBufferData(GL_ARRAY_BUFFER, pVertices.size() * sizeof(Vertex), &pVertices[0], GL_STATIC_DRAW); // etc.. } 

Mesh is a class that does not inherit anything. Initially, he used only glew so that he could receive declarations of OpenGL functions; he did not need to know whether they are valid or not, since this is a print task. Then in the mainApp class, I would install glew. I also understand that there is a QOpenGLFunctions class, which is somewhat similar to the glew class, but with all these GL classes this is clearly confusing in order to know what to use. What else have I tried looking for glGenVertexArrays (..), but it is not found in QOpenGLBuffer, QOpenGLFunctions or QOpenGLWidget; and as far as I know, with OpenGL 4.5 it is still part of the specification; but my graphics drivers do not use OpenGL 4.5, so instead I use OpenGL 4.3. Suffice it to say that I am ready to abandon glew in order to adopt Qt's own approach to calling OpenGL functions.

In a program where various classes use OpenGL functions, how can I use Qt to call them without using glew? Mesh is one of those classes that does not instantiate OpenGL, but simply uses their functions.

Just to let people know, I use Qt for a while (not enough!) And enjoy Qt; but I need to know how I can use Qt in conjunction with OpenGL to continue development. Most tutorials still use pre-5.4 material.

+6
source share
4 answers

Qt 5.4 has headers with specific versions of OpenGL functions, so:

 #include <QOpenGLFunctions_3_3_Core> 

Or any version you want to use. Then, somewhere with a valid OpenGL context, such as QOpenGLWidget :: initializeGL (), create and initialize a QOpenGLFunctions object:

 QOpenGLFunctions_3_3_Core *fun = new QOpenGLFunctions_3_3_Core; fun->initializeOpenGLFunctions(); 

And then in your drawing code just use the OpenGL functions from this object:

 fun->glSomething(1,2,3) 
+4
source

A direct approach with OpenGL is to create a structure that contains pointers to functions:

 struct sLGLAPI { sLGLAPI() { memset( this, 0, sizeof( *this ) ); }; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLATTACHSHADERPROC glAttachShader; PFNGLBEGINQUERYPROC glBeginQuery; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; ... 

Fill it with dlsym -ed pointers from the OpenGL shared library:

 API->glActiveTexture = ( PFNGLACTIVETEXTUREPROC )GetGLProc( "glActiveTexture" ); API->glAttachShader = ( PFNGLATTACHSHADERPROC )GetGLProc( "glAttachShader" ); API->glBeginQuery = ( PFNGLBEGINQUERYPROC )GetGLProc( "glBeginQuery" ); API->glBindAttribLocation = ( PFNGLBINDATTRIBLOCATIONPROC )GetGLProc( "glBindAttribLocation" ); 

And access OpenGL in your code only through this structure. For instance:

 API->glShaderSource( Shader, 1, &Code, nullptr ); API->glCompileShader( Shader ); 

Thus, you can hide the full OpenGL API and even use stub functions if necessary, for example, to register parameters or to switch between OpenGL and OpenGL ES.

+1
source
 #include <QOpenGLFunctions_3_3_Core> class Mesh : public QOpenGLFunctions_3_3_Core { public: Mesh();//initializeOpenGLFunctions() ~Mesh(); void func();//glxxx in it. when using it ,you need an opengl context. //for example, use makeCurrent() in QOpenGLWidget subclass. }; 
+1
source

Using QOpenGLFunctions_X_X_ * will not solve this problem! Before using QOpenGLFunctions_X_X_ * you need to set the openGL context version. Qt uses the default version (I think 1.X), so you need to add this code to the main.cpp file

  QSurfaceFormat format; // format.setDepthBufferSize(24); // format.setStencilBufferSize(8); format.setMajorVersion( 3 ); //whatever version format.setMinorVersion( 3 ); // format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); 

Cheers, Nye

+1
source

Source: https://habr.com/ru/post/981760/


All Articles