glLookAt介绍
glLookAt
描述的是观察坐标系,OpenGL内部会生成逆矩阵(可称为视图矩阵,用于与观察矩阵区分,这种区分是用于帮助自己理解,实际Opengl相关教程中一般对这两个是不区分的,一般就叫模型视图矩阵)。观察矩阵与视图矩阵互为逆矩阵。
测试glLookAt
俯视
//origin = (0, 0, 10)
//x = (1, 0, 0)
//y = (0, 1, 0)
//z = (0, 0, 1)
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
前视
//origin = (0, -10, 0)
//x = (1, 0, 0)
//y = (0, 0, 1)
//z = (0, -1, 0)
gluLookAt(0, -10, 0, 0, 0, 0, 0, 0, 1);
右视
//origin: (10, 0, 0)
//x = (0, 1, 0)
//y = (0, 0, 1)
//z = (1, 0, 0)
gluLookAt(10, 0, 0, 0, 0, 0, 0, 0, 1);
测试所用代码
Matrix3d是自写的矩阵类,读者可以任意找矩阵类替换,此处仅用它来生成逆矩阵。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//俯视
//origin = (0, 0, 10)
//x = (1, 0, 0)
//y = (0, 1, 0)
//z = (0, 0, 1)
//gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
//前视
//origin = (0, -10, 0)
//x = (1, 0, 0)
//y = (0, 0, 1)
//z = (0, -1, 0)
//gluLookAt(0, -10, 0, 0, 0, 0, 0, 0, 1);
//右视
//origin: (10, 0, 0)
//x = (0, 1, 0)
//y = (0, 0, 1)
//z = (1, 0, 0)
gluLookAt(10, 0, 0, 0, 0, 0, 0, 0, 1);
float m[16] = { 0 }; //用来保存当前矩阵数据
glGetFloatv(GL_MODELVIEW_MATRIX, m);//观察矩阵的逆矩阵,得到视图矩阵
float displayMat[4][4] = { 0 };
Matrix3d matTemp;
for (int i = 0; i < 16; ++i)
{
displayMat[i % 4][i / 4] = m[i];
matTemp.entry[i % 4][i / 4] = m[i];
}
//逆矩阵为观察坐标系的矩阵
Matrix3d inverseMat = matTemp.inverse();
std::cout << std::endl << "观察矩阵(OpenGL采用前乘,坐标点用列向量)" << std::endl;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
std::cout << std::setw(4) << inverseMat.entry[i][j];
}
std::cout << std::endl;
}
std::cout << std::endl << std::endl;
//视图矩阵
std::cout << "视图矩阵(OpenGL采用前乘,坐标点用列向量,此为OpenGL的模型视图矩阵,"
<< "模型视图变换用的是这个矩阵):" << std::endl;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
std::cout << std::setw(4) << displayMat[i][j];
}
std::cout << std::endl;
}
std::cout << std::endl << std::endl;