调用 glutWireSphere() 时 PyOpenGL 访问冲突读取

PyOpenGL Access Violation Reading when calling glutWireSphere()

我正在 Python3.5.2

上使用 PyOpenGLPyQt5 构建应用程序

该应用程序的目的是使用 QGLWidget class 设置一个 window 并使用 glutWireSphere 函数绘制一个球体。该代码在我的 Ubuntu Linux 16.04 LTS 笔记本电脑上运行良好,但在我的 Windows 7 台式机上崩溃,OSError: exception: access violation reading 0x00000000000000C1glutWireSphere 行。如果我注释掉这一行,程序就会正常执行。我尝试了一个不同的代码示例(下面的示例),它演示了如何使用 glut 绘制一个球体并且它没有被压碎,但是它使用 glut.[=33= 管理 windowing ]

我的代码:

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
from PyQt5.QtOpenGL import *
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5 import QtCore


class MyWidget(QGLWidget):

    def __init__(self, parent = None):
        super(MyWidget, self).__init__(parent)

        self.cameraDistanceZ = 10

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glColor3f(0.33, 0.33, 0.33)
        glutSolidSphere(1, 20, 20)


    def resizeGL(self, w, h):
        glViewport(0, 0, w, h)
        self.setOrthoProjection()
        self.screenCenterX = w/2
        self.screenCenterY = h/2

    def setOrthoProjection(self):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        w = self.width()
        h = self.height()
        glOrtho(-10, 10, -10, 10, -5.0, 15.0)
        gluLookAt(0,0,self.cameraDistanceZ, 0,0, -10, 0,1,0)

    def initializeGL(self):
        print("Start init process")
        glutInit(sys.argv)
        glClearColor(0.0, 0.0, 0.1, 0.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glClearDepth(1.0)

        self.updateGL()


def main():
    app = QtWidgets.QApplication(["To parathyro"])
    widget = MyWidget()
    widget.show()
    sys.exit(app.exec_())
if __name__ == '__main__':
    main()

工作示例:

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import sys


def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
    glutInitWindowSize(400,400)
    glutCreateWindow(b"myWindow")

    glClearColor(0.,0.,0.,1.)
    glShadeModel(GL_SMOOTH)
    glEnable(GL_CULL_FACE)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_LIGHTING)
    lightZeroPosition = [10.,4.,10.,1.]
    lightZeroColor = [0.8,1.0,0.8,1.0] #green tinged
    glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor)
    glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1)
    glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05)
    glEnable(GL_LIGHT0)
    glutDisplayFunc(display)
    glMatrixMode(GL_PROJECTION)
    gluPerspective(40.,1.,1.,40.)
    glMatrixMode(GL_MODELVIEW)
    gluLookAt(0,0,10,
              0,0,0,
              0,1,0)
    glPushMatrix()
    glutMainLoop()
    return

def display():
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glPushMatrix()
    color = [1.0,0.,0.,1.]
    glMaterialfv(GL_FRONT,GL_DIFFUSE,color)
    glutWireSphere(1,20,20)
    glPopMatrix()
    glutSwapBuffers()
    return

if __name__ == '__main__': main()

如果我尝试绘制其他内容,例如 glutSolidSphere,我会收到相同的错误,但地址不同。我在网上发现的所有访问冲突错误都是特定于应用程序的,它们大多与某些函数中的错误输入类型有关。我的应用程序中不会出现这样的错误,因为我的代码中的函数没有接受很多参数,或者有些东西我还没有注意到。

对于我的 Windows 7 桌面系统,我从官方网站下载了 Python 3.5.2,我通过 [=32] 使用 pipPyOpenGL 安装了 PyQt5 =] 说明

我认为它与 freeglut 库中的问题有关,但它适用于不同的示例。我想这与我在应用程序中初始化 freeglut 的方式有关,或者与 PyQT5

有关

问题

如何在不为我的应用程序迁移到不同架构的情况下跟踪问题并解决它?

似乎发生崩溃是因为 glutWireSphere 要求您先调用 glutCreateWindow,例如检查这个小片段:

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *

from PyQt5.Qt import *  # noqa


class MyWidget(QGLWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glPushMatrix()
        color = [1.0, 0., 0., 1.]
        glMaterialfv(GL_FRONT, GL_DIFFUSE, color)
        glutWireSphere(1, 20, 20)
        glPopMatrix()
        glutSwapBuffers()

    def glutInitialization(self):
        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(400, 400)
        glutCreateWindow(b"Glut Window")

    def initializeGL(self):
        glClearColor(0., 0., 0., 1.)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_CULL_FACE)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_LIGHTING)
        lightZeroPosition = [10., 4., 10., 1.]
        lightZeroColor = [0.8, 1.0, 0.8, 1.0]  # green tinged
        glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition)
        glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor)
        glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1)
        glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05)
        glEnable(GL_LIGHT0)
        glMatrixMode(GL_PROJECTION)
        gluPerspective(40., 1., 1., 40.)
        glMatrixMode(GL_MODELVIEW)
        gluLookAt(0, 0, 10,
                  0, 0, 0,
                  0, 1, 0)
        glPushMatrix()

        self.glutInitialization()


def main():
    app = QApplication(["To parathyro"])
    widget = MyWidget()
    widget.setWindowTitle("Pyqt Widget")
    widget.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

您可以看到球体在 pyqt window(活动 gl 上下文)中的显示方式。然后,再次评论 glutCreateWindow(b"Glut Window") 和 运行,这样你就会看到段错误崩溃又会出现。

我的建议?当不使用 Glut 作为 opengl window 管理系统时,我不会依赖过剩几何函数。

顺便说一句,生成球体根本不是 hard 值得你试一试 :)