1

I write an application in PyQt5. I want to use the latest OpenGL version available. I want some backward compatibility as well.

Currently I have:

fmt = QtOpenGL.QGLFormat()
fmt.setVersion(3, 3)
fmt.setProfile(QtOpenGL.QGLFormat.CoreProfile)

However I want to use the latest version possible.

I need something like:

if supported(4, 5):
    fmt.setVersion(4, 5)

elif supported(4, 4):
    ...

Here is my code:

import struct

import ModernGL
from PyQt5 import QtOpenGL, QtWidgets


class QGLControllerWidget(QtOpenGL.QGLWidget):
    def __init__(self):
        fmt = QtOpenGL.QGLFormat()
        fmt.setVersion(3, 3)
        fmt.setProfile(QtOpenGL.QGLFormat.CoreProfile)
        fmt.setSampleBuffers(True)
        super(QGLControllerWidget, self).__init__(fmt, None)

    def initializeGL(self):
        self.ctx = ModernGL.create_context()

        prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                in vec2 vert;

                void main() {
                    gl_Position = vec4(vert, 0.0, 1.0);
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                out vec4 color;

                void main() {
                    color = vec4(0.30, 0.50, 1.00, 1.0);
                }
            '''),
        ])

        vbo = self.ctx.buffer(struct.pack('6f', 0.0, 0.8, -0.6, -0.8, 0.6, -0.8))
        self.vao = self.ctx.simple_vertex_array(prog, vbo, ['vert'])

    def paintGL(self):
        self.ctx.viewport = (0, 0, self.width(), self.height())
        self.ctx.clear(0.9, 0.9, 0.9)
        self.vao.render()
        self.ctx.finish()


app = QtWidgets.QApplication([])
window = QGLControllerWidget()
window.show()
app.exec_()

EDIT 1:

How to write a function like supported() above?

EDIT 2:

I run a version query with a window asking for OpenGL3.3 support:

GL_VERSION -> 3.3.0 NVIDIA 382.05
GL_VENDOR  -> NVIDIA Corporation
GL_MAJOR   -> 3
GL_MINOR   -> 3
Szabolcs Dombi
  • 5,493
  • 3
  • 39
  • 71
  • So what is your question? You already included an answer. – BDL May 31 '17 at 09:11
  • there is no such function as `supported()` I have no clue how can I use PyQt to do that. (I just edited the question to make sure others will understand it, thanks) – Szabolcs Dombi May 31 '17 at 11:54
  • "code to adapt to whether GL 4.5 or 4.4 is there?" yes some features will be optional and will depend on opengl 4.1 and 4.3 mostly. I can test if `ctx.version_code >= 410` but this may only work if i explicitly ask QT to make an `OpenGL 4.1` context. – Szabolcs Dombi May 31 '17 at 14:59

1 Answers1

1

OpenGL implementations do not give you the version you ask for. They give you a version of OpenGL that is compatible with what you ask for. 4.5 core is compatible with 3.3 core, so an implementation is free to give you a 4.5 core context, even if you asked for 3.3 core.

So if your intent is to have 3.3 be a minimum, with your code taking advantage of post-3.3 features if they're available, the right way to do it is to ask for the minimum. Then ask OpenGL what the actual version is, and use that to turn on those optional features.

But if you don't intend to ever use post-3.3 features, then there's no reason to do anything. If your code doesn't explicitly invoke any post-3.3 OpenGL functionality, then your 3.3-based code will run no differently on a 4.5 implementation than a 3.3 one.

OpenGL versions don't signify things like bug fixes in drivers and the like. So what version you use is a matter of the API itself: the features and functionality that version provides which your code actually uses. If you wrote your code against 3.3, then ask for 3.3 and be done with it.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Asking for core 3.3 does not allow me to use subroutines. this is why i ask for 4.x context explicitly (then it works fine) but i loose my backward compatibility this case. (i get 0 pointer for subroutine related functions) – Szabolcs Dombi Jun 01 '17 at 07:45
  • 2
    @SzabolcsDombi: If your code needs shader subroutines, then your code *needs* GL 4.0 or better. Therefore, that is what your code should ask for. You lose backwards compatibility because your code *requires* features from higher GL versions. You ask for what you need. If you truly need shader subroutines, ask for a GL version that supplies them. If you truly need greater compatibility, stop using features from versions that are higher than your compatibility targets. – Nicol Bolas Jun 01 '17 at 14:07
  • The best "app" that shows what i want would be an example browser... So if you have OpenGL 4.5 you will see 100+ examples if you have only OpenGL 3.3 you will see only 50+ examples. – Szabolcs Dombi Jun 01 '17 at 14:11
  • @SzabolcsDombi: My answer explains how to do that. You ask for a *minimum*; you then check to see what version you actually got, and you adjust your code paths according to the version you got. – Nicol Bolas Jun 01 '17 at 14:12