调用glutWireSphere()

时间:2018-02-20 18:57:18

标签: python pyqt access-violation pyopengl

我正在PyOpenGL上使用PyQt5Python3.5.2构建应用程序

该应用程序的目的是使用QGLWidget类设置一个窗口,并使用glutWireSphere函数绘制一个球体。该代码在我的Ubuntu Linux 16.04 LTS笔记本电脑上正常运行,但在我的Windows 7桌面上OSError: exception: access violation reading 0x00000000000000C1glutWireSphere时崩溃了。如果我注释掉这一行,程序将正常执行。我尝试了一个不同的代码示例(下面的示例),该示例演示了如何使用glut绘制球体并且没有压缩,但它使用glut来管理窗口。

我的代码:

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的{​​{1}}桌面系统,我使用Python 3.5.2PyQt5通过Unofficial Windows Binaries for Python Extension Packages安装了pip根据{{​​3}}说明

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

有关

问题

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

1 个答案:

答案 0 :(得分:0)

似乎崩溃发生是因为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窗口中的显示方式(活动gl上下文)。然后,评论glutCreateWindow(b"Glut Window")并再次运行,这样您就会看到seg故障崩溃将会重新出现。

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

不过,生成一个球体根本不是hard,值得你试一试:)