为什么我的渲染图像没有显示我希望使用gluLookAt看到的视图?

时间:2017-03-02 10:03:22

标签: python opengl pyglet

我想要解决的任务很简单:加载一个纹理化的OBJ文件并显示它,使其占用最大量的图像空间。只要相机向下看负z轴并且y轴是向上矢量,就不需要旋转网格。我正在使用pyglet来做到这一点。

要将摄像机设置到所需位置,我将执行以下操作(代码见下文):计算网格的边界球体,该球体由网格中心和距离最远点的半径定义。中央。然后我按照解释的那样计算平截头体。 here并相应地设置正交投影。然后我使用gluLookAt更新模型视图矩阵,如下所示:摄像机位于正z轴上,朝向网格中心,y轴是向上矢量。

问题是我渲染的图像看起来并不像我期望的那样,例如网格的中心不在图像的中心,如下图所示。图像显示了边界框和坐标轴,这些坐标轴来自网格的计算中心(红色:x轴,绿色:y轴,蓝色:z轴)。

enter image description here

设置相机的代码是:

    # get the bounding sphere
    center, radius = self._mesh.compute_bounding_sphere()
    diam = radius*2.0

    print 'center:'
    print center
    print 'radius: %f' % radius

    # set up near and far clipping plane
    z_near = 1.0
    z_far = z_near + diam

    # construct params for orthographic projection matrix
    left = center[0] - radius
    right = center[0] + radius
    bottom = center[1] - radius
    top = center[1] + radius

    # if we are not rendering a square image, must correct for aspect ratio
    aspect_ratio = float(self.width) / float(self.height)
    if aspect_ratio < 1.0:
        bottom /= aspect_ratio
        top /= aspect_ratio
    else:
        left *= aspect_ratio
        right *= aspect_ratio

    print 'znear %f, zfar %f' % (z_near, z_far)
    print 'left %f, right %f' % (left, right)
    print 'bottom %f, top %f' % (bottom, top)

    # specify a parallel projection with clipping planes as computed above
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(left, right, bottom, top, z_near, z_far)
    # gluPerspective(50.0, aspect_ratio, z_near, z_far)

    # construct a viewing transform as follows: we look at the center of the mesh, the eye is located on the
    # positive z-axis, and the 3D y-axis is the up-vector, i.e. it will be mapped to the y-axis in image space.
    eye = center[2] + radius
    print 'eye:'
    print eye
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    gluLookAt(0.0, 0.0, eye, center[0], center[1], center[2], 0.0, 1.0, 0.0)

打印

center:
[ 8.51203675 -1.95199815  0.35396978]
radius: 10.462382
znear 1.000000, zfar 21.924764
left -1.950345, right 18.974419
bottom -12.414380, top 8.510384
eye:
10.8163515441

你能帮我辨别我做错了吗?

1 个答案:

答案 0 :(得分:1)

  

只要相机向下看负z轴并且y轴是向上矢量,就不需要旋转网格。

您的相机没有向下看z轴:

gluLookAt(0.0, 0.0, eye, center[0], center[1], center[2], 0.0, 1.0, 0.0)

这将引入旋转,以便世界空间中的摄像机方向为(center[0], center[1], center[2] - eye) = (center[0], center[1], -radius)

由于您已根据对象移动了视图卷,因此lookAt点将成为将出现在屏幕中心的点。您实际需要做的只是查看-z,您只需要沿着+z翻译相机:

gluLookAt(0.0, 0.0, eye, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

请注意,从概念上讲,您根本不需要视图矩阵用于您的用例。您可以简单地包围对象的轴对齐边界框,并可以直接将其用作视图体积的参数(就像使用xy一样,但出于某些原因,不适用于z)。唯一的技巧是你需要否定nearfar的值,因为glOrtho的设计方式。