[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()