OpenGL glulookat的使用 位置的放置

时间:2022-09-10 17:48:40
写了一个程序,想实现相机对模型的跟踪,调用glutlookat函数,不能达到预定目标,而且这个函数放在不同位置实现效果也不一样,不懂,希望高手指点。部分程序源码在这。。
::glLoadIdentity();
::glTranslatef(scenePos[0], scenePos[1], scenePos[2]);
::glRotatef( sceneRot[0], 1.0F, 0.0F, 0.0F );
::glRotatef( sceneRot[1], 0.0F, 1.0F, 0.0F );
::glRotatef( sceneRot[2], 0.0F, 0.0F, 1.0F );
::glScalef(0.2f,0.2f,0.2f);
::gluLookAt(scenePos[0]-10,scenePos[1],scenePos[2]+10,scenePos[0],scenePos[1],scenePos[2],0.0f,1.0f,0.0f);
Draw3ds();
scenePos[0]=scenePos[0]+1;
::SwapBuffers(m_pDC->GetSafeHdc());
glutlookat函数应该怎么用,放在哪里呀?

13 个解决方案

#1


int main(int argc, char **argv)
{
  glutInitWindowSize(475, 950);
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);
  glutCreateWindow("GLUT geometric shapes");
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);

  glClearColor(1.0, 1.0, 1.0, 1.0);
  glColor3f(0.0, 0.0, 0.0);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  glEnable(GL_LIGHT0);
  glEnable(GL_DEPTH_TEST);
  glMatrixMode(GL_PROJECTION);
  gluPerspective( /* field of view in degree */ 22.0,
  /* aspect ratio */ 1.0,
    /* Z near */ 1.0, /* Z far */ 10.0);
  glMatrixMode(GL_MODELVIEW);
  gluLookAt(0.0, 0.0, 5.0,  /*  eye is at (0,0,5) */
    0.0, 0.0, 0.0,      /* center is at (0,0,0) */
    0.0, 1.0, 0.);      /* up is in postivie Y direction */
  glTranslatef(0.0, 0.0, -3.0);
  glRotatef(25, 1.0, 0.0, 0.0);
  glRotatef(5, 0.0, 1.0, 0.0);

  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

#2


在这个问题上面你应该搞清楚OpenGL中的坐标系之间的变换,它们如下:
本地坐标系-->世界坐标系-->眼坐标系-->裁剪坐标系
一般gluLookAt()用于从世界坐标系到眼坐标系的转换,但是由于OpenGL里面模型视图矩阵直接将本地坐标系转换为眼坐标系,所以gluLookAt()应该被用来设置模型视图矩阵,但是有一点得注意了:
gluLookAt()的调用应该在场景绘制初glLoadIdentity()函数调用之后,在所有的glTranslate*()、glRotate*()、glScale*()函数调用之前调用,且只调用一次,类似代码如下:


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
//这里最好先调用glPushMatrix()
//下面就可以任意调用glTranslate*(),glRotate*(),glScale*()等函数了,注意如果再次调用了glLoadIdentity(),则需要重新调用gluLookAt()
//也就是说,如果让gluLookAt()函数调用达到想要的效果的话,gluLookAt()设置的矩阵一定是模型视图矩阵所乘的第一个矩阵,且最多乘一次

#3


我要绘制的模型在glRotate  glTranslate glscale 之后到达准确位置,时钟的刷新使模型不断运动,我觉得glulookat应该放在Draw3ds();语句前边或后边,但是调试结果不对,不懂!!!!谢谢呀。

#4


一个是摄像机(眼),一个是模型,单独哪个动都能体现出来模型在运动
所以要让模型看起来是摄像机绕着它旋转,2个办法,要么动摄像机,用glLookAt(),要么修改ModelView矩阵,
2个一起动也可以,但是要有相对运动,因此不是很有必要

#5


projection view model 3个矩阵按着顺序来,最后顶点的真实位置也是 projection * view * model * vertex_position 来的。

#6


没有我想要的答案,我想实现的功能是相机对模型的跟踪,就是说相机和模型的相对位置一直不变,gllookat 函数中把眼睛的位置设置为模型位置加一相对位移,眼睛看向模型,这样就可以了吧,但是,仿真效果不对,模型总之飞出视野。为什么呀!!!!!伤不起呀。

#7


如何实现相机对模型的跟踪观察。???有源码也可以呀。。急需解决!!!!

#8


只单个动的话,模型很快就飞出视野了呀!!!所以应该两个都动吧。
引用 4 楼  的回复:
一个是摄像机(眼),一个是模型,单独哪个动都能体现出来模型在运动
所以要让模型看起来是摄像机绕着它旋转,2个办法,要么动摄像机,用glLookAt(),要么修改ModelView矩阵,
2个一起动也可以,但是要有相对运动,因此不是很有必要

#9


gluLookAt()不是你想象中的那样工作,与glTranslate*()\glRorate*()\glScale*()函数一样,它只是构造一个矩阵,并将它与glMatrixMode()函数指定的矩阵相乘而已。

#10


在这一点上,OpenGL与Direct3D不同的,在Direct3D中我们可以通过
pD3DDevice->SetTransform(D3DTS_VIEW,&matView);来设置观察矩阵,而在OpenGL里面根本没有。。。

#11


Direct3D中把模型矩阵(在Direct3D中称为世界矩阵)与视图矩阵分开了,而在OpenGL里面把它们先相乘,称为模型视图矩阵。。。
所在才要像上面我说的那样调用它。。。

#12


2楼同志解释的非常好,小弟彻底明白了,谢谢

#13


引用 2 楼 the_venus 的回复:
在这个问题上面你应该搞清楚OpenGL中的坐标系之间的变换,它们如下:
本地坐标系-->世界坐标系-->眼坐标系-->裁剪坐标系
一般gluLookAt()用于从世界坐标系到眼坐标系的转换,但是由于OpenGL里面模型视图矩阵直接将本地坐标系转换为眼坐标系,所以gluLookAt()应该被用来设置模型视图矩阵,但是有一点得注意了:
gluLookAt()的调用应该在场景绘制初glLoadIdentity()函数调用之后,在所有的glTranslate*()、glRotate*()、glScale*()函数调用之前调用,且只调用一次,类似代码如下:


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
//这里最好先调用glPushMatrix()
//下面就可以任意调用glTranslate*(),glRotate*(),glScale*()等函数了,注意如果再次调用了glLoadIdentity(),则需要重新调用gluLookAt()
//也就是说,如果让gluLookAt()函数调用达到想要的效果的话,gluLookAt()设置的矩阵一定是模型视图矩阵所乘的第一个矩阵,且最多乘一次
看完特意登上来谢谢老兄,很受用。 OpenGL glulookat的使用 位置的放置

#1


int main(int argc, char **argv)
{
  glutInitWindowSize(475, 950);
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);
  glutCreateWindow("GLUT geometric shapes");
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);

  glClearColor(1.0, 1.0, 1.0, 1.0);
  glColor3f(0.0, 0.0, 0.0);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  glEnable(GL_LIGHT0);
  glEnable(GL_DEPTH_TEST);
  glMatrixMode(GL_PROJECTION);
  gluPerspective( /* field of view in degree */ 22.0,
  /* aspect ratio */ 1.0,
    /* Z near */ 1.0, /* Z far */ 10.0);
  glMatrixMode(GL_MODELVIEW);
  gluLookAt(0.0, 0.0, 5.0,  /*  eye is at (0,0,5) */
    0.0, 0.0, 0.0,      /* center is at (0,0,0) */
    0.0, 1.0, 0.);      /* up is in postivie Y direction */
  glTranslatef(0.0, 0.0, -3.0);
  glRotatef(25, 1.0, 0.0, 0.0);
  glRotatef(5, 0.0, 1.0, 0.0);

  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}

#2


在这个问题上面你应该搞清楚OpenGL中的坐标系之间的变换,它们如下:
本地坐标系-->世界坐标系-->眼坐标系-->裁剪坐标系
一般gluLookAt()用于从世界坐标系到眼坐标系的转换,但是由于OpenGL里面模型视图矩阵直接将本地坐标系转换为眼坐标系,所以gluLookAt()应该被用来设置模型视图矩阵,但是有一点得注意了:
gluLookAt()的调用应该在场景绘制初glLoadIdentity()函数调用之后,在所有的glTranslate*()、glRotate*()、glScale*()函数调用之前调用,且只调用一次,类似代码如下:


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
//这里最好先调用glPushMatrix()
//下面就可以任意调用glTranslate*(),glRotate*(),glScale*()等函数了,注意如果再次调用了glLoadIdentity(),则需要重新调用gluLookAt()
//也就是说,如果让gluLookAt()函数调用达到想要的效果的话,gluLookAt()设置的矩阵一定是模型视图矩阵所乘的第一个矩阵,且最多乘一次

#3


我要绘制的模型在glRotate  glTranslate glscale 之后到达准确位置,时钟的刷新使模型不断运动,我觉得glulookat应该放在Draw3ds();语句前边或后边,但是调试结果不对,不懂!!!!谢谢呀。

#4


一个是摄像机(眼),一个是模型,单独哪个动都能体现出来模型在运动
所以要让模型看起来是摄像机绕着它旋转,2个办法,要么动摄像机,用glLookAt(),要么修改ModelView矩阵,
2个一起动也可以,但是要有相对运动,因此不是很有必要

#5


projection view model 3个矩阵按着顺序来,最后顶点的真实位置也是 projection * view * model * vertex_position 来的。

#6


没有我想要的答案,我想实现的功能是相机对模型的跟踪,就是说相机和模型的相对位置一直不变,gllookat 函数中把眼睛的位置设置为模型位置加一相对位移,眼睛看向模型,这样就可以了吧,但是,仿真效果不对,模型总之飞出视野。为什么呀!!!!!伤不起呀。

#7


如何实现相机对模型的跟踪观察。???有源码也可以呀。。急需解决!!!!

#8


只单个动的话,模型很快就飞出视野了呀!!!所以应该两个都动吧。
引用 4 楼  的回复:
一个是摄像机(眼),一个是模型,单独哪个动都能体现出来模型在运动
所以要让模型看起来是摄像机绕着它旋转,2个办法,要么动摄像机,用glLookAt(),要么修改ModelView矩阵,
2个一起动也可以,但是要有相对运动,因此不是很有必要

#9


gluLookAt()不是你想象中的那样工作,与glTranslate*()\glRorate*()\glScale*()函数一样,它只是构造一个矩阵,并将它与glMatrixMode()函数指定的矩阵相乘而已。

#10


在这一点上,OpenGL与Direct3D不同的,在Direct3D中我们可以通过
pD3DDevice->SetTransform(D3DTS_VIEW,&matView);来设置观察矩阵,而在OpenGL里面根本没有。。。

#11


Direct3D中把模型矩阵(在Direct3D中称为世界矩阵)与视图矩阵分开了,而在OpenGL里面把它们先相乘,称为模型视图矩阵。。。
所在才要像上面我说的那样调用它。。。

#12


2楼同志解释的非常好,小弟彻底明白了,谢谢

#13


引用 2 楼 the_venus 的回复:
在这个问题上面你应该搞清楚OpenGL中的坐标系之间的变换,它们如下:
本地坐标系-->世界坐标系-->眼坐标系-->裁剪坐标系
一般gluLookAt()用于从世界坐标系到眼坐标系的转换,但是由于OpenGL里面模型视图矩阵直接将本地坐标系转换为眼坐标系,所以gluLookAt()应该被用来设置模型视图矩阵,但是有一点得注意了:
gluLookAt()的调用应该在场景绘制初glLoadIdentity()函数调用之后,在所有的glTranslate*()、glRotate*()、glScale*()函数调用之前调用,且只调用一次,类似代码如下:


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
//这里最好先调用glPushMatrix()
//下面就可以任意调用glTranslate*(),glRotate*(),glScale*()等函数了,注意如果再次调用了glLoadIdentity(),则需要重新调用gluLookAt()
//也就是说,如果让gluLookAt()函数调用达到想要的效果的话,gluLookAt()设置的矩阵一定是模型视图矩阵所乘的第一个矩阵,且最多乘一次
看完特意登上来谢谢老兄,很受用。 OpenGL glulookat的使用 位置的放置