OpenGL里的矩阵堆栈(MVP的初始化以及后续更改M,V,P的操作)
创始人
2024-06-01 10:22:17
0

OpenGL矩阵堆栈

是OpenGL用于进行矩阵变换的一种机制,它包括模型视图矩阵堆栈和投影矩阵堆栈两种类型的矩阵堆栈。每个矩阵堆栈都可以通过调用glMatrixMode函数来进行切换。一旦切换到某个矩阵堆栈,所有的矩阵操作都会作用于该矩阵堆栈。

M模型矩阵:模型矩阵(Model Matrix)用于描述物体在世界坐标系中的位置、方向和大小等属性。通过对模型矩阵进行变换,可以实现物体的平移、旋转和缩放等效果。

glTranslatef:对模型矩阵进行平移变换;
glRotatef:对模型矩阵进行旋转变换;
glScalef:对模型矩阵进行缩放变换。
这些函数可以将变换矩阵乘以当前的模型矩阵,从而实现对模型矩阵的变换。例如,通过调用glTranslatef(x, y, z)函数,可以将模型矩阵右乘一个平移矩阵,实现对模型的平移变换。同样的道理,通过调用glRotatef(angle, x, y, z)函数,可以将模型矩阵右乘一个旋转矩阵,实现对模型的旋转变换;通过调用glScalef(sx, sy, sz)函数,可以将模型矩阵右乘一个缩放矩阵,实现对模型的缩放变换。
除了上述函数之外,我们还可以通过调用glLoadMatrixf函数或glMultMatrixf函数,直接加载或乘以一个指定的变换矩阵,来对模型矩阵进行变换。通过这些函数的组合,我们可以实现复杂的模型变换,从而创建出各种形态的3D场景。

V视图矩阵:视图矩阵(View Matrix)用于描述摄像机在世界坐标系中的位置和方向等属性。通过对视图矩阵进行变换,可以实现摄像机的移动、旋转和缩放等效果。

gluLookAt:对视图矩阵进行相机变换,即描述摄像机在场景中的位置、方向和朝向。
void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz);
eyeX, eyeY, eyeZ:摄像机的位置坐标;
centerX, centerY, centerZ:摄像机的观察点坐标,即相机所看向的点;
upX, upY, upZ:相机的上方向向量,用于确定相机的朝向。

通过调用gluLookAt函数,我们可以实现对视图矩阵的变换,从而实现对场景的观察和渲染。除了gluLookAt函数之外,我们还可以通过调用glTranslatef、glRotatef和glScalef(平移旋转缩放)等函数,对视图矩阵进行变换。这些函数同样是将变换矩阵右乘到当前的视图矩阵中,从而实现对视图矩阵的变换。
(在OpenGL中,视图矩阵是描述摄像机在世界坐标系中的位置和方向等属性,而不是描述物体在摄像机坐标系中的位置和方向等属性。)

P透视矩阵:投影矩阵(Projection Matrix)用于描述将3D场景投影到2D平面的方式和参数。通过对投影矩阵进行变换,可以实现对场景的投影和呈现。

glFrustum:定义一个透视投影矩阵,使得视景体内的物体根据距离大小有不同的大小;
glOrtho:定义一个正交投影矩阵,使得视景体内的物体大小不会因为距离的远近而有所变化;
gluPerspective:定义一个透视投影矩阵,用于指定视景体内部的各个物体在投影平面上的大小和位置。
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
第一个参数fovy表示视角(Field of View,FOV),用于指定视场的大小,单位是度(degree);第二个参数aspect表示宽高比(Aspect Ratio),用于指定视图的宽高比,即视口的宽度与高度之比;第三个参数zNear表示近裁剪面(Near Clipping Plane),用于指定从摄像机到近裁剪面的距离;第四个参数zFar表示远裁剪面(Far Clipping Plane),用于指定从摄像机到远裁剪面的距离。
除了上述函数之外,我们还可以通过调用glLoadMatrixf函数或glMultMatrixf函数,直接加载或乘以一个指定的变换矩阵,来对投影矩阵进行变换。通过这些函数的组合,我们可以实现复杂的投影变换,从而创建出各种形态的3D场景。

这三个矩阵在opengl中的初始化以及后续操作顺序

在OpenGL中,通常的矩阵堆栈操作顺序为先对投影矩阵(P矩阵)进行初始化和操作,再对视图矩阵(V矩阵)进行初始化和操作,最后对模型矩阵(M矩阵)进行初始化和操作。
(1)通过glMatrixMode(GL_PROJECTION)设置当前矩阵模式为投影矩阵模式,并通过glLoadIdentity()清空投影矩阵堆栈,以便进行后续操作。
(2)通过gluPerspective()等函数设置投影矩阵的具体参数,如视角、宽高比、近裁剪面和远裁剪面等。
(3)通过glMatrixMode(GL_MODELVIEW)设置当前矩阵模式为视图矩阵模式,并通过glLoadIdentity()清空视图矩阵堆栈,以便进行后续操作。
(4)通过gluLookAt()等函数设置视图矩阵的具体参数,如摄像机的位置、观察点和上方向向量等。
(5)通过对模型矩阵进行平移、旋转、缩放等变换操作,对场景进行模型变换。这些操作通过对模型矩阵堆栈的操作实现。
(6)最后,通过将投影矩阵、视图矩阵和模型矩阵依次相乘的方式,得到最终的变换矩阵,并将其传递给渲染管线进行处理和渲染。
需要注意的是,OpenGL的矩阵堆栈操作遵循右乘的顺序,即先进行的变换操作会先被应用。因此,在对模型矩阵进行操作时,需要注意操作顺序,以确保得到正确的渲染结果。

在我们渲染中更改M,V,P的话

在OpenGL中,每次更改M、V或P矩阵时,并不需要完整地重新走一遍设置矩阵的流程,而只需要在相应的矩阵堆栈中压入或弹出一个新的矩阵,或者通过矩阵乘法等操作对已有的矩阵进行修改。
具体来说,当需要更改M、V或P矩阵时,可以通过glMatrixMode()函数将当前的矩阵模式切换到相应的模式(如GL_MODELVIEW或GL_PROJECTION),并通过glPushMatrix()或glPopMatrix()函数压入或弹出一个新的矩阵,或者通过glLoadMatrix()或glMultMatrix()等函数直接修改已有的矩阵。
例如,当需要更改模型矩阵M时,可以通过以下步骤完成:
(1)通过glMatrixMode(GL_MODELVIEW)将当前的矩阵模式切换到模型视图矩阵模式。
(2)通过glPushMatrix()函数将当前的模型矩阵压入堆栈中,以便后续操作。
(3)通过glTranslatef()、glRotatef()、glScalef()等函数对模型矩阵进行变换操作。
(4)通过glPopMatrix()函数弹出新的模型矩阵,并将其与视图矩阵和投影矩阵相乘,得到最终的变换矩阵,传递给渲染管线进行处理和渲染。
当需要修改视图矩阵V时,可以通过以下步骤完成:
(1)通过glMatrixMode(GL_MODELVIEW)将当前的矩阵模式切换到模型视图矩阵模式。
(2)通过glLoadIdentity()函数将当前的视图矩阵堆栈清空,以便进行后续操作。
(3)通过gluLookAt()函数设置新的视图矩阵参数,如摄像机的位置、观察点和上方向向量等。
(4)将新的视图矩阵压入堆栈中,以便后续渲染操作。
(5)将投影矩阵、视图矩阵和模型矩阵依次相乘,得到最终的变换矩阵,并将其传递给渲染管线进行处理和渲染。
需要注意的是,在修改视图矩阵时,需要将当前的视图矩阵堆栈清空,以便进行新的操作。如果不清空堆栈,会导致新的视图矩阵和旧的视图矩阵相乘,从而产生错误的变换效果。
注释:在修改视图矩阵V时,模型矩阵M中的变换操作是不会受到影响的,这些变换操作会一直保留下来,直到再次对模型矩阵进行修改。这是因为视图矩阵V和模型矩阵M是两个独立的矩阵,它们分别对应着场景中的视角和物体的位置、旋转、缩放等变换操作。
当需要修改投影矩阵P时,可以按照以下步骤进行操作:
(1)将矩阵模式切换为投影矩阵模式:glMatrixMode(GL_PROJECTION)
(2)将堆栈清空:glLoadIdentity()
(3)根据具体需求设置新的投影矩阵P,例如使用gluPerspective()函数设置透视投影矩阵:gluPerspective(fovy, aspect, zNear, zFar)
(4)将新的投影矩阵P加载到当前矩阵堆栈的顶部:glLoadMatrixf§

修改MVP都是独立的操作,分别对应着模型坐标系、观察坐标系和投影坐标系的变换。因为每个坐标系的变换方式和需求不同,所以这三个矩阵是相互独立的,修改一个矩阵不会影响到其他矩阵。
在渲染过程中,**首先根据模型矩阵M将顶点从模型坐标系变换到世界坐标系,然后根据视图矩阵V将顶点从世界坐标系变换到观察坐标系,最后根据投影矩阵P将顶点从观察坐标系变换到裁剪坐标系,并进行透视或正交投影。**这些变换都是独立的,每个矩阵都承担着自己的角色。

(在OpenGL之外,一般采用左乘的方式进行矩阵变换。左乘的方式指的是先将变换矩阵乘以当前矩阵,再将乘积矩阵作为当前矩阵。左乘的方式适用于行向量,可以看作是在左边乘以变换矩阵。
相比之下,OpenGL中使用的右乘方式适用于列向量,可以看作是在右边乘以变换矩阵。右乘的方式可以将矩阵乘法表示为矩阵乘向量的形式,便于在渲染管线中进行优化。
因此,在OpenGL之外,如果需要进行矩阵变换,一般采用左乘的方式进行,而在OpenGL中,采用右乘的方式进行矩阵变换。需要注意的是,如果将左乘的方式应用于OpenGL中,可能会导致渲染结果出现错误。)

相关内容

热门资讯

Python|位运算|数组|动... 目录 1、只出现一次的数字(位运算,数组) 示例 选项代...
张岱的人物生平 张岱的人物生平张岱(414年-484年),字景山,吴郡吴县(今江苏苏州)人。南朝齐大臣。祖父张敞,东...
西游西后传演员女人物 西游西后传演员女人物西游西后传演员女人物 孙悟空 六小龄童 唐僧 徐少华 ...
名人故事中贾岛作诗内容简介 名人故事中贾岛作诗内容简介有一次,贾岛骑驴闯了官道.他正琢磨着一句诗,名叫《题李凝幽居》全诗如下:闲...
和男朋友一起优秀的文案? 和男朋友一起优秀的文案?1.希望是惟一所有的人都共同享有的好处;一无所有的人,仍拥有希望。2.生活,...
戴玉手镯的好处 戴玉手镯好还是... 戴玉手镯的好处 戴玉手镯好还是碧玺好 女人戴玉?戴玉好还是碧玺好点佩戴手镯,以和田玉手镯为佳!相嫌滑...
依然什么意思? 依然什么意思?依然(汉语词语)依然,汉语词汇。拼音:yī    rán基本解释:副词,指照往常、依旧...
高尔基的散文诗 高尔基的散文诗《海燕》、《大学》、《母亲》、《童年》这些都是比较出名的一些代表作。
心在飞扬作者简介 心在飞扬作者简介心在飞扬作者简介如下。根据相关公开资料查询,心在飞扬是一位优秀的小说作者,他的小说作...
卡什坦卡的故事赏析? 卡什坦卡的故事赏析?讲了一只小狗的故事, 我也是近来才读到这篇小说. 作家对动物的拟人描写真是惟妙...
林绍涛为简艾拿绿豆糕是哪一集 林绍涛为简艾拿绿豆糕是哪一集第三十二集。 贾宽认为是阎帅间接导致刘映霞住了院,第二天上班,他按捺不...
小爱同学是女生吗小安同学什么意... 小爱同学是女生吗小安同学什么意思 小爱同学,小安同学说你是女生。小安是男的。
内分泌失调导致脸上长斑,怎么调... 内分泌失调导致脸上长斑,怎么调理内分泌失调导致脸上长斑,怎么调理先调理内分泌,去看中医吧,另外用好的...
《魔幻仙境》刺客,骑士人物属性... 《魔幻仙境》刺客,骑士人物属性加点魔幻仙境骑士2功1体质
很喜欢她,该怎么办? 很喜欢她,该怎么办?太冷静了!! 太理智了!爱情是需要冲劲的~不要考虑着考虑那~否则缘...
言情小说作家 言情小说作家我比较喜欢匪我思存的,很虐,很悲,还有梅子黄时雨,笙离,叶萱,还有安宁的《温暖的玄》 小...
两个以名人的名字命名的风景名胜... 两个以名人的名字命名的风景名胜?快太白楼,李白。尚志公园,赵尚志。
幼儿教育的代表人物及其著作 幼儿教育的代表人物及其著作卡尔威特的《卡尔威特的教育》,小卡尔威特,他儿子成了天才后写的《小卡尔威特...
海贼王中为什么说路飞打凯多靠霸... 海贼王中为什么说路飞打凯多靠霸气升级?凯多是靠霸气升级吗?因为之前刚到时确实打不过人家因为路飞的实力...
运气不好拜财神有用吗运气不好拜... 运气不好拜财神有用吗运气不好拜财神有没有用1、运气不好拜财神有用。2、拜财神上香前先点蜡烛,照亮人神...