根据我的理解,
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()
的调用似乎无效。以下是代码段:
#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)
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)
!那么有人可以帮我解释一下吗?
gluLookAt
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);
}
答案 0 :(得分:6)
如果我们让旋转和平移矩阵像你的模型视图矩阵那样
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
(我正在写东西,所以矢量乘以左边的矩阵)。
这表明矩阵的转换组件使转换在执行旋转后应用。这就是为什么它们与你的(-eye_x,-eye_y,-eye_z)向量不同,因为你指出翻译是在旋转之前完成的。
平移始终沿着-z方向的原因是因为在视图框架中-z方向指向中心。由于您总是从眼睛中心有300个单位,所以您的所有眼睛位置都将中心位于视图框中的(0,0,-300)。因此,因为在我们进行任何翻译之前,中心从原点开始,所以为其提供正确的共同定义的翻译必须是(0,0,-300)。
另外,您可能已经注意到了这一点,但您显示的模型视图矩阵是病态的,因为您的向上矢量指向视图方向(从眼睛到中心)。这就解释了为什么它有两行完整的零。
答案 1 :(得分:0)
“我对使用此代码中的向前,向上和向侧矢量执行旋转感到非常困惑......” 我想你应该对“UVN相机”有所了解。有一些关于坐标在两个坐标系之间平移的理论。在上面的例子中,两个坐标是世界坐标和相机坐标。 结果是: X
N - 从目标到相机的矢量。在一些3D文献中也被称为“look at”向量。该向量对应于-Z ax。
V - 直立时,这是从头部到天空的矢量。如果你正在编写一个飞行模拟器并且平面被反转,那么矢量很可能指向地面。该向量对应于Y轴。
U - 此向量从相机指向“右侧”。它对应于X轴。
答案 2 :(得分:0)