人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

ティーポット

立方体の描画(2008/8/31)では、四角形プリミティブを6枚使って自分で立方体を作ったわけですが、3次元オブジェクトを作るコマンドがあらかじめ用意されています。今回はそれを使って3次元オブジェクトを描画してみます。サンプルは有名なティーポットと呼ばれる3次元オブジェクトです。

teapot.py
f:id:aidiary:20100814104401p:plain
f:id:aidiary:20100814104402p:plain

サンプルスクリプト

#!/usr/bin/env python
#coding:utf-8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH)
    glutInitWindowSize(300, 300)  # ウィンドウサイズ
    glutInitWindowPosition(100, 100)  # ウィンドウ位置
    glutCreateWindow("ティーポット")  # ウィンドウを表示
    glutDisplayFunc(display)  # 描画コールバック関数を登録
    glutReshapeFunc(reshape)  # リサイズコールバック関数の登録
    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()
    gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)  # 投影変換

def display():
    """描画処理"""
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    # 視野変換:カメラの位置と方向のセット
    gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    
    # ティーポットを描画
    glColor3f(1.0, 0.0, 0.0)
    glutSolidTeapot(1.0)
#    glutWireTeapot(1.0)
    glFlush()  # OpenGLコマンドの強制実行

def reshape(width, height):
    """画面サイズの変更時に呼び出されるコールバック関数"""
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)

if __name__ == "__main__":
    main()

3次元オブジェクトの描画

サンプルスクリプトを見ていただければわかるようにglutの関数を使うといろんな3次元オブジェクトを描画できます。glBegin()、glVertex3f()などは使いません。基本的にソリッド(塗りつぶす)とワイヤー(ポリゴンの線のみ)の2種類があります。

サンプルにあるようにティーポットはglutSolidTeapot()で描画します。ワイヤーにしたければglutWireTeapot()を使います。どちらも引数はティーポットのサイズです。3次元オブジェクトは原点に作成されるのでカメラの位置を原点から(0,0,5)に移動しています。そうしないとカメラがオブジェクトの中に入ってしまいオブジェクトが見えませんね。カメラの移動は立方体の描画(2008/8/31)を参照してください。

ティーポットの他にもいろいろ描画できます。前回作った立方体はglutSolidCube()またはglutWireCube()です。これも引数は立方体のサイズです。

    # 立方体を描画
    glColor3f(1.0, 1.0, 0.0)
    glutWireCube(2.0)

f:id:aidiary:20100814104403p:plain

球は、glutSolidSphere()またはglutWireSphere()です。第1引数は半径、第2引数は経線の分割数、第3引数は緯線の分割数です。分割数が多いほど滑らかな球になります。分割数を小さくするとでこぼこした球になります。

    # 球を描画
    glColor3f(0.0, 0.0, 1.0)
    glutSolidSphere(1.0, 30, 30)  # ソリッド
    glutWireSphere(1.0, 30, 30)  # ワイヤー

f:id:aidiary:20100814104404p:plain
f:id:aidiary:20100814104405p:plain

ここで紹介した以外にも円柱、円錐、トーラスなどいろいろあります。ティーポットの画像を見るとわかるように何かのっぺりしていて3次元っぽくないですよね。これは、あとでマテリアルや照明をセットすると見違えるようになります。