为什么我的渲染图像没有显示我希望使用 gluLookAt 看到的视图?
Why is my rendered image not showing the view I expect to see using gluLookAt?
我要解决的任务很简单:加载一个纹理化的 OBJ 文件并显示它,使其占用最大数量的图像 space。只要相机向下看负 z 轴并且 y 轴是向上矢量,就不需要旋转网格。我正在使用 pyglet 来做到这一点。
为了将相机设置到所需位置,我正在执行以下操作(代码见下文):计算网格的边界球体,它由网格的中心和最远点的半径定义从中心。然后我按照解释计算截锥体,例如here 并相应地设置正交投影。然后我使用 gluLookAt
像这样更新 modelviewmatrix:相机位于正 z 轴上,看向网格的中心,y 轴是向上矢量。
问题是我的渲染图像看起来完全不像我期望的那样,例如网格的中心不在图像的中心,如下图所示。该图像显示了边界框和坐标轴,坐标轴源自网格的计算中心(红色:x 轴,绿色:y 轴,蓝色:z 轴)。
设置相机的代码是:
# 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
你能帮我找出我做错了什么吗?
There is no need to rotate the mesh as long as the camera is looking down the negative z-axis and the y-axis is the up vector.
你的相机没有俯视 z
轴:
gluLookAt(0.0, 0.0, eye, center[0], center[1], center[2], 0.0, 1.0, 0.0)
这将引入一个旋转,以便世界 space 中的相机方向将是 (center[0], center[1], center[2] - eye) = (center[0], center[1], -radius)
。
由于您已经根据对象移动了视图体积,因此注视点将而不是出现在屏幕中心的点。你真正需要做的只是沿着 -z
看,你只需要沿着 +z
:
平移相机
gluLookAt(0.0, 0.0, eye, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
请注意,从概念上讲,您的用例根本不需要视图矩阵。您可以只计算包含对象的轴对齐边界框,并可以直接将其用作视图体积的参数(就像您对 x
和 y
所做的那样,但出于某些原因,不适用于 z
)。唯一的技巧是您需要否定 near
和 far
的值,因为 glOrtho
的设计方式。
我要解决的任务很简单:加载一个纹理化的 OBJ 文件并显示它,使其占用最大数量的图像 space。只要相机向下看负 z 轴并且 y 轴是向上矢量,就不需要旋转网格。我正在使用 pyglet 来做到这一点。
为了将相机设置到所需位置,我正在执行以下操作(代码见下文):计算网格的边界球体,它由网格的中心和最远点的半径定义从中心。然后我按照解释计算截锥体,例如here 并相应地设置正交投影。然后我使用 gluLookAt
像这样更新 modelviewmatrix:相机位于正 z 轴上,看向网格的中心,y 轴是向上矢量。
问题是我的渲染图像看起来完全不像我期望的那样,例如网格的中心不在图像的中心,如下图所示。该图像显示了边界框和坐标轴,坐标轴源自网格的计算中心(红色:x 轴,绿色:y 轴,蓝色:z 轴)。
设置相机的代码是:
# 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
你能帮我找出我做错了什么吗?
There is no need to rotate the mesh as long as the camera is looking down the negative z-axis and the y-axis is the up vector.
你的相机没有俯视 z
轴:
gluLookAt(0.0, 0.0, eye, center[0], center[1], center[2], 0.0, 1.0, 0.0)
这将引入一个旋转,以便世界 space 中的相机方向将是 (center[0], center[1], center[2] - eye) = (center[0], center[1], -radius)
。
由于您已经根据对象移动了视图体积,因此注视点将而不是出现在屏幕中心的点。你真正需要做的只是沿着 -z
看,你只需要沿着 +z
:
gluLookAt(0.0, 0.0, eye, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
请注意,从概念上讲,您的用例根本不需要视图矩阵。您可以只计算包含对象的轴对齐边界框,并可以直接将其用作视图体积的参数(就像您对 x
和 y
所做的那样,但出于某些原因,不适用于 z
)。唯一的技巧是您需要否定 near
和 far
的值,因为 glOrtho
的设计方式。