gluLookAt如何工作? [英] How does gluLookAt work?

查看:109
本文介绍了gluLookAt如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解

gluLookAt(
        eye_x, eye_y, eye_z,
        center_x, center_y, center_z,   
        up_x, up_y, up_z
    );

等效于:

glRotatef(B, 0.0, 0.0, 1.0);
glRotatef(A, wx, wy, wz);
glTranslatef(-eye_x, -eye_y, -eye_z);

但是当我打印出ModelView矩阵时,对glTranslatef()的调用似乎无法正常工作.这是代码段:

But when I print out the ModelView matrix, the call to glTranslatef() doesn't seem to work properly. Here is the code snippet:

#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>

#include <iomanip>
#include <iostream>
#include <string>

using namespace std;

static const int Rx = 0;
static const int Ry = 1;
static const int Rz = 2;

static const int Ux = 4;
static const int Uy = 5;
static const int Uz = 6;

static const int Ax = 8;
static const int Ay = 9;
static const int Az = 10;

static const int Tx = 12;
static const int Ty = 13;
static const int Tz = 14;

void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLfloat lmodel_ambient[] = { 0.8, 0.0, 0.0, 0.0 };
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
}

void displayModelviewMatrix(float MV[16]) {
    int SPACING = 12;
    cout << left;
    cout << "\tMODELVIEW MATRIX\n";
    cout << "--------------------------------------------------" << endl;
    cout << setw(SPACING) << "R" << setw(SPACING) << "U" << setw(SPACING) << "A" << setw(SPACING) << "T" << endl;   
    cout << "--------------------------------------------------" << endl;
    cout << setw(SPACING) << MV[Rx] << setw(SPACING) << MV[Ux] << setw(SPACING) << MV[Ax]  << setw(SPACING) << MV[Tx] << endl;
    cout << setw(SPACING) << MV[Ry] << setw(SPACING) << MV[Uy] << setw(SPACING) << MV[Ay]  << setw(SPACING) << MV[Ty] << endl;
    cout << setw(SPACING) << MV[Rz] << setw(SPACING) << MV[Uz] << setw(SPACING) << MV[Az] << setw(SPACING)  << MV[Tz] << endl;
    cout << setw(SPACING) << MV[3] << setw(SPACING) << MV[7] << setw(SPACING) << MV[11] << setw(SPACING) << MV[15] << endl;
    cout << "--------------------------------------------------" << endl;
    cout << endl;
}

void reshape(int w, int h) {
    float ratio = static_cast<float>(w)/h;
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, ratio, 1.0, 425.0);
}

void draw() {
    float m[16];
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glGetFloatv(GL_MODELVIEW_MATRIX, m);
    gluLookAt(
        300.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    );
    glColor3f(1.0, 0.0, 0.0);
    glutSolidCube(100.0);
    glGetFloatv(GL_MODELVIEW_MATRIX, m);
    displayModelviewMatrix(m);
    glutSwapBuffers();
}


int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(400, 400);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Demo");
    glutReshapeFunc(reshape);
    glutDisplayFunc(draw);
    init();
    glutMainLoop();
    return 0;
} 

无论我为eye矢量使用什么值:
300, 0, 0
0, 300, 0
0, 0, 300
翻译向量是相同的,这没有任何意义,因为代码顺序是反向的,因此glTranslatef应该先运行,然后再运行2圈.另外,旋转矩阵完全独立于平移列(在ModelView矩阵中),那么什么会导致这种奇怪的行为? 这是眼睛向量为(0.0f, 300.0f, 0.0f)

No matter what value I use for the eye vector:
300, 0, 0 or
0, 300, 0 or
0, 0, 300
the translation vector is the same, which doesn't make any sense because the order of code is in backward order so glTranslatef should run first, then the 2 rotations. Plus, the rotation matrix, is completely independent of the translation column (in the ModelView matrix), then what would cause this weird behavior? Here is the output with the eye vector is (0.0f, 300.0f, 0.0f)

        MODELVIEW MATRIX
--------------------------------------------------
R           U           A           T
--------------------------------------------------
0           0           0           0
0           0           0           0
0           1           0           -300
0           0           0           1
--------------------------------------------------

我希望T列为(0, -300, 0)!有人可以帮我解释一下吗?

I would expect the T column to be (0, -300, 0)! So could anyone help me explain this?

来自 http://www.mesa3d.org

void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
      GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
      GLdouble upz)
{
    float forward[3], side[3], up[3];
    GLfloat m[4][4];

    forward[0] = centerx - eyex;
    forward[1] = centery - eyey;
    forward[2] = centerz - eyez;

    up[0] = upx;
    up[1] = upy;
    up[2] = upz;

    normalize(forward);

    /* Side = forward x up */
    cross(forward, up, side);
    normalize(side);

    /* Recompute up as: up = side x forward */
    cross(side, forward, up);

    __gluMakeIdentityf(&m[0][0]);
    m[0][0] = side[0];
    m[1][0] = side[1];
    m[2][0] = side[2];

    m[0][1] = up[0];
    m[1][1] = up[1];
    m[2][1] = up[2];

    m[0][2] = -forward[0];
    m[1][2] = -forward[1];
    m[2][2] = -forward[2];

    glMultMatrixf(&m[0][0]);
    glTranslated(-eyex, -eyey, -eyez);
}

推荐答案

如果我们让旋转和平移矩阵像您的modelview矩阵

If we let a rotation and translation matrix like your modelview matrix

Rxx Rxy Rxz Tx 
Ryx Ryy Ryz Ty 
Rzx Rzy Rzz Tz 
 0   0   0   1 

作用于任意向量

x
y
z
1

我们得到

Rxx x + Rxy y + Rxz z  +  Tx 
Ryx x + Ryy y + Ryz z  +  Ty
Rzx x + Rzy y + Rzz z  +  Tz
1

(我正在写东西,所以向量乘以左边的矩阵).

(I'm writing things so vectors get multiplied by matrices on the left).

这表明矩阵的平移分量使平移在旋转之后应用 .这就是为什么它们与您的(-eye_x,-eye_y,-eye_z)向量不同的原因,因为正如您指出的那样,平移是在旋转之前完成的.

This shows that the translation components of the matrix give the translation to apply after doing the rotation. That's why they aren't the same as your (-eye_x, -eye_y, -eye_z) vector, because as you point out that translation is being done before the rotation.

平移始终沿-z方向进行的原因是,在视框内-z方向指向中心.由于您始终从眼睛获得中心300个单位,因此您所有的眼睛位置都将中心置于视场中的(0,0,-300)处.因此,由于在进行任何翻译之前,中心都是从原点开始的,所以要赋予它正确的共坐标的翻译必须是(0,0,-300).

The reason that the translation is always along the -z direction is because in the view frame the -z direction points towards the centre. Since you always have the centre 300 units from the eye, all of your eye positions put the centre at (0, 0, -300) in the view frame. Therefore, because the centre starts at the origin before we do any translating, the translation to give it the correct co-orindates must be (0, 0, -300).

此外,您可能已经注意到了这一点,但是您显示的modelview矩阵是病理性的,因为您具有沿视图方向(从眼睛到中心)的向上矢量.这就解释了为什么它有两行完整的零.

Also, you might have noticed this, but the modelview matrix you show is pathological because you have the up vector pointing along the view direction (from eye to centre). That explains why it has two full rows of zeros.

这篇关于gluLookAt如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆