OpenGL覚え書き1 ウインドウ

OpenGLの使い方についてまとめてみたいと思います。サンプルコードはPyOpenGLで作成しています。

OpenGL

プラットフォーム非依存のグラフィクス用インターフェース。関数の接頭辞はgl

GLU

OpenGLのいくつかの関数を利用して有用な機能としてまとめたライブラリ。関数の接頭辞はglu

glutとは

OpenGLを利用して描画するためのマルチプラットフォームなウインドウシステムのことです。OpenGLだけではウインドウを開く、マウスやキーボードのイベント処理を行うことはできないのでglutを利用します。glutのコマンドはglutという接頭辞で始まる関数になっています。

OpenGLでウインドウを開く

以下のようなウインドウに関する関数群を利用します。

glutInit glut初期化
glutInitDisplayMode 表示モード設定
glutInitWindowSize ウインドウサイズ
glutInitWindowPosition ウインドウの初期位置
glutCreateWindow ウインドウ作成
glutDisplayFunc 描画関数の呼び出し
glutMainLoop メインループ
def display():
    pass

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(400, 300)
    glutInitWindowPosition(0, 0)

    glutCreateWindow("PyOpenGL")
    glutDisplayFunc(display)
    glutMainLoop()

main()

背景色や透視変換の座標設定などCGを描画する前に行うための初期設定をinit関数などにまとめておくと便利です。

def init():
    glClearColor(0.0,0.0,0.0,0.0) #背景色を黒で初期化

def display():
    glClear(GL_COLOR_BUFFER_BIT)
    #三角形を描画
    glBegin(GL_TRIANGLE_STRIP)
    glVertex2d(0.,0.)
    glVertex2d(0.7,0.7)
    glVertex2d(0.,0.7)
    glEnd()

    glFlush()

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH)
    glutInitWindowSize(400, 300)
    glutInitWindowPosition(0, 0)
    glutCreateWindow("PyOpenGL")
    init()
    glutDisplayFunc(display)
    glutMainLoop()

main()

ダブルバッファ

アニメーションなどでちらつきを抑えるために、2つのバッファを交互に表示される方法をダブルバッファと呼びます。ダブルバッファで表示をするには表示モードに GLUT_DOUBLE を追加して、描画部分でglFlushの代わりにglutSwapBuffersを呼び出します。

def init():
    glClearColor(0.0,0.0,0.0,0.0)

def display():
    glClear(GL_COLOR_BUFFER_BIT)


    glutSwapBuffers()

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(400, 300)
    glutInitWindowPosition(0, 0)
    glutCreateWindow("PyOpenGL")
    init()
    glutDisplayFunc(display)
    glutMainLoop()

main()

イベント処理

イベントハンドラを設定するための関数一覧です。

glutReshapeFunc ウインドウリサイズ時
glutMouseFunc マウスボタンon/off時
glutKeyBoardFunc キーボードon/off時
glutMotionFunc ドラッグ時
glutIdleFunc イベントなしの時

イベントハンドラを自分で定義して引数に関数名を渡します。

def init():
    glClearColor(0.0,0.0,0.0,0.0)

def draw():
    glClear(GL_COLOR_BUFFER_BIT)
    
    glBegin(GL_TRIANGLE_STRIP)
    glVertex2d(0.,0.)
    glVertex2d(0.7,0.7)
    glVertex2d(0.,0.7)
    glEnd()
    
    glutSwapBuffers()
def resize(width, height):
    print width,height
def keyPressed(key,x,y):
    print key,x,y
def mousePressed(button,state,x,y):
    print button,state,x,y
def mouseDragged(x,y):
    print x, y
def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(400, 300)
    glutInitWindowPosition(0, 0)
    glutCreateWindow("PyOpenGL")
    glutDisplayFunc(draw)
     
    glutIdleFunc(draw)
    glutReshapeFunc(resize)
    glutKeyboardFunc(keyPressed)
    glutMouseFunc(mousePressed)
    glutMotionFunc(mouseDragged)
    init()

    glutMainLoop()

main()

glutIdleFuncの引数にNULLを入れると関数の呼び出しを解除することができます。glutIdleFuncは常に実行されるので、例えばマウスハンドラの中でだけ利用するなど無駄な処理を省くために呼び出すタイミングを考える必要があります。