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

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

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

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


相关推荐

  • wireshark抓包教程详解[通俗易懂]

    wireshark抓包教程详解[通俗易懂]wireshark抓包新手使用教程Wireshark是非常流行的网络封包分析软件,可以截取各种网络数据包,并显示数据包详细信息。常用于开发测试过程各种问题定位。本文主要内容包括:1、Wireshark软件下载和安装以及Wireshark主界面介绍。2、WireShark简单抓包示例。通过该例子学会怎么抓包以及如何简单查看分析数据包内容。3、Wireshark过滤器使用。过滤器包含两种类型,一种是抓包过滤器,就是抓取前设置过滤规则。另外一种是显示过滤器,就是在数据包分析时进行过…

    2022年9月7日
    2
  • pycharm 修改镜像源_如何设置linux服务器镜像源

    pycharm 修改镜像源_如何设置linux服务器镜像源由于国外的镜像源安装Python速度较慢,选择国内的镜像速度较快,这篇文章如要讲述如何设置国内镜像源。常用镜像源:清华:https://pypi.tuna.tsinghua.edu.cn/simple阿里云:http://mirrors.aliyun.com/pypi/simple/中国科技大学https://pypi.mirrors.ustc.edu.cn/simple/方法一:…

    2022年8月29日
    5
  • 2021年最新PHP 面试、笔试题汇总(一)[通俗易懂]

    2021年最新PHP 面试、笔试题汇总(一)

    2022年2月18日
    52
  • 久坐提醒软件_久坐提醒app安卓版

    久坐提醒软件_久坐提醒app安卓版作为苦逼的程序员,每天都要久坐好多个小时,经常一不小心一天就过去了,一直坐着对腰非常不友好,在网上搜了几个久坐提醒的软件,都不太合适自己用,干脆就自己写了个软件,定时提醒自己起来休息一下。软件可自定义提醒的时间间隔,界面可点击开始计时、停止计时,重新开始计时,可设置开程序自动开始计时,最小化可隐藏到托盘,界面按钮均支持快捷键,支持windows消息提醒。最近自己一直在使用,以后有空再更新一些内容,让软件更好用一点。使用环境:Windows,dotnetframework4.5.1快捷键:开始

    2022年10月1日
    2
  • struts2拦截器不执行问题「建议收藏」

    struts2拦截器不执行问题「建议收藏」struts2自定义拦截器的配置博文很多,但按一些文章中配置好自定义拦截器后,设置为默认拦截器栈,拦截器方法intercept()却未被调用的问题,原因多种,以下为我问题的解决方式:配置struts2.xml加上原来其他项目中同样的配置却没出现不能被执行的问题,xml配置都差不多,可能深层问题在于action中注解的各项配置引发,有空再验证。参考:http://struts

    2022年10月7日
    4
  • 分享ArcGis For Flex API 1.3 Diagram

    分享ArcGis For Flex API 1.3 Diagram

    2021年8月2日
    59

发表回复

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

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