适用于gluCylinder的gluLookAt

时间:2015-08-13 12:17:31

标签: c++ opengl glulookat

我正在尝试使用gluCylinder在特定方向绘制圆柱体。然而,要指定我使用gluLookAt的方向,就像我之前的那么多,我不确定“向上”向量,因此无法使圆柱指向正确的方向。

我从另一个SO回答中读到了

  

gluLookAt中“向上”向量背后的直觉很简单:看看任何东西。现在将头部倾斜90度。如果你没有改变,你所看到的方向没有改变,但视网膜中的图像显然有。有什么不同?头顶指向的位置。这是向上的向量。

这是一个简单的解释,但在我的圆柱体的情况下,我觉得向上矢量是完全不重要的。由于圆柱体可以绕其轴旋转并且看起来仍然相同,因此不同的向上矢量不会改变任何东西。因此,对于我的问题,应该有无限多的有效向上矢量:从起点到终点的向量的所有正交值。

所以这就是我的所作所为:

  1. 我有圆柱的起点和终点所在的世界坐标,A_worldB_world

  2. 我使用A_vp将它们投影到视口坐标B_vpgluProject

    GLdouble A_vp[3], B_vp[3], up[3], model[16], projection[16];
    GLint gl_viewport[4];
    glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
    glGetDoublev(GL_PROJECTION_MATRIX, &projection[0]);
    glGetIntegerv(GL_VIEWPORT, gl_viewport);
    
    gluProject(A_world[0], A_world[1], A_world[2], &model[0], &projection[0], &gl_viewport[0], &A_vp[0], &A_vp[1], &A_vp[2]);
    
    gluProject(B_world[0], B_world[1], B_world[2], &model[0], &projection[0], &gl_viewport[0], &B_vp[0], &B_vp[1], &B_vp[2]);
    
  3. 我致电glOrtho将相机重置为默认位置:负z进入图片,x向右,y向上:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, vp_edgelen, vp_edgelen, 0, 25, -25);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
  4. 我转换为坐标A_vp,将向上矢量计算为向量A_vp — B_vp的法线,并使用gluLookAt指定视图:

    glTranslatef(A_vp[0], gl_viewport[2] - A_vp[1], A_vp[2]);
    glMatrixMode(GL_MODELVIEW);
    
    GLdouble[] up = {A_vp[1] * B_vp[2] - A_vp[2] * B_vp[1], 
                     A_vp[2] * B_vp[0] - A_vp[0] * B_vp[2],
                     A_vp[0] * B_vp[1] - A_vp[1] * B_vp[0]};
    
    gluLookAt(0, 0, 0,
              B_vp[0], gl_viewport[2] - B_vp[1], B_vp[2],
              up[0], up[1], up[2]);
    
  5. 我用gluCylinder绘制圆柱体:

    GLUquadricObj *gluCylObj = gluNewQuadric();
    gluQuadricNormals(gluCylObj, GLU_SMOOTH);
    gluQuadricOrientation(gluCylObj, GLU_OUTSIDE);
    gluCylinder(gluCylObj, 10, 10, 50, 10, 10);
    
  6. 这是意想不到的结果:

    enter image description here

    由于圆柱体从正确的位置开始,因为我能够在位置B_vp处绘制一个圆,唯一必须错误的是gluLookAt中的“向上”向量,对吧?

1 个答案:

答案 0 :(得分:0)

gluLookAt()没有必要达到正确的观点。将当前的z向量旋转到指向圆柱应该指向的方向就足够了。