OpenGL有三个矩阵堆栈,分别是GL_MODELVIEW(模型视图矩阵堆栈)、GL_PROJECTION(投影矩阵堆栈)、GL_TEXTURE(纹理矩阵堆栈),用法和普通堆栈一样;

这里我们只讲模型视图矩阵堆栈,OpenGL提供了相应的接口:glPushMatirx()和glPopMatrix()。

这个模型视图矩阵堆栈是干嘛用的呢?我们在三维空间中绘制模型,大部分时候需要对模型进行移动、旋转、缩放操作,其实OpenGL移动的不是模型,而是坐标系(效果是一样的啦,就比如你坐在车上,跟你并排的还有一辆车,都是静止不动的,这时候你倒车的效果和旁边那辆车前进的效果是不是一样的)。但是,但空间中有多个模型的时候,这个时候,问题来了,我们怎么确定每个模型都绘制在预期的位置呢?

比如,我们想要绘制太阳系,中间是太阳,静止不动,地球围绕太阳旋转,月亮围绕地球旋转,如下图所示的情景:

我们首先将坐标系移动到太阳的位置,绘制太阳,再将坐标系移动到地球的位置,绘制地球,然后将坐标系移动到月亮的位置,绘制月亮;如果还有金星、木星、火星呢,他们也都是以太阳为中心旋转,这样子,我们可以绘制完月亮之后再将坐标系回退到绘制地球的时候的坐标系,移动相应的位置,绘制金星,然后再回退或者移动新位置绘制木星。。。。。。这样的操作不但麻烦,而且容易出错(麻烦的东西都比较容易出错,所以要简洁),那怎么办最好呢,其实就是绘制地球、金星、木星、火星等的时候以太阳为坐标原点,在绘制地球之前先把当前的模型视图矩阵压入堆栈中保存下来(glPushMatirx),这样你在进行变换就不会影响到堆栈中的矩阵,这个时候将坐标系移动到地球的位置绘制地球,绘制完成之后将模型视图矩阵堆栈中的栈顶矩阵(就是我们刚才保存的矩阵)弹出(glPopMatrix),恢复原来的坐标系,再压入堆栈,绘制金星,再弹出。。。。。。

可以使用嵌套,即:

绘制太阳

压栈

(栈顶矩阵为太阳对应的模型视图矩阵)

移动坐标系到地球位置

绘制地球

压栈(这里就嵌套了)

(栈顶矩阵为地球地球对应的模型视图矩阵)

移动坐标系到月亮的位置

绘制月亮

压栈(嵌套又见嵌套)

(栈顶局长为月亮对应的模型视图矩阵)

移动坐标系到月亮的月亮(虚构)的位置

绘制月亮的月亮

出栈

(栈顶矩阵恢复为地球地球对应的模型视图矩阵,这时可以绘制第二个月亮了)

出栈

(栈顶矩阵恢复为太阳对应的模型视图矩阵,这时可以绘制金星、木星、火星等等了)

出栈

(栈顶为最初的模型视图矩阵,这时可以绘制太阳2,太阳3.。。。。。。太阳9,后羿射日前)

具体代码为(代码只实现了绘制两个月亮,也是嵌套,没有那么多,原理是一样的)

[cpp] view plain copy  
  1. // Called to draw scene
  2. void RenderScene(void)
  3. {
  4. // Earth and Moon angle of revolution
  5. static float fMoonRot = 0.0f;
  6. static float fEarthRot = 0.0f;
  7. // Clear the window with current clearing color
  8. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  9. // Save the matrix state and do the rotations
  10. glMatrixMode(GL_MODELVIEW);
  11. glPushMatrix();
  12. // Translate the whole scene out and into view
  13. glTranslatef(0.0f, 0.0f, -300.0f);
  14. // Set material color, Red
  15. // Sun
  16. glDisable(GL_LIGHTING);
  17. glColor3ub(255, 255, 0);
  18. glutSolidSphere(15.0f, 30, 17);
  19. glEnable(GL_LIGHTING);
  20. // Move the light after we draw the sun!
  21. glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
  22. // Rotate coordinate system
  23. glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);
  24. // Draw the Earth
  25. glColor3ub(0,0,255);
  26. glTranslatef(105.0f,0.0f,0.0f);
  27. glutSolidSphere(15.0f, 30, 17);
  28. glPushMatrix();
  29. // Rotate from Earth based coordinates and draw Moon
  30. glColor3ub(200,200,200);
  31. glRotatef(fMoonRot,0.0f, 1.0f, 0.0f);
  32. glTranslatef(30.0f, 0.0f, 0.0f);
  33. fMoonRot+= 15.0f;
  34. if(fMoonRot > 360.0f)
  35. fMoonRot = 0.0f;
  36. glutSolidSphere(6.0f, 30, 17);
  37. glPopMatrix();
  38. glColor3ub(100, 250, 0);
  39. glRotatef(fMoonRot, 1.0f, 0.0f, 0.0f);
  40. glTranslatef(0.0f, 20.0f, 0.0f);
  41. glutSolidSphere(6.0f, 30, 17);
  42. // Restore the matrix state
  43. glPopMatrix();  // Modelview matrix
  44. // Step earth orbit 5 degrees
  45. fEarthRot += 5.0f;
  46. if(fEarthRot > 360.0f)
  47. fEarthRot = 0.0f;
  48. // Show the image
  49. glutSwapBuffers();
  50. }

实现效果图:

不过需要注意的是,模型视图矩阵堆栈最大为32个,Windows平台,有数量限制,超出的话将会报错。

转载地址:http://blog.csdn.net/tyxkzzf/article/details/40907273

opengl glPushMatrix()相关推荐

  1. OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数详解

    OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的.opengl中的变换一般包括视图变换.模型变换.投影变换等,在每次变换后,opengl将会呈 ...

  2. OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数

    在之前的博客中,我就说过后面会详细讲解这两个函数.今天让我们来认识下它们(glPushMatrix和glPopMatrix函数). OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这 ...

  3. OpenGL中glPushMatrix和glPopMatrix的原理

    glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...

  4. OpenGL使用矩阵堆栈glpushMatrix的原因

    http://anony3721.blog.163.com/blog/static/511974201133095555708/ 题外话:学习OpenGL有两个礼拜了,总结下才发现仅仅明白了其基本概念 ...

  5. Opengl的glPushMatrix和glPopMatrix理解

    glPushMatrix()和glPopMatrix()的配对使用可以消除上一次的变换对本次变换的影响,将本次需要执行的缩放.平移等操作放在两者之间.使本次变换是以世界坐标系的原点为参考点进行. 1) ...

  6. opengl入门记录--glPushMatrix和glPopMatrix原理

    glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...

  7. OpenGL编程指南9:裁剪平面+glPushMatrix和glPopMatrix矩阵栈顶操作

    1.任意裁剪平面 Opengl中,除了视景体的立方体裁剪平面之外,另外还可以额外指定多达6个裁剪平面,对视景体做进一步限制.每一个平面都由平面公式定义:Ax+By+Cz+D = 0.裁剪平面的指定通过 ...

  8. OpenGL中glMatrixMode的使用,以及glPushMatrix和glPopMatrix的原理

    一.glMatrixMode()函数的参数,这个函数其实就是对接下来要做什么进行一下声明,也就是在要做下一步之前告诉计算机我要对"什么"进行操作了,这个"什么" ...

  9. 小白学opengl之glpushmatrix()与glpopmatrix()的作用

    当你做了一些移动或旋转等变换后,使用glPushMatrix(); OpenGL 会把这个变换后的位置和角度保存起来. 然后你再随便做第二次移动或旋转变换,再用glPopMatrix(); OpenG ...

最新文章

  1. php用命令查mysql_phpMySQL命令大全总结
  2. excel导入数据时报错,显示Extracted SQL state class ‘22‘ from value ‘22001‘
  3. 利润中心与其他模块的集成
  4. 笔记--------手动分页
  5. 深度:抖音本地生活服务的真相
  6. 树莓派c语言运行_树莓派完成简单的编程(四)
  7. 当前服务器文件夹不存在,供应商文件夹不存在,无法创建
  8. OpenCV3学习(7.1)——图像分割之一(漫水填充FloodFill)
  9. 《BI那点儿事》数据流转换——透视
  10. linux oracle 删除为空的dbf,Linux上Oracle误删除一个没有用的dbf表空间文件
  11. 拔叉零件的加工工艺、夹具以及拉刀设计
  12. 分享100个好看且实用的PPT模板
  13. 分享 :理解和管理社交媒体算法的4个想法
  14. linux 查看策略路由,Linux下的策略路由。
  15. android 获取全国地址,Android获取所有国家列表
  16. 蕃茄工作法 - 让你轻松应对繁忙的工作
  17. 1、junit学习之junit的基本介绍
  18. GEAP 遗传算法/遗传编程 genetic programming + python(deap库)实现
  19. 试题 算法训练 猴子分苹果
  20. 免费中医坐堂管理软件

热门文章

  1. 批量提取pdf文件名到excel
  2. 初学古筝的一些基础知识
  3. css常用(2):毛玻璃 、模糊滤镜
  4. LayaAir Typescript安装过程详解
  5. SuperCell 的中台你们学不会
  6. SpringMVC中json数据传输
  7. 多元正态分布的四种定义
  8. Ubuntu ens33网卡无ip
  9. 空间音频技术与生态发展高峰论坛成功举办,业界首个Audio Vivid创作工具花瓣三维声亮相
  10. 网络空间安全 渗透 攻防7(web服务器,FTP服务器)