opengl glPushMatrix()[通俗易懂]

opengl glPushMatrix()[通俗易懂]OpenGL有三个矩阵堆栈,分别是GL_MODELVIEW(模型视图矩阵堆栈)、GL_PROJECTION(投影矩阵堆栈)、GL_TEXTURE(纹理矩阵堆栈),用法和普通堆栈一样;这里我们只讲模型视图矩阵堆栈,OpenGL提供了相应的接口:glPushMatirx()和glPopMatrix()。这个模型视图矩阵堆栈是干嘛用的呢?我们在三维空间中绘制模型,大部分时候需要对模型进行

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

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

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

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

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

opengl glPushMatrix()[通俗易懂]

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

可以使用嵌套,即:

绘制太阳

压栈

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

移动坐标系到地球位置

绘制地球

压栈(这里就嵌套了)

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

移动坐标系到月亮的位置

绘制月亮

压栈(嵌套又见嵌套)

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

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

绘制月亮的月亮

出栈

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

出栈

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

出栈

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

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

[cpp] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  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.   
  8.     // Clear the window with current clearing color  
  9.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  10.   
  11.     // Save the matrix state and do the rotations  
  12.     glMatrixMode(GL_MODELVIEW);  
  13.     glPushMatrix();  
  14.   
  15.     // Translate the whole scene out and into view    
  16.     glTranslatef(0.0f, 0.0f, -300.0f);    
  17.       
  18.     // Set material color, Red  
  19.     // Sun  
  20.         glDisable(GL_LIGHTING);  
  21.     glColor3ub(255, 255, 0);  
  22.     glutSolidSphere(15.0f, 30, 17);  
  23.         glEnable(GL_LIGHTING);  
  24.   
  25.     // Move the light after we draw the sun!  
  26.     glLightfv(GL_LIGHT0,GL_POSITION,lightPos);  
  27.   
  28.     // Rotate coordinate system  
  29.     glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);  
  30.   
  31.     // Draw the Earth  
  32.     glColor3ub(0,0,255);  
  33.     glTranslatef(105.0f,0.0f,0.0f);  
  34.     glutSolidSphere(15.0f, 30, 17);  
  35.   
  36.     glPushMatrix();  
  37.     // Rotate from Earth based coordinates and draw Moon  
  38.     glColor3ub(200,200,200);  
  39.     glRotatef(fMoonRot,0.0f, 1.0f, 0.0f);  
  40.     glTranslatef(30.0f, 0.0f, 0.0f);  
  41.     fMoonRot+= 15.0f;  
  42.     if(fMoonRot > 360.0f)  
  43.         fMoonRot = 0.0f;  
  44.     glutSolidSphere(6.0f, 30, 17);  
  45.     glPopMatrix();  
  46.   
  47.     glColor3ub(100, 250, 0);  
  48.     glRotatef(fMoonRot, 1.0f, 0.0f, 0.0f);  
  49.     glTranslatef(0.0f, 20.0f, 0.0f);  
  50.     glutSolidSphere(6.0f, 30, 17);  
  51.   
  52.     // Restore the matrix state  
  53.     glPopMatrix();  // Modelview matrix  
  54.   
  55.     // Step earth orbit 5 degrees  
  56.     fEarthRot += 5.0f;  
  57.     if(fEarthRot > 360.0f)  
  58.         fEarthRot = 0.0f;  
  59.   
  60.     // Show the image  
  61.     glutSwapBuffers();  
  62. }  

实现效果图:

opengl glPushMatrix()[通俗易懂]

opengl glPushMatrix()[通俗易懂]

opengl glPushMatrix()[通俗易懂]

opengl glPushMatrix()[通俗易懂]

opengl glPushMatrix()[通俗易懂]

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/206840.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Tomcat调优总结

    Tomcat调优总结Tomcat优化分为系统优化,Java虚拟机调优,Tomcat本身的优化。

  • Word2vec负采样

    Word2vec负采样下文中的模型都是以Skip-gram模型为主。1、论文发展word2vec中的负采样(NEG)最初由Mikolov在论文《DistributedRepresentationsofWordsandPhrasesandtheirCompositionality》中首次提出来,是Noise-ContrastiveEstimation(简写NCE,噪声对比估计)的简化版本…

  • 列举出linux文件和目录常用的命令_查看centos根目录下有哪些内容

    列举出linux文件和目录常用的命令_查看centos根目录下有哪些内容目录命令总览ls(英文全拼:listfiles):列出目录及文件名cd(英文全拼:changedirectory):切换目录pwd(英文全拼:printworkdirectory):显

  • 激光雷达(二)——三角测距法和TOF原理

    激光雷达(二)——三角测距法和TOF原理对于市面上的主流激光雷达,主要是用于环境探测、地图构建,按技术路线可分为:三角测距激光雷达,TOF激光雷达。三角测距激光雷达原理三角法的原理如下图所示,激光器发射激光,在照射到物体后,反射光由线性CCD接收,由于激光器和探测器间隔了一段距离,所以依照光学路径,不同距离的物体将会成像在CCD上不同的位置。按照三角公式进行计算,就能推导出被测物体的距离。CCD是ChargeCoupled…

  • Mysql | 数据库锁表的原因和解决方法「建议收藏」

    Mysql | 数据库锁表的原因和解决方法「建议收藏」锁表的原因:当多个连接(数据库连接)同时对一个表的数据进行更新操作,那么速度将会越来越慢,持续一段时间后将出现数据表被锁的现象,从而影响到其它的查询及更新。  例如:存储过程循环30次更新操作(cycore_file_id为唯一标识)/*30次更新操作*/BEGINDECLAREv1INTDEFAULT30;WHILEv1>0DOu…

  • 谷歌的api_谷歌浏览器添加搜索引擎

    谷歌的api_谷歌浏览器添加搜索引擎1.搜索引擎API接口地址为https://www.proxy.ustclug.org/customsearch/v1?key={YOUR_KEY}&q={SEARCH_WORDS}&cx={YOUR_CX}&start={10}&num={10}通过谷歌可编程搜索引擎自定义个人搜索引擎,并且记住搜索引擎的CXid。创建后即可根据项目中的apiid,查询链接console.cloud.google.com根据CXid和apiid,即可调用定义好的搜索引擎

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号