ImageVerifierCode 换一换
格式:DOCX , 页数:10 ,大小:98.94KB ,
资源ID:3786621      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3786621.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(OpenGL学习脚印 关于gluLookAt函数的理解.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

OpenGL学习脚印 关于gluLookAt函数的理解.docx

1、OpenGL学习脚印 关于gluLookAt函数的理解OpenGL学习脚印: 关于gluLookAt函数的理解写在前面 本节借助gluLookAt函数,推导世界坐标转换到照相机坐标的一种方法,重点在于理解UVN相机坐标系,以及变换矩阵的推导。限于笔者水平,如果错误 请纠正我。 gluLookAt函数提供给用户完成模式变换(model-view transformation)中,在将模型坐标系转换都世界坐标系后,进行世界坐标系到照相机坐标系的转换。实际上,照相机的定位也是在世界坐标系下定 义的,这里的转换,可以理解为:从照相机的角度解释世界坐标系中物体的坐标。通过构造一个UVN坐标系来简化这一转

2、换。先直观感受下UVN,UVN坐标系中的照相机模型如下图所示:借助下图正式定义UVN相机坐标系: 与UVN相关的概念包括: 相机位置,或者叫做视点(eyepoint): 观察参考点 (View Reference Point) 相机镜头方向,通过观察平面的法向量指定: 观察平面法向量VPN (View Plane Normal) 相机顶部正朝向:VUV (View Up Vector)形象的表达为: gluLookAt函数原型为: cpp view plaincopyprint?1. voidgluLookAt(GLdoubleeyeX,GLdoubleeyeY,GLdoubleeyeZ,2.

3、 3. GLdoublecenterX,GLdoublecenterY,GLdoublecenterZ,4. 5. GLdoubleupX,GLdoubleupY,GLdoubleupZ);官网关于此函数的描述:gluLookAt 通过指定一个视点、表面场景中心的参考点以及up向量来构造一个视变换矩阵。这个矩阵将代表场景中心的参考点映射到-Z轴,视点映射成为原点。当使用一个特定的投影矩阵时,场景的中心就映射到视口的中心。类似地,由up向量描述的方向投影到投影平面成为+y轴,这样它在视口中向上指向。up向量必须不能与从视点到参考点的直线平行。 那么如何确定u-v-n坐标系呢?计算公式如下: 这里

4、需要注意: OpenGL中使用的相机坐标系是右手坐标系,UVN坐标系是左手坐标系。在构造实际变换矩阵的过程中,OpenGL需要将-n轴翻转为相机坐标系的+z轴,uv轴定位相机坐标系的+x和+y轴。这与推导相机变换矩阵一文最后的结果矩阵有所不同。如何构造视变换矩阵?视变换就是在相机坐标系下解释世界坐标系下的点。而这个变换矩阵的构造,可以看做将相机坐标系变换到与原来的世界坐标系重合。而将世界坐标系变换到与相机坐标系重合,可以看做是这个所求变换的逆过程。 将世界坐标系变换到与相机坐标系重合,实际上进行了两个步骤:第一步将世界坐标系旋转一定角度记作变换R,再将世界坐标系平移到 视点位置记作T,那么这个

5、变换矩阵记为M=TR。要将世界坐标系的点变换到照相机坐标系下,需要使用矩阵M的逆矩阵,即: inverse(M)=inverse(R)*inverse(T)。即所求变换矩阵为inverse(M)。平移矩阵的逆矩阵形式简单,就是取平移量(eyex,eyey,eyez)的相反数,即:那么现在的关键是如何求出旋转矩阵R?上面我们构造的UVN坐标系u-v-n3个基向量可以构造成矩阵:注意这里对n轴进行了翻转,构成右手照相机坐标系。怎么看这个矩阵A呢,矩阵A实际上代表的就是一个旋转矩阵(从矩阵形式上看出)。旋转矩阵的一个特点就是它是正交矩阵,即有inverse(A) = transpose(A).(A-

6、1 = AT)很多教材和博客都说,这里A矩阵可以看做是将世界坐标系转换到与照相机坐标系重合时的旋转矩阵,这一点怎么理解呢?个人理解,矩阵A第四列为0,0,0,1,可以看做是世界坐标系和照相机坐标系原点重合;根据OpenGL学习脚印: 理解坐标系及坐标变换(上) 中所讲,矩阵前3列即变换后的基向量,那么这个基向量(都是单位向量)是如何计算出来的呢?就是通过旋转原来的世界坐标系的基向量来构造的。因此,可以说矩阵A代表的就是将世界坐标系旋转到与相机坐标系重合时的旋转矩阵R,即R = A。则inverse(R) = inverse(A) = transpose(A) 即为:所以gluLookAt所求变

7、换矩阵inverse(M)为:gluLookAt的默认值是(0, 0, 0, 0, 0,-1, 0, 1, 0);通过计算可得出:u=(1,0,0),v=(0,1,0),n=(0,0,-1),这样构成的矩阵M-1即为单位矩阵。下面通过代码来验证下结论。代码绘制一个立方体,设置为透视投影,并通过gluLookAt设置相机方位来查看立方体。注意,为了便于观察视变换矩阵,这里并没有进行其他模型变换;手动计算矩阵时使用了数学库glm来进行向量点积和叉积运算。 cpp view plaincopyprint?1. /计算gluLookAt矩阵2. 3. #include4. #include5. #in

8、clude6. #include7. #pragmacomment(lib,freeglut.lib)8. #pragmacomment(lib,glew32.lib)9. 10. voiduserInit();11. voiddisplay(void);12. voidkeyboardAction(unsignedcharkey,intx,inty);13. voidreshape(intw,inth);14. 15. intmain(intargc,char*argv)16. 17. glutInit(&argc,argv);/初始化GLUT18. 19. glutInitDisplayM

9、ode(GLUT_RGBA|GLUT_DOUBLE);20. glutInitWindowPosition(100,100);21. glutInitWindowSize(512,512);22. glutCreateWindow(gluLookAtdemo);23. 24. glewInit();/使用GLEW时,使用该函数初始化GLEW25. userInit();/自定义的初始化函数26. glutReshapeFunc(reshape);27. glutDisplayFunc(display);28. glutKeyboardFunc(keyboardAction);29. glutM

10、ainLoop();30. return0;31. 32. /自定义初始化函数33. voiduserInit()34. 35. glClearColor(0.0,0.0,0.0,0.0);36. glColor4f(0.6f,0.5f,0.0,0.0);37. 38. /设置视变换矩阵39. voidsetViewMatrix(GLdouble*theMatrix,GLdoubleeyex,GLdoubleeyey,GLdoubleeyez,40. GLdoubletargetx,GLdoubletargety,GLdoubletargetz,41. GLdoublevupx,GLdoubl

11、evupy,GLdoublevupz)42. 43. glm:vec3eye(eyex,eyey,eyez),target(targetx,targety,targetz),vup(vupx,vupy,vupz);44. /构造n轴45. glm:vec3nvec(target-eye);46. nvec=glm:normalize(nvec);47. /构造u轴48. vup=glm:normalize(vup);49. glm:vec3uvec=glm:cross(nvec,vup);50. uvec=glm:normalize(uvec);51. /构造v轴52. glm:vec3vve

12、c=glm:cross(uvec,nvec);53. vvec=glm:normalize(vvec);54. /设置4x4矩阵55. memset(theMatrix,0,sizeof(GLdouble)*16);56. 57. theMatrix0=uvec.x;58. theMatrix4=uvec.y;59. theMatrix8=uvec.z;60. theMatrix12=-glm:dot(eye,uvec);61. 62. theMatrix1=vvec.x;63. theMatrix5=vvec.y;64. theMatrix9=vvec.z;65. theMatrix13=-

13、glm:dot(eye,vvec);66. 67. /注意这行数据68. theMatrix2=-nvec.x;69. theMatrix6=-nvec.y;70. theMatrix10=-nvec.z;71. theMatrix14=glm:dot(eye,nvec);72. 73. theMatrix15=1.0;74. 75. voidreshape(intw,inth)76. 77. glViewport(0,0,GLsizei(w),GLsizei(h);78. glMatrixMode(GL_PROJECTION);79. glLoadIdentity();80. gluPers

14、pective(60.0,(GLfloat)w/(GLfloat)h,1.0,10.0);81. glMatrixMode(GL_MODELVIEW);82. glLoadIdentity();83. 84. /gluLookAt(2.0,0.0,1.8,0.0,0.0,0.0,0.0,1.0,0.0);85. 86. /手动构造视变换矩阵87. GLdoubletheMatrix16;88. setViewMatrix(theMatrix,2.0,0.0,1.8,0.0,0.0,0.0,0.0,1.0,0.0);89. glMultMatrixd(theMatrix);90. 91. /打印

15、当前模视变换矩阵内容92. GLdoublemodelViewMat16;93. glGetDoublev(GL_MODELVIEW_MATRIX,modelViewMat);94. for(inti=0;i4;i+)95. for(intj=0;j4;j+)96. 97. fprintf(stdout,%-.4ft,modelViewMati+4*j);98. if(j+1)%4=0)fprintf(stdout,n);99. 100. 101. /绘制回调函数102. voiddisplay(void)103. 104. glClear(GL_COLOR_BUFFER_BIT);/清除颜色

16、缓存105. glLineWidth(2.0);106. glutWireCube(1.0);107. glutSwapBuffers();108. 109. /键盘按键回调函数110. voidkeyboardAction(unsignedcharkey,intx,inty)111. 112. switch(key)113. case033:/Escapekey114. caseq:caseQ:115. exit(EXIT_SUCCESS);116. break;117. 118. 使用gluLookAt如下图左右所示:手动计算视变换矩阵,效果如下图所示:可以看出两者是一样的,二者的视变换矩阵打印出来均为:0.6690 0.0000 -0.7433 0.00000.0000 1.0000 0.0000 0.00000.7433 0.0000 0.6690 -2.69070.0000 0.0000 0.0000 1.0000至此证明了上述推导的矩阵确实为OpenGL中使用的视变换矩阵。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1