您的位置:首页 > 其它

矩阵堆栈的操作、组合变换

2014-11-06 16:34 225 查看

矩阵堆栈的操作:

因为各种变换都是以矩阵方式存储的, 对于连续的存储、变换、反变换的排序, 矩阵堆栈提供了一种理想的机制。所有描述过的矩阵操作:

函数: glLoadMatrix*();

glMultMatrix*();

glLoadIdentity();

glTranslate*();

glRotated();

glScale*();

gluLookAt();....

负责处理当前矩阵, 或者处理当前栈顶矩阵。程序员可以使用执行堆栈操作的函数控制哪个矩阵位于顶部。其中函数glPushMatrix() 确定位于栈顶的矩阵,及拷贝当前矩阵, 并将其拷贝矩阵压入栈顶, 而函数glPopMatrix()用来删除栈顶的矩阵。

当前矩阵总是指向位于堆栈顶部的那个矩阵.

实际上glPushMatrix表示 “记住你当前的位置” , 而函数 glPopMatrix() 表示“回到原处”。

看一下下面的伪代码

void Draw_wheel_and_bolts()
{
draw_wheel();
for (int i = 0; i != 5; ++i)
{
glPushMatrix();  // 记住当前栈顶的矩阵
glRotatef(72 * i, 0, 0, 1);
glTranslatef(3.0, 0, 0);
glPopMatrix();  // 回到原处。
}
}

void draw_body_and_wheel_and_bolts()
{
draw_car_body();  //画了车身
glPushMatrix();
glTranslatef(40, 0, 30);  // 平移到一个第一个车轮位置
Draw_wheel_and_bolts();   // 画一个车轮
glPopMatrix();   // 恢复之前的位置。

glPushMatrix();
glTranslatef(40, 0, -30); // 画第二个
Draw_wheel_and_bolts();
glPopMatrix();

。。。。
}


模型视图矩阵堆栈:

模型视图矩阵是视图变换矩阵和模型变换矩阵乘积的累积结果。每一个视图或者模型变换都要产生一个新的矩阵, 它与当前的模型视图矩阵相乘, 相乘得到的结果成为新的当前矩阵。程序员可以通过查询函数glGetIntegerv() 传GL_MAX_MODELVIEW_STACK_DEPTH来得到堆栈中最大允许的矩阵数。

投影矩阵堆栈:

投影矩阵描述了视图体。通常,我们不希望对投影矩阵进行合成,因此在投影变换之前应该调用glLoadIdentity()。同样的原因, 投影矩阵堆栈深度只需要两级深度。在特殊情况下, 也允许多于两个, 可以调用glGetIntegerv 传 GL_MAX_PROJECTION_STACK_DEPTH,获得堆栈深度。

在某些应用程序中,要在窗口中显示三维场景, 同时又要显示带有文本的帮助窗口, 这时一般需要用到堆栈中的第二个矩阵。因为文本最容易用正交投影绘制,因此可以将当前投影暂时改为正交投影方式。如果你有更多的数学知识,可以自己来定义投影矩阵,实现OPENGL没有实现的函数。

附加裁剪平面:

除了视图体的6个裁剪平面, 我们还可以定义6个附加的裁剪平面, 以便更严格地限制视图体。

每个平面由方程Ax +By + Cz +D = 0 的系数A B C D所决定。裁剪平面根据模型变换和视图变换,自动的进行适当的变换。裁剪结果为视图体和所有附加裁剪平面定义的半空间的交集,且在切面上,OPENGL为自动的生成相应的边。

glClipPlane (GLenum plane, const GLdouble *equation);

equation 定义了平面方程4个系数的指针。M是当前视图模型矩阵, 所有满足 (A B C D)M^-1(xe, ye, ze, we)^ T > 0 的人眼坐标(xe, ye, ze, we)的点都位于该平面所定义的半空间内。参数plane 为 GL_CLIP_PLANEi i= [0,5]的自然数。

可以用glEnable(GL_CLIP_PLANEi) 来激活附加平面。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: