如果您想创建第一个视图矩阵,请从 gluLookAt 开始。
使用这个方便的Legacy OpenGL 实用函数,您可以通过位置 (eye)、目标点 (target) 和上向量 (up) 定义视图矩阵:
(另见Java Code Examples for org.lwjgl.util.glu.GLU.gluLookAt())
GLU.gluLookAt(eye.x, eye.y, eye.z, target.x, target.y, target.z, up.x, up.y, up.z);
视图空间是由场景中的视点定义的局部系统。
视图的位置、视线和视图的向上方向,定义了一个相对于世界坐标系的坐标系。场景的对象必须相对于视图坐标系进行绘制,才能从观察位置“看到”。视图坐标系的逆矩阵称为视图矩阵。该矩阵从世界坐标转换为视图坐标。
此外,您还需要Orthographic 或Perspective 投影矩阵。
前一个矩阵可以定义为glOrtho
(另见Java Code Examples for org.lwjgl.opengl.GL11.glOrtho())
GL11.glOrtho(0, width, height, 0, 1, -1);
后来gluPerspective
(另见Java Code Examples for org.lwjgl.util.glu.GLU.gluPerspective())
GLU.gluPerspective(45.0f, wRatio, (float) near, (float) far);
投影矩阵描述了从场景的 3D 点到视口的 2D 点的映射。投影矩阵从视图空间转换到剪辑空间。通过除以剪辑坐标的w 分量,剪辑空间中的坐标被转换为范围为 (-1, -1, -1) 到 (1, 1, 1) 的标准化设备坐标 (NDC)。
在旧版 OpenGL 中存在不同的当前矩阵。投影矩阵应设置为当前GL_PROJECTION 矩阵,视图矩阵应设置为当前GL_MODELVIEW 矩阵。见glMatrixMode。
例如:
float width = ...; // width of the window
float height = ...; // height of the window
Vector3f eye = ...; // camera position
Vector3f target = ...; // camera target
Vector3f up = ...; // camera up vector
float ratio = 1.0f * width / height;
GL11.glViewport(0, 0, (int) w, (int) h);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(45.0f, ratio , 0.1f, 100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GLU.gluLookAt(eye.x, eye.y, eye.z, target.x, target.y, target.z, up.x, up.y, up.z);
代替GLU.gluPerspective,可以设置透视投影矩阵如下:
float width = ...; // width of the window
float height = ...; // height of the window
float fov_y = 45.0f; // filed of view in degrees (y axis)
float n = 0.1f; // near plane
float f = 100.0f; // far plane
float a = width / height;
float ta = Math.tan(Math.radians(fov_y) / 2.0f);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
glLoadMatrixf(new float[]{
1.0f/(ta*a), 0.0f, 0.0f, 0.0f,
0.0f, 1.0f/ta, 0.0f, 0.0f,
0.0f, 0.0f, -(f+n)/(f-n), -1.0f,
0.0f, 0.0f, -2.0f*f*n/(f-n), 0.0f
});
可以通过glTranslate 和glRoatate 设置视图矩阵,而不是使用GLU.gluLookAt:
float distance = 10.0f; // distance to object
float pitch = 0.0f; // pitch in degrees
float yaw = 0.0f; // yaw in degrees
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
GL11.glTranslatef(0.0f, 0.0f, -distance);