文档章节

为什么调用glPushMatrix()和glPopMatrix()

Kobe_Gong_5
 Kobe_Gong_5
发布于 2015/06/20 00:45
字数 856
阅读 2
收藏 0

今天忽然感悟到为什么在进行变换之前要用glPushMatrix();这个函数,而在变换完毕后有用glPopMatrix()这两个函数了,赶紧记下来:

    我们在变换坐标的时候,使用的是glTranslatef(),glRotaef()等函数来操作,操作的是什么呢?操作的是当前矩阵,我们也知道,这些坐标变换(翻转,旋转也好)都是通过操作矩阵来实现的,而矩阵相乘是会叠加的,当你用完一个变换函数后,当前操作的矩阵就被改变了,当你还停留在变换以前的思维,我在这个地方绘制恰好是我想要的时候,你会发现再绘制出来的不是在你想要的位置,因为你在操作变换的时候,当前矩阵被改变了。

   比如你在默认情况下在原点画了一个球,然后又进行了一个变换,比如用glTranslatef( 0.0, 0.0, 1.0 );沿z轴移动一定距离又画了一个球,然后你想再在原点画一个大一点的球覆盖原来的那个,当你绘制的时候就会发现,你现在绘制的球已不在你想像的地方了。

我们来做个实验:

代码如下:

void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glShadeModel( GL_SMOOTH );

//现在原点绘制一个红色正方形
glColor3f( 1.0, 0.0, 0.0 );
glRectf( -0.05, -0.05, 0.05, 0.05 );

//glPushMatrix();

//变换--沿x轴移动
    glTranslatef( 0.2, 0.0, 0.0 );

    //glPopMatrix();

//再绘制一个正方形
glColor3f( 0.0, 1.0, 0.0 );
glRectf( -0.05, -0.05, 0.05, 0.05 );//这时,当我们还想在同样位置绘制时,却发现已经偏移

glFlush();
}

 

    当我们把glPushMatrxi()和glPopMatrix()注释掉以后我们发现,当我们再想在同样的位置绘制一个正方形的时候,就会发现已经按我们的glTransfef()所指定的沿x轴偏移了0.2个单位。

而当我们不把两句函数调用注释掉时,运行发现,绿色的正方形覆盖了原来的红色的正方形。

 

所以,这两个函数的压栈弹栈是有用地~~~~~~~~~~

这两个函数的具体的执行方式就不扯了,网上n多。

知之为知之,不知百度之

~~~~~~~~~~~~吼吼~~~~~~~~~~

续文:

顿悟这点以后,晚上又突然想明白了另一个大问题:移动光源的位置。

在顿悟以前,总觉得光源该怎么移动呢?那不是十分十分麻烦么,而且不知道怎么办,现在明白了这个道理以后,光照的移动就简单了。

移动方式:

      先pushMatrix()一下,然后在进行移动操作,然后旋转操作,然后指定光源的位置,然后PopMatrix()一下,就完成了。

测试代码:

#include <gl/glut.h>

static int spin = 0;

void init()
{
glShadeModel( GL_SMOOTH );
    glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_DEPTH_TEST );

}

void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };

glPushMatrix();
glTranslatef( 0.0, 0.0, -5.0 );

glPushMatrix();
glRotated( (GLdouble)spin, 1.0, 0.0, 0.0 );
glLightfv( GL_LIGHT0, GL_POSITION, position );
glTranslated( 0.0, 0.0, 1.5 );
glDisable( GL_LIGHTING );
glColor3f( 0.0, 1.0, 0.0 );
glutWireCube( 0.1 );//绿色的下框,代表光源位置
glEnable( GL_LIGHTING );
glPopMatrix();

glutSolidSphere( 0.5, 40, 40 );//被光照的物体
glPopMatrix();
glFlush();
}

void reshape( int w, int h )
{
    glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}

void mouse( int button, int state, int x, int y )
{
switch ( button )
{
case GLUT_LEFT_BUTTON:
   if ( state == GLUT_DOWN )
   {
    spin = ( spin + 30 ) % 360;
    glutPostRedisplay();
   }
   break;
default:
   break;
}
}

int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 500, 500 );
glutCreateWindow( argv[0] );
init();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
glutMainLoop();
return 0;
}

© 著作权归作者所有

共有 人打赏支持
Kobe_Gong_5
粉丝 2
博文 55
码字总数 43587
作品 0
成都
android 3D游戏开发-glPushMatrix() glPopMatrix()

1 、 在opengl中,函数glTranslatef的作用就是移动坐标原点。对应的3个参数对应着3个坐标轴。就是使绘图坐标系相对世界坐标系沿x,y,z轴移动x,y,z个单位。 如果你调用一次glTranslatef(1.0f,0...

长平狐
2012/08/29
359
0
【初学者】openGL的物体转速不一样

就是如下代码里面 MyDisplay()中的第二段for循环的内容执行与否 为什么会影响第一段的物体的转速?不明白 如果把第二段for循环注释了,就会发现转速变了。。。 include include include incl...

Michaelwpf
2016/05/17
126
0
OpenGL绘制的几类三维实体

OpenGL绘制的几类三维实体 EXAM304_H //防止重复嵌入 #if !defined EXAM304H_ #define EXAM304H_ //指定嵌入文件 #include<gl/glut.h> #include<math.h> //宏 #define RADIUS 50.0f #define......

小青_1989
2014/04/09
0
0
《基于MFC的OpenGL编程》Part 5 Transformations - Rotations, Translations and Scaling

Transformations - Translation, Rotation and Scaling Translation is nothing but moving along an arbitrary axis. Rotation is spinning about an arbitrary axis. Scaling is increase ......

嗯哼9925
2017/12/21
0
0
《基于MFC的OpenGL编程》Part 7 Animation

本文中将对第5篇文章的太阳系模型进行修改,加入一些动画效果。此外还会加入显示帧速率的代码。 加入动画效果最容易的方法是响应WM_TIMER消息,在其消息处理函数中改变一些参数值,比如每过多...

嗯哼9925
2017/12/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

中国发布域名系统基础软件 “红枫”

9月12日消息,域名工程中心(英文缩写 ZDNS)发布了宣称自主开发的域名系统基础软件 “红枫(Maple DNS)”。 9月12日消息,域名工程中心(英文缩写 ZDNS)发布了宣称自主开发的域名系统基础软...

问题终结者
18分钟前
1
0
Shell编程(分发系统介绍、expect远程登录、expect远程执行命令、expect传递参数)

分发系统介绍expect 分发系统expect即分发脚本,是一种脚本语言;通过他可以实现传输,输入命令(上线代码) 应用场景:业务越来越大,网站app,后端,编程语言是php,所以就需要配置lamp或者...

蛋黄_Yolks
23分钟前
1
0
Java Http请求工具类

public static String httpPost(String source, String params) {URL url = null;HttpURLConnection conn = null;OutputStream os = null;String ret = null;try {......

yuewawa
29分钟前
1
0
C++11 智能指针

C++11提供了三个智能指针,std::shared_ptr,std::unique_ptr,std::weak_ptr。最常用的是shared_ptr和unique_ptr。 (1)std::shared_ptr shared_ptr是共享指针,通过在控制块中增加引用计数...

yepanl
30分钟前
1
0
React 服务器渲染原理解析与实践

网盘下载地址 React 服务器渲染原理解析与实践 本套课程,讲解了React中SSR技术的整个搭建思路及流程,完整的从原理上讲清楚了SSR的概念,重点在于讲解编写SSR框架遇到的各种知识点,以及细节...

qq__2304636824
42分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部