[pukiwiki]
秋なので(?) 3DCG描画ライブラリのOpenGLで遊んでみました
http://boxheadroom.com/wp/wp-content/uploads/2009/10/bounds.gif
[[Pyglet:http://www.pyglet.org/]] と PyOpenGL どちらを使ったらいいか判らなかったので、まずはPyOpenGLにチャレンジ
[/pukiwiki]
[pukiwiki]
*参考にしたページ
-[[PyOpenGL 公式:http://pyopengl.sourceforge.net/]]
適当なアーカイブをもらってきて setup.py install
-[[Pythonでゲーム作りますが何か?:http://pygame.skr.jp/index.php?FrontPage#iae4aa71]]
まずは、こちらのチュートリアル (OpenGL関連だけ) を ひと通り コピペして動かしてみると、Cで書かれたサンプルコードをPythonに移植できる程度の実力がついてるはず。
(というか、関数名はCと同じなので)
-[[GLUTによる「手抜き」OpenGL入門:http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html]]
次は こちらのコードを一通り Pythonに移植してみました (といっても、ごくわずかの書き換えですが)
-[[OpenGLプログラミングコース ( (株) エクサ):http://www.exa-corp.co.jp/solutions/common/ubiquitous/ubiquitous-solution/]]
これを読んでる途中
-[[pyglet プログラミングガイド:http://www.aida.k.u-tokyo.ac.jp/~saeki/pyglet/doc.ja/]]
こちらは、もう一つのOpenGLラッパー Pygletのドキュメントの翻訳。
[/pukiwiki]
勉強したところまでの復習を兼ねて、ワイヤーフレームの箱の中で点がバウンドするアニメーションプログラム。
実行環境は vista py2.5 (たぶん 他のOSでも動きます)
#!/usr/bin/env python #coding:utf-8 from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import sys import math,random W,H=300,300 cube_v=[ -1.0, -1.0, -1.0 , #A 0 1.0, -1.0, -1.0 , #B 1 1.0, 1.0, -1.0 , #C 2 -1.0, 1.0, -1.0 , #D 3 -1.0, -1.0, 1.0 , #E 4 1.0, -1.0, 1.0 , #F 5 1.0, 1.0, 1.0 , #G 6 -1.0, 1.0, 1.0 #H 7 ] cube_i=[ 0,1, 1,2, 2,3, 3,0, 0,4, 1,5, 2,6, 3,7, 4,5, 5,6, 6,7, 7,4 ] cube_i2=[ 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 7, 0, 1, 5, 4, 2, 1, 5, 6, 3, 0, 4, 7 ] def main(): glutInit(sys.argv) glutInitDisplayMode(GLUT_RGB |GLUT_DOUBLE | GLUT_DEPTH) glutInitWindowSize(W,H) # ウィンドウサイズ glutInitWindowPosition(100, 100) # ウィンドウ位置 glutCreateWindow(u"立方体の描画") # ウィンドウを表示 glutDisplayFunc(display) # 描画コールバック関数を登録 glutReshapeFunc(reshape) # リサイズコールバック関数の登録 glutIdleFunc(idle) init(300, 300) glutMainLoop() def init(width, height): """初期化""" glClearColor(0.0, 0.0, 0.0, 1.0) glEnable(GL_DEPTH_TEST) # 隠面消去を有効に glMatrixMode(GL_PROJECTION) glLoadIdentity() a=float(width)/float(height) #glOrtho( -2*a, 2*a, -2, 2, 0.1, 10) #視界を正射影で設定 gluPerspective(45.0, float(width)/float(height), 0.1, 100.0) # 投影変換 glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(3.0, 2.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # 右斜め上から撮影 point_init() angle=0 def idle(): """アイドル時に呼ばれるコールバック関数""" global angle angle+= 0.05 if angle>360.:angle-=360. glutPostRedisplay() # 再描画 idx=0 def display(): """描画処理""" global idx glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT) glPushMatrix() # 視野変換:カメラの位置と方向のセット #gluLookAt(0, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # 右斜め上から撮影 #gluLookAt(3.0, 2.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # 右斜め上から撮影 #gluLookAt(-4.0, 0, -4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # 左斜め後ろから撮影 glRotate(angle,0,1,0) cube() points() glPopMatrix() glutSwapBuffers() # OpenGLコマンドの強制実行 def reshape(width, height): """画面サイズの変更時に呼び出されるコールバック関数""" glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() a=float(width)/float(height) #glOrtho( -3, 3, -3, 3, 0.1, 10) #視界を正射影で設定 #glOrtho( -2*a, 2*a, -2, 2, 0.1, 10) #視界を正射影で設定 gluPerspective(45.0, float(width)/float(height), 0.1, 100.0) # 投影変換 #gluPerspective(45.0, float(width)/float(height), 0.1, 100.0) glMatrixMode(GL_MODELVIEW) def cube(): glEnableClientState(GL_VERTEX_ARRAY) glVertexPointer(3, GL_FLOAT, 0,cube_v ) glColor3d(1.0,1.0,1.0) glDrawElements(GL_LINES, 24, GL_UNSIGNED_BYTE,cube_i) #glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, cube_i2); glDisableClientState(GL_VERTEX_ARRAY); point_max=16 point_v=[] point_d=[] point_i=range(point_max) def point_init(): d=0.005 for i in xrange(point_max): x,y,z=[ 2.0*(random.random()-0.5) for j in xrange(3)] w=math.sqrt(x**2.+y**2.+z**2.) x/=w; y/=w; z/=w point_v.extend([x,y,z]) point_d.extend([x*d,y*d,z*d]) print len(point_d)==len(point_v) point_c=[ 1. , 1. , 1. ] *point_max def points(): for i in xrange(point_max*3): v=point_v[i] if v <-1. : point_d[i]=abs(point_d[i]) point_v[i]+= point_d[i]*1.2 elif v > 1. : point_d[i]=-1.0*abs(point_d[i]) point_v[i]+= point_d[i]*1.2 else : point_v[i]+=point_d[i] glEnableClientState(GL_COLOR_ARRAY) glColorPointer(3,GL_FLOAT,0,point_c) glEnableClientState(GL_VERTEX_ARRAY) glVertexPointer(3, GL_FLOAT, 0,point_v ) glPointSize(6.) #glColor3d(1.0,1.0,1.0) glDrawElements(GL_POINTS, point_max, GL_UNSIGNED_BYTE,point_i) glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); if __name__ == "__main__": main()