很早就一直想学Python,看到一些书都有介绍,不管是做为游戏的脚本语言,还是做为开发项目的主要语言都有提及(最主要的CUDA都开始支持Python,CUDA后面一定要学),做为先熟悉一下Python,本文用PyOpenGL实现一些基本的显示效果,一个网格,一个球体,加一个能切换第一与第三人称的摄像机。
PyOpenGL是一个用Python实现的多平台的OpenGL的API,为了学习Python与PyOpengl,本文也是用的Python,而不是.net版本的IronPython.
先看一下,相关环境的搭建:
首先我们需要下载Python: http://www.python.org/getit/
然后是PyOpenGL库:https://pypi.python.org/pypi/PyOpenGL
和PyOpenGL库常连在一起用的二个库,一个库numpy,提供常用的科学计算包含矩阵运算,数组转换与序列化,还有一个是3D常用的图片处理库:Python Imaging Library (PIL)。
numpy下载:http://sourceforge.net/projects/numpy/files/ 简介:http://sebug.net/paper/books/scipydoc/numpy_intro.html
Python Imaging Library (PIL)下载:http://www.pythonware.com/products/pil/
当上面环境安装完成后,我们先来实现一个基本的球体VBO实现,代码请参考前面的WebGL 利用FBO完成立方体贴图中的球的代码:
1 #common.py 2 import math 3 from OpenGL.GL import * 4 from OpenGL.arrays import vbo 5 from OpenGL.GLU import * 6 from OpenGL.GLUT import * 7 #import OpenGL.GLUT as glut 8 import numpy as ny 9 #Python Imaging Library (PIL) 10 class common: 11 bCreate = False 12 13 #球的实现 14 class sphere(common): 15 def __init__(this,rigns,segments,radius): 16 this.rigns = rigns 17 this.segments = segments 18 this.radius = radius 19 def createVAO(this): 20 vdata = [] 21 vindex = [] 22 for y in range(this.rigns): 23 phi = (float(y) / (this.rigns - 1)) * math.pi 24 for x in range(this.segments): 25 theta = (float(x) / float(this.segments - 1)) * 2 * math.pi 26 vdata.append(this.radius * math.sin(phi) * math.cos(theta)) 27 vdata.append(this.radius * math.cos(phi)) 28 vdata.append(this.radius * math.sin(phi) * math.sin(theta)) 29 vdata.append(math.sin(phi) * math.cos(theta)) 30 vdata.append(math.cos(phi)) 31 vdata.append(math.sin(phi) * math.sin(theta)) 32 for y in range(this.rigns - 1): 33 for x in range(this.segments - 1): 34 vindex.append((y + 0) * this.segments + x) 35 vindex.append((y + 1) * this.segments + x) 36 vindex.append((y + 1) * this.segments + x + 1) 37 vindex.append((y + 1) * this.segments + x + 1) 38 vindex.append((y + 0) * this.segments + x + 1) 39 vindex.append((y + 0) * this.segments + x) 40 #this.vboID = glGenBuffers(1) 41 #glBindBuffer(GL_ARRAY_BUFFER,this.vboID) 42 #glBufferData (GL_ARRAY_BUFFER, len(vdata)*4, vdata, GL_STATIC_DRAW) 43 #this.eboID = glGenBuffers(1) 44 #glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this.eboID) 45 #glBufferData (GL_ELEMENT_ARRAY_BUFFER, len(vIndex)*4, vIndex, 46 #GL_STATIC_DRAW) 47 this.vbo = vbo.VBO(ny.array(vdata,'f')) 48 this.ebo = vbo.VBO(ny.array(vindex,'H'),target = GL_ELEMENT_ARRAY_BUFFER) 49 this.vboLength = this.segments * this.rigns 50 this.eboLength = len(vindex) 51 this.bCreate = True 52 def drawShader(this,vi,ni,ei): 53 if this.bCreate == False: 54 this.createVAO() 55 #glBindBuffer(GL_ARRAY_BUFFER,this.vboID) 56 #glVertexAttribPointer(vi,3,GL_FLOAT,False,24,0) 57 #glEnableVertexAttribArray(vi) 58 #glVertexAttribPointer(ni,3,GL_FLOAT,False,24,12) 59 #glEnableVertexAttribArray(ni) 60 #glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this.eboID) 61 #glDrawElements(GL_TRIANGLES,this.eboLength,GL_UNSIGNED_INT,0) 62 this.vbo.bind() 63 def draw(this): 64 if this.bCreate == False: 65 this.createVAO() 66 #glBindBuffer(GL_ARRAY_BUFFER,this.vboID) 67 #glInterleavedArrays(GL_N3F_V3F,0,None) 68 #glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this.eboID) 69 #glDrawElements(GL_TRIANGLES,this.eboLength,GL_UNSIGNED_INT,None) 70 this.vbo.bind() 71 glInterleavedArrays(GL_N3F_V3F,0,None) 72 this.ebo.bind() 73 glDrawElements(GL_TRIANGLES,this.eboLength,GL_UNSIGNED_SHORT,None)