PyOpenGL勉強中

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

コメントを残す

メールアドレスが公開されることはありません。