I am so excited to post this! This is part 1 in a series of tutorials demonstrating how to render 2D/3D objects using the builtin functions of Qt 5.5. Part 1 will just be information to help you get started on the right foot. Part 2 will be drawing a basic triangle using the QOpenGLWindow class. Click here to go to Part 2 for example code.
I have been working on converting any basic OpenGL tutorial using modern OpenGL (3+) and Qt for a while now. Many OpenGL examples you see use the outdated fixed pipeline OpenGL.
You can recognize those by their use of glBegin()/glEnd(). Almost all of the examples I found that reference modern OpenGL use the Windows API with GLEW and GLUT or similar. This tutorial uses the modern OpenGL Qt functions like QOpenGLBuffer (OpenGL VBO) and QOpenGLVertexArrayObject (OpenGL VAO). If you already have Qt as a dependency then I think this is the easiest and best way to write a cross platform OpenGL application. That is probably not true if you are writing a 3D game as I don’t have any experience in that area. If you want a 2D cross platform game then I decided V-Play with Qt was the easiest way. If you are reading this then there is a good chance you are new to Qt or OpenGL so I will link you to some prerequisite reading you should probably do. Thanks to the many tutorials and OpenGL examples I found online that helped me get this far! Note that the fact Qt uses OpenGL for its internal rendering is mostly unrelated to custom rendering OpenGL graphics using the relatively low level Qt OpenGL functions and classes.
Note that modern OpenGL generally means OpenGL 3 functions and higher. Starting with OpenGL 3.2 the old style functions were deprecated and need to be accessed through a core profile (as opposed to a forwards compatibility profile). Qt defaults to use a subset of OpenGL functions that can be used on all platforms including mobile. I don’t think that all the modern OpenGL functions will be fully supported on mobile with Qt until OpenGL ES 3.0 is the default for Qt. Note that you can always do anything you want if you try hard enough. I am talking about full support as defined by you can use that functionality in the same way as you normally would for Qt desktop development. That definition will be different for some other people. If you choose to set the OpenGL version of our Qt classes to 3 or higher or you use OpenGL functions that are not part of OpenGL ES 2 then you are basically developing for desktop currently. As of Qt 5.5 the prebuilt binaries (aka Qt library available for download on their website) defaults to the Qt compile option of -opengl dynamic. This means that Qt will 1) try to use OpenGL drivers on the client computer then 2) use the ANGLE library to translate OpenGL functions to Direct3D functions if on Windows and no suitable OpenGL driver was found. This is important if you are trouble shooting an example and read online that maybe it is because you don’t have a Qt install with the -desktop option. If you use the prebuilt binary you no longer have to worry about that.
*If you want to just read one other website on OpenGL choose this one. This is a well done but concise introduction to modern OpenGL by Joe Groff.
*All the QOpenGL classes and functions documentation can be found here (use as reference do not try and read all)
*Here is the blog series introducing the latest Qt OpenGL functions by the main contributors to Qt in this area. There are more parts but I found the first one the most helpful for basic rendering. They also give a bit of the history of OpenGL with Qt.
*QOpenGLWindow example this code is loosely based on.
*OpenGL website introduction
*OpenGL and GLSL specifications
There are Three Main Ways to Combine Qt and OpenGL
1 – Use external to Qt OpenGL libraries for rendering (ie native platform API and GLEW) and use Qt just for its other functionality like creating menus and buttons and such. (This I have read is tricky but doable as Qt coding style and headers can conflict with standard OpenGL usage. You also have to figure out how to share an OpenGL context across threads with this method I believe.)
2 – Use Qt OpenGL functions and/or context inheriting from QOpenGLFunctions but do not use Qt helper classes like QOpenGLVertexArrayObject QOpenGLBuffer etc (basically pick and choose which Qt classes/functions you think gives you the best functionality)
3 – Use Qt OpenGL functions and all helper classes (for reasonably simple rendering I believe this is the easiest way to get cross platform compatibility)
Qt Has Two Options for Rendering OpenGL to the Screen
You can subclass QWindow to create a full window graphics application or you can subclass QOpenGLWidget to create an application with an OpenGL graphics view alongside other widgets. QOpenGLWidget is the approach for creating a standard application with menus and toolbars inside a QMainWindow. I recommend starting with the QWindow class unless you are already familiar with using Qt.
To start with you need to ensure that your shader language version is not higher than your OpenGL context you are planning on using. Combining shaders from different examples online with your context creation code can get you into trouble! Check here to make sure you are using a supported shader language version. The shader language for OpenGL is called GLSL and you can see the version at the top of most shader code that looks like this “#version 140”. That corresponds to GLSL 1.4 which is the maximum version supported by OpenGL version 3.1 which I am planning on using. There are only two types of shaders: vertex and fragment. Vertex shaders do math on the co-ordinates of each vertex point. Fragment shaders process the texture or colour of each fragment. GLSL variables declared with the uniform keyword are constant and shared between vertex and fragment shaders for the whole call to render the screen. Shader input variables refer to OpenGL attribute names. I am not a master of shaders yet but you don’t really need to know more than that to get started with these tutorials.
Other Tutorials Showing More Advanced OpenGL Usage