基于这个教程
http://www.arcsynthesis.org/gltut/Basics/Tut02%20Vertex%20Attributes.html
Required packages:
- pyopengl
- numpy
pyopengl with freeglut.
To make freeglut works you need to download a pre-compiled binary from http://www.transmissionzero.co.uk/software/freeglut-devel/ or compile it from source http://freeglut.sourceforge.net/.
Copy the freeglut.dll or freeglut64.dll to site-packages/OpenGL/DLLS/
你需要去下载编译好的freeglut,下载地址 http://www.transmissionzero.co.uk/software/freeglut-devel/,把freeglut.dll 或 freeglut64.dll放到site-packages/OpenGL/DLLS/里
# -------------------------------------------------------------------------------- # Copyright (c) 2013 Mack Stone. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # -------------------------------------------------------------------------------- """ Modern OpenGL with python. render a color triangle with pyopengl using freeglut. @author: Mack Stone """ import ctypes import numpy from OpenGL.GL import * from OpenGL.GL import shaders from OpenGL.GLUT import * VERTEX_SHADER = """ #version 330 layout (location=0) in vec4 position; layout (location=1) in vec4 color; smooth out vec4 theColor; void main() { gl_Position = position; theColor = color; } """ FRAGMENT_SHADER = """ #version 330 smooth in vec4 theColor; out vec4 outputColor; void main() { outputColor = theColor; } """ shaderProgram = None VAO = None def initialize(): global VERTEX_SHADER global FRAGMENT_SHADER global shaderProgram global VAO # compile shaders and program vertexShader = shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER) fragmentShader = shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER) shaderProgram = shaders.compileProgram(vertexShader, fragmentShader) # triangle position and color vertexData = numpy.array([0.0, 0.5, 0.0, 1.0, 0.5, -0.366, 0.0, 1.0, -0.5, -0.366, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, ], dtype=numpy.float32) # create VAO VAO = glGenVertexArrays(1) glBindVertexArray(VAO) # create VBO VBO = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, VBO) glBufferData(GL_ARRAY_BUFFER, vertexData.nbytes, vertexData, GL_STATIC_DRAW) # enable array and set up data glEnableVertexAttribArray(0) glEnableVertexAttribArray(1) glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, None) # the last parameter is a pointer # python donot have pointer, have to using ctypes glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(48)) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) def render(): global shaderProgram global VAO glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # active shader program glUseProgram(shaderProgram) glBindVertexArray(VAO) # draw triangle glDrawArrays(GL_TRIANGLES, 0, 3) glBindVertexArray(0) glUseProgram(0) glutSwapBuffers() def main(): # init freeglut glutInit([]) # make a window glutInitContextVersion(3, 3) glutInitContextFlags(GLUT_FORWARD_COMPATIBLE) glutInitContextProfile(GLUT_CORE_PROFILE) glutInitWindowSize(640, 480) glutCreateWindow("pyopengl with glut") initialize() glutDisplayFunc(render) glutMainLoop() if __name__ == '__main__': main()
pyopengl with glfw.
Get pyglfw from https://github.com/nightcracker/pyglfw
There was a glfw.dll included in pyglfw. I think it was a 32bit version. You can replace it to the 64bit version for using python 64bit. The pyglfw only support GLFW 2.x.x version. You can download it from http://sourceforge.net/projects/glfw/. I think it had a small bug that it only works with python2.7. It's easy to fix if you want to using python2.6.
安装pyglfw,下载地址 https://github.com/nightcracker/pyglfw。
它已经附带了一个glfw.dll,但这版本可能不是你想要或能用的,你可以直接替换成你需要的版本,但pyglfw只支持GLFW 2.x.x的版本,下载地址 http://sourceforge.net/projects/glfw/。它有个小bug,使得它只支持python2.7,这个bug不难修复。
# -------------------------------------------------------------------------------- # Copyright (c) 2013 Mack Stone. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # -------------------------------------------------------------------------------- """ Modern OpenGL with python. render a color triangle with pyopengl using glfw. @author: Mack Stone """ import ctypes import numpy from OpenGL.GL import * from OpenGL.GL import shaders import glfw VERTEX_SHADER = """ #version 330 layout (location=0) in vec4 position; layout (location=1) in vec4 color; smooth out vec4 theColor; void main() { gl_Position = position; theColor = color; } """ FRAGMENT_SHADER = """ #version 330 smooth in vec4 theColor; out vec4 outputColor; void main() { outputColor = theColor; } """ shaderProgram = None VAO = None def initialize(): global VERTEX_SHADER global FRAGMENT_SHADER global shaderProgram global VAO # compile shaders and program vertexShader = shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER) fragmentShader = shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER) shaderProgram = shaders.compileProgram(vertexShader, fragmentShader) # triangle position and color vertexData = numpy.array([0.0, 0.5, 0.0, 1.0, 0.5, -0.366, 0.0, 1.0, -0.5, -0.366, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, ], dtype=numpy.float32) # create VAO VAO = glGenVertexArrays(1) glBindVertexArray(VAO) # create VBO VBO = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, VBO) glBufferData(GL_ARRAY_BUFFER, vertexData.nbytes, vertexData, GL_STATIC_DRAW) # enable array and set up data glEnableVertexAttribArray(0) glEnableVertexAttribArray(1) glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, None) # the last parameter is a pointer # python donot have pointer, have to using ctypes glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(48)) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) def render(): global shaderProgram global VAO glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # active shader program glUseProgram(shaderProgram) glBindVertexArray(VAO) # draw triangle glDrawArrays(GL_TRIANGLES, 0, 3) glBindVertexArray(0) glUseProgram(0) glfw.SwapBuffers() def main(): # init glfw glfw.Init() # make a window glfw.OpenWindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.OpenWindowHint(glfw.OPENGL_VERSION_MAJOR, 3) glfw.OpenWindowHint(glfw.OPENGL_VERSION_MINOR, 3) glfw.OpenWindow(640, 480, 8, 8, 8, 8, 0, 0, glfw.WINDOW) initialize() while glfw.GetWindowParam(glfw.OPENED): render() glfw.Terminate() if __name__ == '__main__': main()
pyopengl with PySide/PyQt.
Install PySide/PyQt4. I only tested with PySide. It should works fine with PyQt4.
安装PySide或PyQt4。我只测试了PySide。
# -------------------------------------------------------------------------------- # Copyright (c) 2013 Mack Stone. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # -------------------------------------------------------------------------------- """ Modern OpenGL with python. render a color triangle with pyopengl using PySide/PyQt4. @author: Mack Stone """ import ctypes import numpy from OpenGL.GL import * from OpenGL.GL import shaders from PySide import QtGui, QtOpenGL #from PyQt4 import QtGui, QtOpenGL VERTEX_SHADER = """ #version 330 layout (location=0) in vec4 position; layout (location=1) in vec4 color; smooth out vec4 theColor; void main() { gl_Position = position; theColor = color; } """ FRAGMENT_SHADER = """ #version 330 smooth in vec4 theColor; out vec4 outputColor; void main() { outputColor = theColor; } """ class MyWidget(QtOpenGL.QGLWidget): def initializeGL(self): glViewport(0, 0, self.width(), self.height()) # compile shaders and program vertexShader = shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER) fragmentShader = shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER) self.shaderProgram = shaders.compileProgram(vertexShader, fragmentShader) # triangle position and color vertexData = numpy.array([0.0, 0.5, 0.0, 1.0, 0.5, -0.366, 0.0, 1.0, -0.5, -0.366, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, ], dtype=numpy.float32) # create VAO self.VAO = glGenVertexArrays(1) glBindVertexArray(self.VAO) # create VBO VBO = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, VBO) glBufferData(GL_ARRAY_BUFFER, vertexData.nbytes, vertexData, GL_STATIC_DRAW) # enable array and set up data glEnableVertexAttribArray(0) glEnableVertexAttribArray(1) glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, None) # the last parameter is a pointer # python donot have pointer, have to using ctypes glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(48)) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) def paintGL(self): glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # active shader program glUseProgram(self.shaderProgram) glBindVertexArray(self.VAO) # draw triangle glDrawArrays(GL_TRIANGLES, 0, 3) glBindVertexArray(0) glUseProgram(0) def main(): import sys app = QtGui.QApplication(sys.argv) glformat = QtOpenGL.QGLFormat() glformat.setVersion(3, 3) glformat.setProfile(QtOpenGL.QGLFormat.CoreProfile) w = MyWidget(glformat) w.resize(640, 480) w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()