在OSX上遇到PyOpenGL和PyQt5的问题

时间:2017-03-29 19:20:37

标签: python macos graphics pyqt5 pyopengl

我本学期开始介绍计算机图形学,目前正在使用PyOpenGL和PyQt5来探索重心坐标。我的同学使用Windows机器能够运行以下代码而没有开箱即用的问题,但OSX上的所有人都遇到了同样的问题。我希望那里的其他人有更多这种环境的经验,可能会想到我们如何解决这些问题;我们已经做了大量的谷歌搜索,没有结果。谢谢!

代码:


    import sys
    from array           import array
    from ctypes          import c_void_p
    from OpenGL.GL       import *
    from OpenGL.GLU      import *
    from PyQt5.QtGui     import QImage, qRgb
    from PyQt5.QtOpenGL  import QGLWidget
    from PyQt5.QtWidgets import QApplication
    from textwrap        import dedent


    # create a function that draws a triangle via software rasterization
    def softwareRasterization(width, height, vertices, colors):
        image = QImage(width, height, QImage.Format_RGB32)
        # TODO: compute the bounding box around the given vertices
        # TODO: compute the barycentric coordinates for each point in the box
        # TODO: color the points that are inside of the triangle
        if image.save("triangle.jpg", None, 100):
            print("Output triangle.jpg")
        else:
            print("Unable to save triangle.jpg")


    # extend QGLWidget to draw a triangle via hardware rasterization
    class HardwareRasterizationWidget(QGLWidget):

        def __init__(self, vertices, colors, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.vertices = array('f')
            # TODO: convert the input coordinate to normalized device coordinates
            self.colors = array('f', colors)


        def _sizeof(self, a):
            return a.itemsize * len(a)


        def initializeGL(self):

            verticesSize = self._sizeof(self.vertices)

            # create a new Vertex Array Object on the GPU which saves the attribute
            # layout of our vertices
            vao = glGenVertexArrays(1)
            glBindVertexArray(vao)

            # create a buffer on the GPU for position and color data
            dataBuffer = glGenBuffers(1)

            # upload the data to the GPU, storing it in the buffer we just created
            # TODO: upload the color data into the GPU buffer as well
            glBindBuffer(GL_ARRAY_BUFFER, dataBuffer)
            glBufferData(
                GL_ARRAY_BUFFER,
                verticesSize,
                None,
                GL_STATIC_DRAW
            )
            glBufferSubData(
                GL_ARRAY_BUFFER,
                0,
                verticesSize,
                self.vertices.tostring()
            )

            # load our vertex and fragment shaders into a program object on the GPU
            program = self.loadShaders()

            # bind the attribute "position" (defined in our vertex shader) to the
            # currently bound buffer object, which contains our position data
            # this information is stored in our vertex array object
            position = glGetAttribLocation(program, 'position')
            glEnableVertexAttribArray(position)
            glVertexAttribPointer(
                position,
                3,
                GL_FLOAT,
                GL_FALSE,
                0,
                c_void_p(0)
            )

            # TODO: bind the attribute "color" to the buffer object


        def loadShaders(self):
            # create a GL Program Object
            program = glCreateProgram()

            # vertex shader
            # TODO: add a color input and color output
            vs_source = dedent("""
                #version 330
                in vec3 position;
                void main()
                {
                   gl_Position = vec4(position, 1.0);
                }\
            """)
            vs = glCreateShader(GL_VERTEX_SHADER)
            glShaderSource(vs, vs_source)
            glCompileShader(vs)
            glAttachShader(program, vs)
            if glGetShaderiv(vs, GL_COMPILE_STATUS) != GL_TRUE:
                raise RuntimeError(glGetShaderInfoLog(vs))

            # fragment shader
            # TODO: add a color input with the same name as the vertex output
            fs_source = dedent("""
                #version 330
                void main()
                {
                   gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
                }\
            """)
            fs = glCreateShader(GL_FRAGMENT_SHADER)
            glShaderSource(fs, fs_source)
            glCompileShader(fs)
            glAttachShader(program, fs)
            if glGetShaderiv(fs, GL_COMPILE_STATUS) != GL_TRUE:
                raise RuntimeError(glGetShaderInfoLog(fs))

            # use the program
            glLinkProgram(program)
            glUseProgram(program)

            return program


        def paintGL(self):
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            glDrawArrays(GL_TRIANGLES, 0, 3)


        def resizeGL(self, width, height):
            glViewport(0, 0, width, height)



    if __name__ == "__main__":

        width = 640
        height = 480

        # TODO: prompt the user for 3 points and colors separated by spaces
        # TODO: validate input and parse into the vertices and colors lists

        vertices = [
            50, 50, 0,    # vertice 1
            600, 20, 0,   # vertice 2
            300, 400, 0   # vertice 3
        ]
        colors = [
            1, 0, 0,  # color 1
            0, 1, 0,  # color 2
            0, 0, 1   # color 3
        ]

        softwareRasterization(width, height, vertices, colors)

        app = QApplication(sys.argv)
        w = HardwareRasterizationWidget(vertices, colors)
        pRatio = w.devicePixelRatio()
        w.resize(width/pRatio, height/pRatio)
        w.show()

        sys.exit(app.exec_())

错误:


Traceback (most recent call last):
File "/Users/JesseRichmond/vEnvPyCharm/lib/python3.5/site-packages/OpenGL/latebind.py", line 41, in __call__
return self._finalCall( *args, **named )
TypeError: 'NoneType' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/JesseRichmond/Desktop/Spring 2017 Academics/Projects/310/rasterization.py", line 45, in initializeGL
vao = glGenVertexArrays(1)
File "/Users/JesseRichmond/vEnvPyCharm/lib/python3.5/site-packages/OpenGL/latebind.py", line 45, in __call__
return self._finalCall( *args, **named )
File "/Users/JesseRichmond/vEnvPyCharm/lib/python3.5/site-packages/OpenGL/wrapper.py", line 657, in wrapperCall
result = wrappedOperation( *cArguments )
File "/Users/JesseRichmond/vEnvPyCharm/lib/python3.5/site-packages/OpenGL/platform/baseplatform.py", line 407, in __call__
self.__name__, self.__name__,
OpenGL.error.NullFunctionError: Attempt to call an undefined function glGenVertexArrays, check for bool(glGenVertexArrays) before calling

0 个答案:

没有答案