OpenGL gluLookat()函数的实现

OpenGL gluLookat()函数的实现

  1. 函数形式:
gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
  1. 参数解释:

    视点:(eyeX,eyeY,eyeZ)
    观察点:(centerX,centerY,centerZ)
    V(向上)向量 :(upX,upY,upZ)

  2. 函数原理:
    步骤:
    (1)世界坐标系中选中一点eye(eyeX,eyeY,eyeZ)作为视点,则定义z轴为:(centerX-eyeX,centerY-eyeY,centerZ-eyeZ),并归一化;
    (2)再指定定义y方向的观察向上向量V(upX,upY,upZ),注意:此时的V与z未必垂直,然后将归一化后的z与V进行一次叉乘,得到x轴,也进行归一化;
    (3)至此,视点的坐标系只剩下y轴没有确定,同理,只需将归一化后z轴与x轴进行叉乘运算便得到了y轴,最后再将y轴进行归一化;
    综上:其实gluLookat()函数的实现就是确定视点的坐标系的过程,也即求世界坐标系到观察坐标系的一个4*4的变换。

  1. 代码:
#include 
#include 
#include 
#include 
using namespace std;

struct point
{
	GLdouble x, y, z;
	point()
	{
		x = y = z = 0;
	}
	point(GLdouble _x, GLdouble _y, GLdouble _z)
	{
		x = _x;
		y = _y;
		z = _z;
	}
};
typedef point Vector;
void Normalize(Vector &V)
{
	GLdouble tmp = sqrt(V.x*V.x + V.y*V.y + V.z*V.z);
	V.x = V.x / tmp;
	V.y = V.y / tmp;
	V.z = V.z / tmp;
}
Vector Cross(Vector a, Vector b)//
{
	return Vector(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
}
//视点、参考点、向上向量V
void MyLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ)
{
	GLdouble Mat[16];
	memset(Mat, 0, sizeof(Mat));//内存空间初始化(用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'/0')
	Mat[15] = 1;
	Vector forward(centerX - eyeX, centerY - eyeY, centerZ - eyeZ);//正Z轴方向
	Vector up(upX, upY, upZ);//向上向量
	Normalize(forward);//归一化
	Vector side = Cross(forward, up);//x方向
	Normalize(side);
	up = Cross(side, forward);//y方向
	Mat[0] = side.x;
	Mat[4] = side.y;
	Mat[8] = side.z;
	Mat[1] = up.x;
	Mat[5] = up.y;
	Mat[9] = up.z;
	Mat[2] = -forward.x;
	Mat[6] = -forward.y;
	Mat[10] = -forward.z;
	cout << Mat[10] << " ";
	cout << endl;
	glLoadMatrixd(Mat);

	glTranslated(-eyeX, -eyeY, -eyeZ);
}
void init(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0); //背景黑色  
}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0, 1.0, 1.0); //画笔白色  

	glLoadIdentity();  //加载单位矩阵  

	//  gluLookAt(0, 0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	MyLookAt(0, 0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glutWireTeapot(2);
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800, 600);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);
	init();
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMainLoop();
	return 0;
}

到这里说完了,第一次发博客文章,文字解释可能逻辑性不是太强,但只要开始就是好的,也希望自己能越写越好!

你可能感兴趣的:(OpenGL)