glulookat函数Word文档格式.docx

上传人:b****2 文档编号:1149883 上传时间:2023-04-30 格式:DOCX 页数:12 大小:217.07KB
下载 相关 举报
glulookat函数Word文档格式.docx_第1页
第1页 / 共12页
glulookat函数Word文档格式.docx_第2页
第2页 / 共12页
glulookat函数Word文档格式.docx_第3页
第3页 / 共12页
glulookat函数Word文档格式.docx_第4页
第4页 / 共12页
glulookat函数Word文档格式.docx_第5页
第5页 / 共12页
glulookat函数Word文档格式.docx_第6页
第6页 / 共12页
glulookat函数Word文档格式.docx_第7页
第7页 / 共12页
glulookat函数Word文档格式.docx_第8页
第8页 / 共12页
glulookat函数Word文档格式.docx_第9页
第9页 / 共12页
glulookat函数Word文档格式.docx_第10页
第10页 / 共12页
glulookat函数Word文档格式.docx_第11页
第11页 / 共12页
glulookat函数Word文档格式.docx_第12页
第12页 / 共12页
亲,该文档总共12页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

glulookat函数Word文档格式.docx

《glulookat函数Word文档格式.docx》由会员分享,可在线阅读,更多相关《glulookat函数Word文档格式.docx(12页珍藏版)》请在冰点文库上搜索。

glulookat函数Word文档格式.docx

5. 

upX, 

upY, 

upZ);

官网关于此函数的描述:

gluLookAt 

通过指定一个视点、外表场景中心的参考点以及up向量来构造一个视变换矩阵。

这个矩阵将代表场景中心的参考点映射到-Z轴,视点映射成为原点。

当使用一个特定的投影矩阵时,场景的中心就映射到视口的中心。

类似地,由up向量描述的方向投影到投影平面成为+y轴,这样它在视口中向上指向。

up向量必须不能与从视点到参考点的直线平行。

那么如何确定u-v-n坐标系呢?

计算公式如下:

这里需要注意:

OpenGL中使用的相机坐标系是右手坐标系,UVN坐标系是左手坐标系。

在构造实际变换矩阵的过程中,OpenGL

需要将-n轴翻转为相机坐标系的+z轴,uv轴定位相机坐标系的+x和+y轴。

这与推导相机变换矩阵一文最后的结果矩阵有所不同。

如何构造视变换矩阵?

视变换就是在相机坐标系下解释世界坐标系下的点。

而这个变换矩阵的构造,可以看做将相机坐标系变换到与原来的世界坐标系重合。

而将世界坐标系变换到与相机坐标系重合,可以看做是这个所求变换的逆过程。

将世界坐标系变换到与相机坐标系重合,实际上进展了两个步骤:

第一步将世界坐标系旋转一定角度记作变换R,再将世界坐标系平移到视点位置记作T,那么这个变换矩阵记为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^-1=A^T)

很多教材和博客都说,这里A矩阵可以看做是将世界坐标系转换到与照相机坐标系重合时的旋转矩阵,这一点怎么理解呢?

个人理解,矩阵A第四列为0,0,0,1,可以看做是世界坐标系和照相机坐标系原点重合;

根据?

理解坐标系及坐标变换(上)?

中所讲,矩阵前3列即变换后的基向量,那么这个基向量(都是单位向量)是如何计算出来的呢?

就是通过旋转原来的世界坐标系的基向量来构造的。

因此,可以说矩阵A代表的就是将世界坐标系旋转到与相机坐标系重合时的旋转矩阵R,即R=A。

那么inverse(R)=inverse(A)=transpose(A) 

即为:

所以gluLookAt所求变换矩阵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来进展向量点积和叉积运算。

1.//计算gluLookAt矩阵 

3.#include 

<

GL/glew.h>

4.#include 

GL/freeglut.h>

5.#include 

glm/glm.hpp>

6.#include 

iostream>

7.#pragma 

comment(lib,"

freeglut.lib"

) 

8.#pragma 

glew32.lib"

9. 

10.void 

userInit();

11.void 

display( 

void 

);

12.void 

keyboardAction( 

unsigned 

char 

key, 

int 

x, 

13.void 

reshape(int 

w,int 

h);

14. 

15.int 

main( 

argc, 

**argv 

16.{ 

17. 

glutInit(&

argv);

//初始化GLUT 

18. 

19. 

glutInitDisplayMode( 

GLUT_RGBA|GLUT_DOUBLE);

20. 

glutInitWindowPosition(100,100);

21. 

glutInitWindowSize( 

512, 

512 

22. 

glutCreateWindow( 

"

demo"

23. 

24. 

glewInit();

//使用GLEW时,使用该函数初始化GLEW 

25. 

//自定义的初始化函数 

26. 

glutReshapeFunc(reshape);

27. 

glutDisplayFunc( 

display 

28. 

glutKeyboardFunc( 

keyboardAction 

29. 

glutMainLoop();

30. 

return 

0;

31.} 

32.//自定义初始化函数 

33.void 

userInit() 

34.{ 

35. 

glClearColor( 

0.0, 

0.0 

36. 

glColor4f(0.6f,0.5f,0.0,0.0);

37.} 

38.//设置视变换矩阵 

39.void 

setViewMatrix(GLdouble 

*theMatrix,GLdouble 

eyex,GLdouble 

eyey,GLdouble 

eyez, 

40. 

targetx,GLdouble 

targety,GLdouble 

targetz, 

41. 

vupx,GLdouble 

vupy,GLdouble 

vupz) 

42.{ 

43. 

glm:

:

vec3 

eye(eyex,eyey,eyez),target(targetx,targety,targetz),vup(vupx,vupy,vupz);

44. 

//构造n轴 

45. 

nvec(target-eye);

46. 

nvec=glm:

normalize(nvec);

47. 

//构造u轴 

48. 

vup 

normalize(vup);

49. 

uvec 

cross(nvec,vup);

50. 

uvec=glm:

normalize(uvec);

51. 

//构造v轴 

52. 

vvec 

cross(uvec,nvec);

53. 

vvec=glm:

normalize(vvec);

54. 

//设置4x4矩阵 

55. 

memset(theMatrix,0,sizeof(GLdouble)*16);

56. 

57. 

theMatrix[0] 

uvec.x;

58. 

theMatrix[4] 

uvec.y;

59. 

theMatrix[8] 

uvec.z;

60. 

theMatrix[12 

-glm:

dot(eye,uvec);

61. 

62. 

theMatrix[1] 

vvec.x;

63. 

theMatrix[5] 

vvec.y;

64. 

theMatrix[9] 

vvec.z;

65. 

theMatrix[13] 

dot(eye,vvec);

66. 

67. 

//注意这行数据 

68. 

theMatrix[2] 

-nvec.x;

69. 

theMatrix[6] 

-nvec.y;

70. 

theMatrix[10] 

-nvec.z;

71. 

theMatrix[14] 

dot(eye,nvec);

72. 

73. 

theMatrix[15] 

1.0;

74.} 

75.void 

h) 

76.{ 

77. 

glViewport(0,0,GLsizei(w),GLsizei(h));

78. 

glMatrixMode(GL_PROJECTION);

79. 

glLoadIdentity();

80. 

gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,10.0);

81. 

glMatrixMode(GL_MODELVIEW);

82. 

83. 

84. 

//gluLookAt(2.0,0.0,1.8,0.0,0.0,0.0,0.0,1.0,0.0);

85. 

86. 

//手动构造视变换矩阵 

87. 

theMatrix[16];

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. 

//打印当前模视变换矩阵容 

92. 

modelViewMat[16];

93. 

glGetDoublev(GL_MODELVIEW_MATRIX,modelViewMat);

94. 

for(int 

i<

4;

i++) 

95. 

j=0;

j<

j++) 

96. 

97. 

fprintf(stdout,"

%-.4f\t"

modelViewMat[i+4*j]);

98. 

if((j+1) 

%4 

== 

0) 

\n"

99. 

100.} 

101.//绘制回调函数 

102.void 

103.{ 

104. 

glClear( 

GL_COLOR_BUFFER_BIT);

//去除颜色缓存 

105. 

glLineWidth(2.0);

106. 

glutWireCube(1.0);

107. 

glutSwapBuffers();

108.} 

109.//键盘按键回调函数 

110.void 

111.{ 

112. 

switch( 

key 

113. 

case 

033:

// 

Escape 

114. 

'

q'

Q'

115. 

exit( 

EXIT_SUCCESS 

116. 

break;

117. 

118.} 

使用gluLookAt如以下图左右所示:

手动计算视变换矩阵,效果如以下图所示:

可以看出两者是一样的,二者的视变换矩阵打印出来均为:

0.6690 

0.0000 

-0.74330.0000

0.0000 

1.0000 

0.0000

0.7433 

0.6690 

-2.6907

1.0000

至此证明了上述推导的矩阵确实为OpenGL中使用的视变换矩阵。

关于OpenGLgluLookAt官网提供了参考实现,可以查看:

GluLookAtcode;

另外关于顶部正朝向vup的理解有更好的通俗解释,可以查看:

Opengl---gluLookAt函数详解。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2