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

矩阵堆栈的操作:

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

函数:    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) 来激活附加平面。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值