调用 glutWireSphere() 时 PyOpenGL 访问冲突读取 [英] PyOpenGL Access Violation Reading when calling glutWireSphere()

查看:28
本文介绍了调用 glutWireSphere() 时 PyOpenGL 访问冲突读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Python3.5.2

应用程序的目的是使用QGLWidget 类设置一个窗口,并使用glutWireSphere 函数绘制一个球体.该代码在我的 Ubuntu Linux 16.04 LTS 笔记本电脑上运行良好,但它在我的 Windows 7 台式机上崩溃并出现 OSError: exception: access conflict reading 0x000000000000000C1 inglutWireSphere 行.如果我注释掉这一行,程序将正常执行.我尝试了一个不同的代码示例(下面的示例),它演示了如何使用 glut 绘制一个球体,它没有被压碎,但它使用 glut 管理窗口.

The purpose of the application is to setup a window with QGLWidget class and draw a sphere using glutWireSphere function. The code works fine on my Ubuntu Linux 16.04 LTS laptop but it crashes on my Windows 7 desktop with OSError: exception: access violation reading 0x00000000000000C1 in the line of glutWireSphere. If I comment out this line, the program executes normally. I tried a different code example (sample below) that demonstrates how to draw a sphere with glut and it did not crushed, but it manages the windowing with 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,我会收到相同的错误,但地址不同.我在网上发现的所有访问冲突错误都是特定于应用程序的,它们主要与某些函数中的错误输入类型有关.由于我的代码中的函数没有太多参数,或者我还没有注意到一些东西,因此在我的应用程序中没有太多的空间可以犯这样的错误.

If i try to draw something else, for example glutSolidSphere I get the same error but on a different address. All access violation errors I have found online are application specific and they are mostly related to wrong input type in some function. There is not much room for such a mistake in my application since functions in my code do not take many arguments, or there is something that I have not noticed yet.

对于我的 Windows 7 桌面系统,我从官方网站下载了 Python 3.5.2,我使用 pip<安装了 PyQt5/code> 和 PyOpenGL 通过 非官方 Windows 二进制文件的 Python 扩展包根据这些说明

For my Windows 7 desktop system I downloaded Python 3.5.2 from the official website, I installed PyQt5 using pip and PyOpenGL through the Unofficial Windows Binaries for Python Extension Packages according to these instructions

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

I thought it was something related to problems in the freeglut library but it works on a different example. I guess it has something to do with how I initialize freeglut in my application, or it is related to PyQT5

问题

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

How can I track the problem and solve it without moving to different architecture for my application?

推荐答案

看起来崩溃是因为 glutWireSphere 要求你先调用 glutCreateWindow,例如查看这个小片段:

It seems the crash occurs because glutWireSphere requires you to call first glutCreateWindow, check this little snippet for example:

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") 并再次运行它,所以你会看到段错误崩溃会再次出现.

You can see how the sphere will appear in the pyqt window (active gl context). Then, comment glutCreateWindow(b"Glut Window") and run it again, so you'll see the seg fault crash will appear back.

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

My suggestion? I wouldn't rely on glut geometric function when not using Glut as the opengl window management system.

顺便说一句,生成一个球体一点也不困难值得你试一试:)

Btw, generating a sphere isn't hard at all and is worth you give it a shot :)

这篇关于调用 glutWireSphere() 时 PyOpenGL 访问冲突读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆