gluLookAt

lookat.png

gluPerspectiveを使うならgluLookAt(0,0,正,0,0,0,0,1,0);が正しい。

デフォルトではこうなってるらしい。

gluLookAt(0.0,0.0,0.0,0.0,0.0,-100.0,0.0,1.0,0.0);

カメラ原点 (0,0,0)
注視点 (0,0,-100)
アッパーベクトル (0,1,0)

カメラが原点にあって、
注視点は(0,0,-100)つまりz軸の負の方向を見下ろしている。
じゃあ、このカメラから見えるようにするには、z=負のところになにかおけばいいってことよね。
でも、だいたいはオブジェクトの中心が原点のほうが扱いやすいから、
gluLookAt(0,0,正…)にして、下がってるのね。
gluLookAtは内部でglTranslateやglRotateを呼び出している。

なので、このコマンドはcamera to local座標って考えていいかも。
だから、このとき指定したカメラ位置は、ワールド座標でのカメラ位置になるんだ。

カメラ原点のz > 注視点のz

でなければならないってことだ。

gluLookAtは古い?

Macでコンパイルすると、

'glLookAt' is deprecated: first deprecated in OS X 10.9
use GLKMatrix4MakeLookAt

GLKMatrix4MakeLookAtを使えと出てきます

絶対見える方程式

nearZ< 見えてほしいもののZ<farZ

Android でgluLookAtがない

なんと、gluLookAtがない!!!!
NDKのサンプルからゲットするのじゃ。
how to convert modelview matrix to gluLookAt parameters?

gluLookAtのコード

 void gluLookAt(float eyex, float eyey, float eyez,
            float centerx, float centery, float centerz,
            float upx, float upy, float upz)
        {
            float x[3], y[3], z[3];
            float mag;
            mat4<T> model;//モデル行列
            mat4<T> view;//ビュー行列
 
            /* Make rotation matrix */
 
            /* 座標軸Z vector */
            z[0] = eyex - centerx;
            z[1] = eyey - centery;
            z[2] = eyez - centerz;
            mag = (float)sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
            if (mag) {            /* mpichler, 19950515 */
                z[0] /= mag;
                z[1] /= mag;
                z[2] /= mag;
            }
 
            /* 座標軸Y vector */
            y[0] = upx;
            y[1] = upy;
            y[2] = upz;
 
            /* X vector = Y cross Z *///座標軸のxはy軸とz軸の外積から求めることができる。
            x[0] =  y[1] * z[2] - y[2] * z[1];
            x[1] = -y[0] * z[2] + y[2] * z[0];
            x[2] =  y[0] * z[1] - y[1] * z[0];
 
            /* Recompute Y = Z cross X */
            y[0] =  z[1] * x[2] - z[2] * x[1];
            y[1] = -z[0] * x[2] + z[2] * x[0];
            y[2] =  z[0] * x[1] - z[1] * x[0];
 
            /* mpichler, 19950515 */
            /* cross product gives area of parallelogram, which is < 1.0 for
            * non-perpendicular unit-length vectors; so normalize x, y here
            */
            //各座標軸を正規化
            mag = (float)sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
            if (mag) {
                x[0] /= mag;
                x[1] /= mag;
                x[2] /= mag;
            }
 
            mag = (float)sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
            if (mag) {
                y[0] /= mag;
                y[1] /= mag;
                y[2] /= mag;
            }
 
            #define M(row,col)  model.m[col*4+row]
                        M(0, 0) = x[0];        M(0, 1) = x[1];        M(0, 2) = x[2];        M(0, 3) = 0.0;
                        M(1, 0) = y[0];        M(1, 1) = y[1];        M(1, 2) = y[2];        M(1, 3) = 0.0;
                        M(2, 0) = z[0];        M(2, 1) = z[1];        M(2, 2) = z[2];        M(2, 3) = 0.0;
                        M(3, 0) = 0.0;        M(3, 1) = 0.0;        M(3, 2) = 0.0;        M(3, 3) = 1.0;
            #undef M
                        /* Translate Eye to Origin */
                        //glTranslatex((GLfixed)(-eyex * 65536),(GLfixed)(-eyey * 65536),(GLfixed)(-eyez * 65536));//と同じ
                        view.m[0]=1;view.m[4]=0;view.m[ 8]=0;view.m[12]=-eyex;
                        view.m[1]=0;view.m[5]=1;view.m[ 9]=0;view.m[13]=-eyey;
                        view.m[2]=0;view.m[6]=0;view.m[10]=1;view.m[14]=-eyez;
                        view.m[3]=0;view.m[7]=0;view.m[11]=0;view.m[15]=1;
                        //view.print("view");model.print("model");
                        *this=(model*view);
        }
/* Following gluLookAt implementation is adapted from the
 * Mesa 3D Graphics library. http://www.mesa3d.org
 */
static void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
                  GLfloat centerx, GLfloat centery, GLfloat centerz,
                  GLfloat upx, GLfloat upy, GLfloat upz)
{
    GLfloat m[16];
    GLfloat x[3], y[3], z[3];
    GLfloat mag;
 
    /* Make rotation matrix */
 
    /* Z vector */
    z[0] = eyex - centerx;
    z[1] = eyey - centery;
    z[2] = eyez - centerz;
    mag = (float)sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
    if (mag) {            /* mpichler, 19950515 */
        z[0] /= mag;
        z[1] /= mag;
        z[2] /= mag;
    }
 
    /* Y vector */
    y[0] = upx;
    y[1] = upy;
    y[2] = upz;
 
    /* X vector = Y cross Z */
    x[0] = y[1] * z[2] - y[2] * z[1];
    x[1] = -y[0] * z[2] + y[2] * z[0];
    x[2] = y[0] * z[1] - y[1] * z[0];
 
    /* Recompute Y = Z cross X */
    y[0] = z[1] * x[2] - z[2] * x[1];
    y[1] = -z[0] * x[2] + z[2] * x[0];
    y[2] = z[0] * x[1] - z[1] * x[0];
 
    /* mpichler, 19950515 */
    /* cross product gives area of parallelogram, which is < 1.0 for
     * non-perpendicular unit-length vectors; so normalize x, y here
     */
 
    mag = (float)sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
    if (mag) {
        x[0] /= mag;
        x[1] /= mag;
        x[2] /= mag;
    }
 
    mag = (float)sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
    if (mag) {
        y[0] /= mag;
        y[1] /= mag;
        y[2] /= mag;
    }
 
#define M(row,col)  m[col*4+row]
    M(0, 0) = x[0];
    M(0, 1) = x[1];
    M(0, 2) = x[2];
    M(0, 3) = 0.0;
    M(1, 0) = y[0];
    M(1, 1) = y[1];
    M(1, 2) = y[2];
    M(1, 3) = 0.0;
    M(2, 0) = z[0];
    M(2, 1) = z[1];
    M(2, 2) = z[2];
    M(2, 3) = 0.0;
    M(3, 0) = 0.0;
    M(3, 1) = 0.0;
    M(3, 2) = 0.0;
    M(3, 3) = 1.0;
#undef M
    {
        int a;
        GLfixed fixedM[16];
        for (a = 0; a < 16; ++a)
            fixedM[a] = (GLfixed)(m[a] * 65536);
        glMultMatrixx(fixedM);
    }
 
    /* Translate Eye to Origin */
    glTranslatex((GLfixed)(-eyex * 65536),
                 (GLfixed)(-eyey * 65536),
                 (GLfixed)(-eyez * 65536));
}

camera modelview-matrix

サポートサイト Wikidot.com cameramodelview-matrix