glPushMatrix()和glPopmatirx()

原文地址:http://blog.csdn.net/tyxkzzf/article/details/40907273OpenGL有三个矩阵堆栈,分别是GL_MODELVIEW(模型视图矩阵堆栈)、GL_PROJECTION(投影矩阵堆栈)、GL_TEXTURE(纹理矩阵堆栈),用法和普通堆栈一样;这里我们只讲模型视图矩阵堆栈,OpenGL提供了相应的接口:glPushMatir

大家好,又见面了,我是你们的朋友全栈君。

原文地址:http://blog.csdn.net/tyxkzzf/article/details/40907273

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

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

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

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

glPushMatrix()和glPopmatirx()

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

实现效果图:

glPushMatrix()和glPopmatirx()

glPushMatrix()和glPopmatirx()

glPushMatrix()和glPopmatirx()

glPushMatrix()和glPopmatirx()

glPushMatrix()和glPopmatirx()

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

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125895.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • phpstrom2021 激活码【2021最新】

    (phpstrom2021 激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月22日
    48
  • pytest重试_手机qq插件加载失败

    pytest重试_手机qq插件加载失败安装:pip3installpytest-rerunfailures重新运行所有失败用例要重新运行所有测试失败的用例,请使用–reruns命令行选项,并指定要运行测试的最大次数:$py

    2022年7月31日
    8
  • 初识ABP vNext(5):ABP扩展实体

    初识ABP vNext(5):ABP扩展实体

    2020年11月20日
    184
  • 理解dropout

    理解dropout开篇明义,dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。dropout是CNN中防止过拟合提高效果的一个大杀器,但对于其为何有效,却众说纷纭。在下读到两篇代表性的论文,代表两种不同的观点,特此分享给大家。

    2022年4月27日
    44
  • 智能避障小车_单片机智能小车程序

    智能避障小车_单片机智能小车程序      接下来我对所用的模块以及小车的硬件部分做一个讲解        小车的总体效果图如下:      首先是模块简介:            1、首先就是L298N,这是一个经典的电机驱动,相信基本所有玩过单片机,玩过电机的人都使用过,它可以最高容忍15v电压输入,逻辑电平2.4-5.5v,所以使用单片机的3.3v完全可以驱动,它并没有PWM接口来控制电机的速度,只能使逻辑电平输出…

    2022年10月17日
    2
  • fault.java.lang_如何解决mapping exception to axisfault

    fault.java.lang_如何解决mapping exception to axisfault这个涉及到两个地方,action和JS:我一般是这样写的,小例子,希望能对你有用:action:publicActionForwardgetFiled(ActionMappingmapping,ActionFormform,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{Strings…

    2025年11月5日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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