使用glPushMatrix和glPopMatrix的原因
转自 百度百科
1. 原理讲解
2 举例
#include "windows.h"
#include <gl/glut.h>
static int spin = ;
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 };
//第一点也是最重要的一点:OpenGL中的模型视图变换矩阵全是右乘当前变换矩阵
glPushMatrix(); //将当前变换矩阵(单位阵)压入堆栈
glTranslatef( 0.0, 0.0, -5.0 ); // transformation 1
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(); //消除绘制绿色WireCube时对当前变换矩阵的影响
glutSolidSphere( 0.5, , );//以被光照的物体
glPopMatrix(); // Pop the old matrix without the transformations. //返回到单位矩阵
glFlush();
}
void reshape( int w, int h )
{
glViewport( , , (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 + ) % ;
glutPostRedisplay();
}
break;
default:
break;
}
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
glutInitWindowPosition( , );
glutInitWindowSize( , );
glutCreateWindow( argv[] );
init();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
glutMainLoop();
return ;
}
#include "windows.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
void myinit(void);
void drawPlane(void);
void CALLBACK elbowAdd (void);
void CALLBACK elbowSubtract (void);
void CALLBACK shoulderAdd (void);
void CALLBACK shoulderSubtract (void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
static int shoulder = , elbow = ;
void CALLBACK elbowAdd (void)
{
elbow = (elbow + ) % ;
}
void CALLBACK elbowSubtract (void)
{
elbow = (elbow - ) % ;
}
void CALLBACK shoulderAdd (void)
{
shoulder = (shoulder + ) % ;
}
void CALLBACK shoulderSubtract (void)
{
shoulder = (shoulder - ) % ;
}
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 1.0);
glPushMatrix(); // 将此句注释掉后可以发现上一次的变换结果对当前变换有影响,加上了glPushMatrix的目的是让各次变换相互独立。
glTranslatef (-0.5, 0.0, 0.0); // 将旋转后的Wirebox向左移动0.5个单位
glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0); //看到shoulder是相对于0的绝对角度,不是基于上一次位置的相对角度。
glTranslatef (1.0, 0.0, 0.0); //Step 1将WireBox向右移动一个单位
// void auxWireBox(GLdouble width,GLdouble height,GLdouble depth)
auxWireBox(2.0, 0.2, 0.5); //这个WireBox以x=1为中心,width=2从该中心开始向两边各延伸1个单位。
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
glTranslatef (0.8, 0.0, 0.0);
auxWireBox(1.6, 0.2, 0.5);
glPopMatrix(); // 可以看出glPushMatrix和glPopMatrix之间的变换效果被消除。清除上一次对modelview矩阵的修改。
glFlush();
}
void myinit (void)
{
glShadeModel (GL_FLAT);
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
glViewport(, , w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0, -5.0); /* 认为是viewing transform 不好理解,因此时是物体不动,世界坐标系向z轴正方向移动5个单位,眼睛位于世界坐标系的原点; 此处理解为对模型的变换更加直观既将物体向负z轴移动5个单位。*/
}
void main(void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
auxInitPosition (, , , );
auxInitWindow ("Composite Modeling Transformations");
myinit ();
auxKeyFunc (AUX_LEFT, shoulderSubtract);
auxKeyFunc (AUX_RIGHT, shoulderAdd);
auxKeyFunc (AUX_UP, elbowAdd);
auxKeyFunc (AUX_DOWN, elbowSubtract);
auxReshapeFunc (myReshape);
auxMainLoop(display);
}
使用glPushMatrix和glPopMatrix的原因的更多相关文章
- OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数详解
OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的.opengl中的变换一般包括视图变换.模型变换.投影变换等,在每次变换后,opengl将会呈 ...
- OpenGL中glPushMatrix和glPopMatrix的原理
glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...
- 通俗解释glLoadIdentity(),glPushMatrix(),glPopMatrix()的作用
通俗解释glLoadIdentity(),glPushMatrix(),glPopMatrix()的作用 (2012-04-02 09:17:28) 转载▼ 对于glLoadIdentity(), ...
- opengl入门学习
OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...
- OpenGL入门学习(转)
OpenGL入门学习 http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 说起编程作图,大概还有很多人想起TC的#includ ...
- OpenGL------三维变换
我们生活在一个三维的世界——如果要观察一个物体,我们可以:1.从不同的位置去观察它.(视图变换)2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它.(模型变换)3.如果把物 ...
- OpenGL理解
说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...
- OpenGL入门学习(转载)
说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...
- openGl 基础
最近由于手机项目中需要用到OpenGL ES的知识,所以这段时间正在研究OpenGL的相关知识.因为OpenGL ES是OpenGL的剪裁版本,所以我直接从OpenGL入手,然后再去看OpenGL E ...
随机推荐
- lsof 命令简介
losf 命令可以列出某个进程打开的所有文件信息.打开的文件可能是普通的文件,目录,NFS文件,块文件,字符文件,共享库,常规管道,明明管道,符号链接,Socket流,网络Socket,UNIX域So ...
- NetworkX-根据权重画图
load_data = sio.loadmat(load_path) #阈值处理 mat=np.array(load_data['R']) mat[mat<0]=0 mat[mat<0.4 ...
- 服务器搭建域控与SQL Server的AlwaysOn环境过程(三)配置故障转移
0 引言 主要讲述如何搭建故障转移集群,因为AlwaysOn是基于Windows的故障转移集群的. 在讲解步骤之前需要了解一下故障转移集群仲裁配置 下面图片来自<Windows Server20 ...
- (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树
题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...
- [agc004d]salvage robot
题意: 别问我谁翻译的 虫合虫莫国的领土我们可以抽象为H*W的笼子,在这虫合土上,有若干个机器人和一个出口,其余都是空地,每次虫合虫莫会要求让所有的机器人向某个方向移动一步,当机器人移动到出口时会被虫 ...
- mycat详细
MyCAT的优势基于阿里开源的Cobar产品而研发,Cobar的稳定性.可靠性.优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远.业界优 ...
- redhat下搭建jdk+tomcat环境
由于redhat自带安装了jdk,我们需要现将其进行卸载 卸载系统自带的jdk版本: 查看自带的jdk: 输入命令:rpm -qa|grep gcj 可能看到如下类似的信息: libgcj-4.1.2 ...
- P2899 [USACO08JAN]手机网络Cell Phone Network
P2899 [USACO08JAN]手机网络Cell Phone Networ题目描述 Farmer John has decided to give each of his cows a cell ...
- ASIHTTPRequest 框架的导入
刚接触ios 对一切都不熟悉 记录一下ASIHTTPRequest 框架的导入 步骤 以便日后再用 1.首先下载ASIHTTPRequest:点击下载 2.在project中导入下面文件: 导入方式 ...
- 安卓开发,adb shell 调试sqlite3数据库
安卓开发,adb shell 调试sqlite3数据库 在安卓中创建了sqlite3数据库,想要调试怎么办? 通过adb shell来进行查看. 第一步,将adb加入到系统变量中. 这样就可以在命令行 ...