1

我在 PyQt5 中编写了一个应用程序。我想使用可用的最新 OpenGL 版本。我也想要一些向后兼容性。

目前我有:

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

但是我想尽可能使用最新版本。

我需要类似的东西:

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

elif supported(4, 4):
    ...

这是我的代码:

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_()

编辑1:

如何编写像supported()上面这样的函数?

编辑2:

我运行版本查询,窗口要求支持 OpenGL3.3:

GL_VERSION -> 3.3.0 NVIDIA 382.05
GL_VENDOR  -> NVIDIA Corporation
GL_MAJOR   -> 3
GL_MINOR   -> 3
4

1 回答 1

1

OpenGL 实现不会为您提供您要求的版本。他们为您提供了与您所要求的兼容的 OpenGL 版本。4.5 核心与 3.3 核心兼容,因此即使您要求 3.3 核心,实现也可以免费为您提供 4.5 核心上下文。

因此,如果您的意图是使 3.3 成为最低要求,并且您的代码利用 3.3 后的功能(如果它们可用),那么正确的做法是要求最低要求。然后询问 OpenGL 的实际版本是什么,并使用它来打开那些可选功能。

但是,如果您不打算使用 3.3 后的功能,那么就没有理由做任何事情。如果您的代码没有显式调用任何 3.3 后的 OpenGL 功能,那么基于 3.3 的代码在 4.5 实现上的运行与 3.3 实现没有什么不同。

OpenGL 版本并不表示驱动程序中的错误修复等。因此,您使用什么版本是 API 本身的问题:该版本提供的代码实际使用的特性和功能。如果您针对 3.3 编写代码,则要求 3.3 并完成它。

于 2017-05-31T14:59:18.007 回答