2008/05/08

real meening of gluLookAt

この2日ほどカメラ座標の移動に取り組んでいたのですが、やっと分かりました。OpenGLはあくまでもMODELVIEW行列を設定してから何か絵を描くと、MODELVIEW行列で指定した位置、方向、大きさでモデルが描画されるというだけのAPIなのです。これが、オブジェクト指向や、データベースや、オブジェクトの絶対座標とカメラの移動などに慣れている人には大きな関門になるのです。本をよく読むと、次のようなことが書いてはあるのですが、なかなか理解できませんでした。
・カメラは動かない。常に図形側を全部動かす。
・gluLookAt関数はカメラの移動であるが、実際にはカメラの移動の逆行列をセットしているだけ。
・glLoadIdentity()を実行するとgluLookAtでセットされた行列もリセットされる。カメラは元の位置に戻る。
・glLoadIdentity()実行後に元のカメラ位置で描画するには、再度gluLookAtを実行する。
・データベースはなく、画面に書いているだけである。再描画をすると全部書き直すだけである。
・データベース構築はアプリケーションの責任

I spent whole two two days to understand gluLookAt() command. This just set inversed matrix of MODELVIEW. This simulate camera movement, but it is not a real camera movement. This is very difficult to understand for person who is using Object oriented, database, camera movement with world coordinate system. There are no actual camera movement, no world coordinate system, no database in OpenGL API. It just draw pictures on screen using fixed camera and MODELVIEW matrix. Books said as follows which was really difficult for me to understand.
- Camera position is fixed. We always move all drawing objects which is MODELVIEW.
- gluLookAt simulate camera movement. But, it just set inverse matrix of MODELVIEW.
- glLoadIdentity() reset matrix set by gluLookAt(). glLoadIdentity() resets camera movement.
- After glLoadIdentity(), use the same gluLookAt() to draw something from the camera positon.
- OpenGL doesn't handle database onject. It just draw something on screen.
- Database sould be done by application outside OpenGL.

このサンプルでは、キーボードを押して、異なる図形に異なるカメラアングルを与えることができます。
The following example moves two different cameras for different group of objects.

Please push the following keys to see what happens.
h
j
k
u
m
i
n
a
d
w
x
e
z
v
b


#movey.py

import sys
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
xx=yy=zz=x1=y1=z1=0.0
fov=30.0

def display():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)

glLoadIdentity()
gluLookAt(20.0, 20.0, 20.0, x1, y1, z1, 0.0, 1.0, 0.0)
glColor3f(0.0, 1.0, 0.0)
glutWireCone(1.0,1.0,12,12)
glTranslatef(0.0, 0.0, -5.0)
glutWireCone(1.0,1.0,12,12)
glTranslatef(0.0, 0.0, -5.0)
glutWireCone(1.0,1.0,12,12)

glLoadIdentity()
gluLookAt(20.0, 20.0, 20.0, xx, yy, zz, 0.0, 1.0, 0.0)
glColor3f(1.0, 1.0, 0.0)
glTranslatef(0.0, 0.0, 5.0)
glutWireCone(1.0,1.0,12,12)

glLoadIdentity()
gluLookAt(20.0, 20.0, 20.0, xx, yy, zz, 0.0, 1.0, 0.0)
glColor3f(0.0, 1.0, 1.0)
glTranslatef(0.0, 0.0, 8.0)
glRotatef(-90, 1.0, 0.0, 0.0)
glutWireCone(1.0,1.0,12,12)

glFlush()

def mykey(key, x, y):
global xx, yy, zz, x1, y1, z1, fov
if key=='k': # +x
xx = xx + 1.0
print "xx=", xx
elif key=='h': # -x
xx = xx - 1.0
print "xx=", xx
elif key=='u': #+y
yy = yy + 1.0
print "yy=", yy
elif key=='m': #-y
yy = yy - 1.0
print "yy=", yy
elif key=='i': #-z
zz = zz - 1.0
print "zz=", zz
elif key=='n': #+z
zz = zz + 1.0
print "zz=", zz

elif key=='d': # +x1
x1 = x1 + 1.0
print "x1=", x1
elif key=='a': # -x1
x1 = x1 - 1.0
print "x1=", x1
elif key=='w': #+y1
y1 = y1 + 1.0
print "y1=", y1
elif key=='x': #-y1
y1 = y1 - 1.0
print "y1=", y1
elif key=='e': #-z1
z1 = z1 - 1.0
print "z1=", z1
elif key=='z': #+z1
z1 = z1 + 1.0
print "z1=", z1

elif key=='j': # center camera to origin 0,0
xx=yy=zz=x1=y1=z1=0.0
fov=30
print "reset x,y,z to (0,0)"
elif key=='v': # +fov
fov = fov + 5
elif key=='b': #-fov
fov = fov - 5

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(fov, 1.0, 0.0, 100.0)

glutPostRedisplay()

glutInit( sys.argv )
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB )
glutInitWindowSize( 500, 500 )
glutInitWindowPosition(0,0)
glutCreateWindow( 'model' )
glutDisplayFunc( display )
glutKeyboardFunc(mykey)

glClearColor(0.0, 0.0, 0.0, 0.0)

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(30, 1.0, 0.0, 100.0)

glutMainLoop()

0 件のコメント: