OpenGL | OpenGL矩阵操作(视图模型矩阵下)

这篇具有很好参考价值的文章主要介绍了OpenGL | OpenGL矩阵操作(视图模型矩阵下)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在opengl场景中一般存在多种矩阵变换操作,而控制这些操作的命令主要用到glMatrixMode函数。

模型视图矩阵是在对物体进行缩放或者从不同的视角观察物体的时候所调用的。主要涉及到三个函数:

glTranslate、glRotate、glScale。

一、平移glTranslatef

1.glTranslatef介绍

void WINAPI glTranslatef(
   GLfloat x,
   GLfloat y,
   GLfloat z
);
  • 沿X轴正方向平移x个单位(x是有符号数)

  • 沿Y轴正方向平移y个单位(y是有符号数)

  • 沿Z轴正方向平移z个单位(z是有符号数)

2.glTranslatef应用

众所周知:当我们利用OpenGL绘制图形时,glVertex3f第三个参数>=0的话屏幕就绘制不出效果。如下方代码:

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);
    //绘制独立的三角形
    glBegin(GL_TRIANGLES);        //注意是逆时针绘制
    glColor4ub(0, 0, 255, 255);   //蓝
    glVertex3f(-0.2f, -0.2f, 0.0f);

    glColor4ub(255, 0, 0, 255);   //红
    glVertex3f(0.2f, -0.2f, 0.0f);

    glColor4ub(0, 255, 0, 255);   //绿
    glVertex3f(0.0f, 0.2f, 0.0f);
    glEnd();
}

所以要想获得正确的绘制效果,除了改glVertex3f的第三个参数为负数,我们还可以用矩阵转换的方式实现。

void Init()
{
    glMatrixMode(GL_PROJECTION);//将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW); //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();           //把矩阵设为单位矩阵
    glTranslatef(0, 0, - 1.5f);//此时ModedlViewMatrix就可以让之后的所有数据都带上一个-1.5的Z方向的偏移
}

二、旋转glRotatef

1.glRotatef介绍

void WINAPI glRotatef(
   GLfloat angle,
   GLfloat x,
   GLfloat y,
   GLfloat z
);

glRotatef函数针对上一个矩阵,使该矩阵以点(0,0,0)到点(x,y,z)为轴,逆时针旋转angle度。

2.glRotatef应用

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵
    glRotatef(30, 0, 0, 1);         //此时ModedlViewMatrix就可以让之后的所有数据都绕(0,0,1)旋转30度
}

三、缩放glScalef

1.glScalef介绍

void WINAPI glScalef(
   GLfloat x,
   GLfloat y,
   GLfloat z
);

glScalef 函数沿 xyz 轴生成常规缩放。

2.glScalef应用

以第三个参数来分析:

(1)当glVertex3f的第三个参数为0,通过glTranslatef来进行矩阵平移时,在使用glScalef后绘制画面上会有图形缩放的效果。

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵

    glTranslatef(0, 0, - 1.5f);    //平移

    glScalef(0.1f, 0.1f, 0.1f);
}

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);

    //绘制独立的三角形
    glBegin(GL_TRIANGLES);        //注意是逆时针绘制
    glColor4ub(0, 0, 255, 255);   //蓝
    glVertex3f(-0.2f, -0.2f, 0.0f);

    glColor4ub(255, 0, 0, 255);   //红
    glVertex3f(0.2f, -0.2f, 0.0f);

    glColor4ub(0, 255, 0, 255);   //绿
    glVertex3f(0.0f, 0.2f, 0.0f);
    glEnd();
}

如上方代码:

注释glScalef(0.1f, 0.1f, 0.1f);时

opengl matrix,OpenGL,c++,opengl,Powered by 金山文档

添加glScalef(0.1f, 0.1f, 0.1f);时

opengl matrix,OpenGL,c++,opengl,Powered by 金山文档

(2)当glVertex3f的第三个参数不为0,且没有通过glTranslatef来进行矩阵平移时,由于glScalef影响了glVertex3f的第三个参数,点的绘制离摄像头近了,所以绘制后,在视觉效果上没有图形缩放的效果。如下方的代码:加上或者注释glScalef(0.1f, 0.1f, 0.1f);后画面效果不变。

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵
    glScalef(0.1f, 0.1f, 0.1f);
}

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);

    //绘制独立的三角形
    glBegin(GL_TRIANGLES);        //注意是逆时针绘制
    glColor4ub(0, 0, 255, 255);   //蓝
    glVertex3f(-0.2f, -0.2f, -1.5f);

    glColor4ub(255, 0, 0, 255);   //红
    glVertex3f(0.2f, -0.2f, -1.5f);

    glColor4ub(0, 255, 0, 255);   //绿
    glVertex3f(0.0f, 0.2f, -1.5f);
    glEnd();
}

四、压栈出栈

由于openGL只有一个坐标系,所以平常画物体,应该注意保存当前坐标系坐标,以便画完后返回。如下方代码:这样画A就不会影响其他部分了。

glPushMatrix()
//坐标变换。。。
//画好物体A
glPopMatrix();
//继续新的代码

1.glPushMatrix & glPopMatrix

对于矩阵的操作都是对于矩阵栈的栈顶来操作的。当前矩阵即为矩阵栈的栈顶元素,而对当前矩阵进行平移、旋转等的变换操作也同样是对栈顶矩阵的修改。所以我们在变换之前调用glPushMatrix()的话,就会把当前状态压入第二层,并且此时栈顶的矩阵也与第二层的相同。

当经过一系列的变换后,栈顶矩阵被修改,此时调用glPopMatrix()时,栈顶矩阵被弹出,且又会恢复为原来的状态。

2.举个栗子

(1)代码

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵 
}

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);

    glLoadIdentity();                //重置矩阵设为单位矩阵

     //glTranslatef使两个同位置的三角形分开
    glPushMatrix();
         glTranslatef(-0.4f, 0.0f, 0.0f);    //向左平移0.4个单位

         glBegin(GL_TRIANGLES);        //注意是逆时针绘制
         glColor4ub(0, 0, 255, 255);   //蓝
         glVertex3f(-0.2f, -0.2f, -1.0f);

         glColor4ub(255, 0, 0, 255);   //红
         glVertex3f(0.2f, -0.2f, -1.0f);

         glColor4ub(0, 255, 0, 255);   //绿
         glVertex3f(0.0f, 0.2f, -1.0f);
         glEnd();
    glPopMatrix();

    glPushMatrix();
         glTranslatef(0.4f, 0.0f, 0.0f);    //向右平移0.4个单位

         glBegin(GL_TRIANGLES);        //注意是逆时针绘制
         glColor4ub(0, 0, 255, 255);   //蓝
         glVertex3f(-0.2f, -0.2f, -1.0f);

         glColor4ub(255, 0, 0, 255);   //红
         glVertex3f(0.2f, -0.2f, -1.0f);

         glColor4ub(0, 255, 0, 255);   //绿
         glVertex3f(0.0f, 0.2f, -1.0f);
         glEnd();
    glPopMatrix();

(2)效果

opengl matrix,OpenGL,c++,opengl,Powered by 金山文档

五、注意

由于矩阵乘法不具有交换律的性质,所以对一个矩阵先旋转后平移和先平移后旋转这两种不同的操作产生的效果不同。(想想unity场景中对一个模型的操作)。文章来源地址https://www.toymoban.com/news/detail-769472.html

到了这里,关于OpenGL | OpenGL矩阵操作(视图模型矩阵下)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第五章 OpenGL ES 基础-透视投影矩阵与正交投影矩阵

    第一章 OpenGL ES 基础-屏幕、纹理、顶点坐标 第二章 OpenGL ES 基础-GLSL语法简单总结 第三章 OpenGL ES 基础-GLSL渲染纹理 第四章 OpenGL ES 基础-位移、缩放、旋转原理 第五章 OpenGL ES 基础-透视投影矩阵与正交投影矩阵 模型都是3D的,但屏幕是2D的。如何将3D空间投影到2D平面,还能保

    2024年03月09日
    浏览(31)
  • 第八章 OpenGL ES 基础-MVP矩阵理解

    第一章 OpenGL ES 基础-屏幕、纹理、顶点坐标 第二章 OpenGL ES 基础-GLSL语法简单总结 第三章 OpenGL ES 基础-GLSL渲染纹理 第四章 OpenGL ES 基础-位移、缩放、旋转原理 第五章 OpenGL ES 基础-透视投影矩阵与正交投影矩阵 第六章 OpenGL ES 基础-FBO、VBO理解与运用 第七章 OpenGL ES 基础-输入

    2024年04月26日
    浏览(25)
  • 一篇搞懂数学在OpenGL中的应用及矩阵

    目录 一、图形学中的矩阵 1.矩阵的计算公式 2.矩阵变换 3.为什么旋转,平移都是左乘矩阵,不能右乘 4.齐次坐标系统 5.变换先后顺序 二、利用矩阵来变换图形 (补充) 三、OpenGL中的三种变换矩阵  话不多说,我把我看的视频链接贴出来,下面的笔记是由视频学习和自己的补

    2024年02月03日
    浏览(24)
  • Qt OpenGL 3D模型

    这次教程中,我们将之前几课的基础上,教大家如何创建立体的3D模型。我们将开始生成真正的3D对象,而不是像之前那几课那样3D世界中的2D对象。我们会把之前的三角形变为立体的金字塔模型,把四边形变为立方体。 我们给三角形增加左侧面、右侧面、后侧面来生成一个金

    2024年02月11日
    浏览(38)
  • OpenGL 鼠标拾取模型

    1.简介 在我们的场景中,使用鼠标光标点击或“挑选”一个3d对象是很有用的。一种方法是从鼠标投射3d光线,通过相机,进入场景,然后检查光线是否与任何物体相交。这通常被称为 光线投射 。 我们不是从局部空间中的网格开始,而是从 视口空间中的2d鼠标光标位置开始

    2024年02月12日
    浏览(25)
  • OpenGL加载模型 之网格

    我们的工作就是去解析这些导出的模型文件,并将其中的模型数据存储为OpenGL能够使用的数据。一个常见的问题是,导出的模型文件通常有几十种格式,不同的工具会根据不同的文件协议把模型数据导出到不同格式的模型文件中。 有的模型文件格式只包含模型的静态形状数据

    2024年02月03日
    浏览(25)
  • 第十三章 opengl之模型(导入3D模型)

    使用Assimp并创建实际的加载和转换代码。Model类结构如下: Model类包含一个Mesh对象的vector,构造器参数需要一个文件路径。 构造器通过loadModel来加载文件。私有函数将会处理Assimp导入过程中的一部分,私有函数还存储了 文件路径的目录,加载纹理时会用到。 Draw函数的作用:

    2024年02月05日
    浏览(31)
  • OpenGL之鼠标拾取和模型控制

     使用鼠标单击或“选择”场景中的 3D 对象可能很有用 光标。一种方法是从鼠标投射 3D 射线, 通过摄像机,进入场景,然后检查该光线是否与任何对象。这通常称为光线投射。 步骤 0:2D 视口坐标  范围 [0:宽度、高度:0]  我们从鼠标光标坐标开始。这些是 2d,并且在

    2024年02月11日
    浏览(34)
  • OpenGL ES相关库加载3D 车辆模型

    需求类似奇瑞的这个效果,就是能全方位旋转拖拽看车,以及点击开关车门车窗后备箱等 瑞虎9全景看车 (chery.cn) 最开始收到这个需求的时候还有点无所适从,因为以前没有做过类似的效果,后面一经搜索后发现实现的方式五花八门,但始终绕不过opengl,于是通过opengl 逐步展

    2024年02月06日
    浏览(29)
  • 基于QT使用OpenGL,加载obj模型,进行鼠标交互

    基于QT平台,使用OpenGL进行obj文件加载显示; 使用鼠标对场景进行缩放、移动、旋转交互;   OpenGL是基于C的,学习曲线比较抖,但是总的来说就是下面一幅图,   用语言简单的描述(个人理解,可能不太准确)是把 cpu里内存里的3D数据,传输到显卡的内存里,以及如何

    2024年02月04日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包