描画した図形を回転させる

PythonOpenGLライブラリで、図形の描画を行う練習を行っている。とりあえずは、以下のプロセスに沿って、いろいろと試して進めていく。

  1. なんでもいいので3次元の図形を描画(practice1.py)  <--今、ここ。
  2. 描いた図形をマウスで回転できるようにする
  3. 複数の六面体を描画
  4. 描いた六面体をマウスで回転できるようにする
  5. より多くの六面体を描画する

マウスで回転することを念頭に置いて、以下のコード(practice1.py)を書く。

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys

ESCAPE = '\033'  #10進数にすると27
lastx = x = 30
lasty = y = 30

def initialize():
    glClearDepth(1.0)  #デプスバッファをクリアするときの値
    glEnable(GL_DEPTH_TEST) #デプスバッファテストによる隠面消去をオンにする
    glClearColor(0.0, 0.5, 0.0, 0.0) #画面をクリアする色の指定
    glShadeModel(GL_SMOOTH) #平面のポリゴンを曲面に見せる処理

    glMatrixMode(GL_PROJECTION)   #投影変換マトリックスを操作対象とする
    glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0) #ビューボリュームを指定する
    glMatrixMode(GL_MODELVIEW)  #モデルビュー変換マトリックスを操作対象とする

    glTranslatef(0.0, 0.0, -2.0) #物体を移動
    glRotatef(y, 1.0, 0.0, 0.0)  #物体を回転
    glRotatef(x, 0.0, 1.0, 0.0)
    glEnable(GL_LIGHTING)     #照明モデルを有効化
    glEnable(GL_LIGHT0)      #使用する光源
    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE)
    glEnable(GL_COLOR_MATERIAL)

def mouseMotion(x, y):
    global lastx, lasty
    lastx = x
    lasty = y
    glutPostRedisplay()  #描画イベントを発生させる

def display():
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) #画面を指定した色でクリアする
                  # GL_COLOR_BUFFER_BIT:
                                    # GL_DEPTH_BUFFER_BIT:
    glPushMatrix()        #行列スタック

    glBegin(GL_QUADS)       #四角形ポリゴンを描画する。 glEndまで。
    glNormal3f( 0.0, 0.0, 1.0)  #法線の指定(以下の頂点に割当てる)
    glVertex3f( 0.5, 0.5, 0.5)  #頂点座標の指定
    glVertex3f(-0.5, 0.5, 0.5)
    glVertex3f(-0.5,-0.5, 0.5)
    glVertex3f( 0.5,-0.5, 0.5)

    glNormal3f( 0.0, 0.0,-1.0)
    glVertex3f(-0.5,-0.5,-0.5)
    glVertex3f(-0.5, 0.5,-0.5)
    glVertex3f( 0.5, 0.5,-0.5)
    glVertex3f( 0.5,-0.5,-0.5)

    glNormal3f( 0.0, 1.0, 0.0)
    glVertex3f( 0.5, 0.5, 0.5)
    glVertex3f( 0.5, 0.5,-0.5)
    glVertex3f(-0.5, 0.5,-0.5)
    glVertex3f(-0.5, 0.5, 0.5)

    glNormal3f( 0.0,-1.0, 0.0)
    glVertex3f(-0.5,-0.5,-0.5)
    glVertex3f( 0.5,-0.5,-0.5)
    glVertex3f( 0.5,-0.5, 0.5)
    glVertex3f(-0.5,-0.5, 0.5)

    glNormal3f( 1.0, 0.0, 0.0)
    glVertex3f( 0.5, 0.5, 0.5)
    glVertex3f( 0.5,-0.5, 0.5)
    glVertex3f( 0.5,-0.5,-0.5)
    glVertex3f( 0.5, 0.5,-0.5)

    glNormal3f(-1.0, 0.0, 0.0)
    glVertex3f(-0.5,-0.5,-0.5)
    glVertex3f(-0.5,-0.5, 0.5)
    glVertex3f(-0.5, 0.5, 0.5)
    glVertex3f(-0.5, 0.5,-0.5)
    glEnd()

    glPopMatrix()
    glutSwapBuffers()   #フロントバッファとバックバッファの入れ替え
    
def keyboard(*args):
    if args[0] == ESCAPE:  #ESCキー(コード27)
        sys.exit()       #プログラム終了

def reshape(w, h):
    pass

def main():
    glutInit(sys.argv)   #GLUTの初期化

    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ) #ウィンドウの表示モード
               # GLUT_DOUBLE: アニメーション
               # GLUT_RGB: RGBモード
               # GLUT_DEPTH: 隠面処理をする
    glutInitWindowPosition( 100, 100 ) #ウィンドウの位置
    glutInitWindowSize( 500, 400 ) #ウィンドウのサイズ
    glutCreateWindow( sys.argv[0] ) #引数をタイトルとしてウィンドウを開く

    glutDisplayFunc( display )      #描画イベントが発生したとき処理する関数
    glutKeyboardFunc( keyboard )  #キーボードイベントが発生したときのコールバック関数
    glutReshapeFunc( reshape )   #ウィンドウサイズが変更されたときのコールバック関数
    glutMotionFunc( mouseMotion )  #マウスが移動したときのコールバック関数

    initialize()

    glutMainLoop()         #イベント処理の無限ループ

print "Hit ESC key to quit."
main()

図形は描ける(下図)が、現状ではマウスで回転できない。