如何使用OpenGL从移动对象实现视图?

时间:2011-12-14 22:34:52

标签: opengl glut

我有一辆车在OpenGL的椭圆轨道上移动。自上而下的视图很简单,但我似乎无法弄清楚驾驶员的视线。以下是定义赛道上赛车位置和方向的公式:

const double M_PI = 4.0*atan(1.0);
carAngle += (M_PI/180.0);
if (carAngle > 2.0*M_PI) {
    carAngle -= 2.0*M_PI;
}
carTwist = (180.0 * atan2(42.5*cos(carAngle), 102.5*sin(carAngle)) / M_PI)-90.0;

这些计算保存在Timer Func中,以下是转换的代码:

// These are the inside/outside unit measurements
// of the track along the major/minor axes.
insideA = 100;
insideB = 40;
outsideA = 105;
outsideB = 45;

glPushMatrix();
glTranslated(cos(carAngle)*(outsideA+insideA)/2.0,
             0.0,
             sin(carAngle)*(outsideB+insideB)/2.0);
glScaled(10.0, 10.0, 10.0);
glRotated(carTwist, 0.0, 1.0, 0.0);
glCallList(vwListID1);
glPopMatrix();

使用gluLookAt查看此内容,如下所示:

gluLookAt(0.0, 20.0, 0.0, 
          0.0,  0.0, 0.0, 
          0.0,  0.0, 1.0);

这很好用,汽车沿轨道移动并按预期转弯。现在我想要一辆车的“相机”视图。我在一个单独的窗口中尝试这个,并且我在第二个窗口工作正常,但我无法正确查看。

我认为它会是这样的:

double x, z, lx, lz;
x = cos(carAngle)*(outsideA+insideA)/2.0;
z = sin(carAngle)*(outsideB+insideB)/2.0;
lx = sin(carTwist);
lz = cos(carTwist);

gluLookAt(x,   1.0, z,
          lx,  1.0, lz,
          0.0, 1.0, 0.0);

当然,如果我使用gluLookAt使用x, 20.0, z作为眼睛坐标,并使用x, 0.0, z作为中心坐标,那么定位当然可以正常工作中心屏幕。由于carTwist是从正z轴到轨道上当前汽车位置的切线的角度,因此矢量[sin(alpha),1,cos(alpha)]应该在眼睛坐标前面提供一个点1单位。视线。但这根本不起作用。

另一方面,我尝试使用模型转换来达到同样的效果,但没有运气。我假设如果我在没有设置gluLookAt的情况下反转变换,我应该得到所需的视图。即:

glTranslated(-(cos(carAngle)*(outsideA+insideA)/2.0),
             0.0,
             -(sin(carAngle)*(outsideB+insideB)/2.0));
glRotated(-carTwist, 0.0, 1.0, 0.0);

根据this article,它应提供相同的观点。

对这两种方法有任何帮助吗?

1 个答案:

答案 0 :(得分:1)

您当前的lx和lz应该是您想要的外观方向,但它们是以原点为中心的坐标。

gluLookAt的第4,第5和第6个参数指定要查看的场景中的一个点,而不是外观方向。

因此,您需要将相机位置的外观方向添加到场景中以获得指向相机的位置。

此外,由于carTwist以度为单位,您需要将其转换为弧度以用于cos和sin函数。

double x, z, lx, lz;
x = cos(carAngle)*(outsideA+insideA)/2.0;
z = sin(carAngle)*(outsideB+insideB)/2.0;
lx = x + cos(carTwist * M_PI / 180.0);
lz = z + sin(carTwist * M_PI / 180.0);