可以只在opengl中移动相机而不重绘场景吗?

时间:2012-03-27 16:29:00

标签: opengl

我在opengl中创建了一个渲染非常昂贵的场景(使用顶点缓冲对象),当所有对象保持原位时,我想做一些像对象的“平滑追踪”。即:将对象保留在原位,并以一定的恒定速度向左或向右移动摄像机/视点。目前,我通过调用glTranslatef函数中的draw,然后重新绘制所有对象的代码来执行此操作。然而,这是非常昂贵的(很多物品!)。有没有办法移动相机,而无需重新绘制整个场景?

4 个答案:

答案 0 :(得分:4)

OpenGL中没有摄像头。或者,如果你真的想要有,那么你必须意识到“相机”停留在OpenGL的原点,总是朝着同一个方向看。通过移动和旋转世界中的所有物体来模拟“相机”效果,而“相机”位于原点。

因此,如果您想移动“相机”,您必须移动世界(或世界上的所有物体)。换句话说,实际上没有办法“在不重绘所有物体的情况下移动相机”。如果你真的想要的话,一个选择是将场景渲染到比屏幕大的纹理,然后移动纹理以模拟移动的“相机”。请注意,如果您使用透视投影,则执行此操作时看起来会非常错误。如果您使用正交投影,这只会看起来不错。

然而,这听起来像是在立即模式中绘制,这是一种古老而缓慢的方法。您应该使用带有着色器和顶点数组对象/顶点缓冲区对象的现代绘制调用。

答案 1 :(得分:3)

  

在opengl

中创建渲染非常昂贵的场景

不,不。你是绘图一个非常复杂的场景。但OpenGL不适用于场景。 OpenGL为您提供点,线和三角形,并根据您的命令将它们绘制到二维帧缓冲区。但是,一旦您发送绘图命令,并且几何体已经绘制,OpenGL将不再记录您所说的内容。

你最终得到的是一张照片。如果你想改变它的任何方面,并且只是它的优势点,你必须重新绘制整个事物。

答案 2 :(得分:1)

嗯,你可以将场景渲染到比视口大的纹理。然后在该纹理上滑动视口。每当你接近纹理的边缘时,你必须重绘场景,但不是每一帧。

但请注意,这有几个缺点:

  • 因为深度的感知取决于相机在不更新深度信息的情况下移动相机的位置可能会导致不必要的和明显的视觉效果,例如场景显得平坦等。

  • 从那时起你无法转动相机,视觉瑕疵会更加明显,或者视口可能会离开纹理空间。

作为替代方案,请尝试优化场景绘制。有几种方法可以做到,其中一些是:

  • 遮挡剔除
  • 为远处的物体渲染平面冒名顶替者/精灵
  • 减少视图深度
  • 使用顶点和索引缓冲区
  • 实例化

修改

重新阅读您的问题似乎glTranslatef等来电可能是问题所在。在现代OpenGL(以及Direct3D)应用程序中,您自己计算矩阵(可能使用OpenCL但 glTranslatef等),存储它们并将它们传递给着色器以呈现对象。

如果每次更新完成,可能会耗尽性能的矩阵计算。如果您的对象不经常移动,您可能只想在移动时计算矩阵,在绘制时只需将它们传递给OpenGL。为了进一步优化,您可能需要考虑数据局部性以减少缓存未命中等 - 但这已经是一个非常低级别的优化。

总结答案:不要尝试减少帧更新的数量,但尝试优化各个更新。当“摄像机”移动时,您需要更新视图(即重新渲染),因此您唯一的选择是减少这些更新所需的工作。

答案 3 :(得分:0)

不,必须重新绘制整个场景。

glTranslatef调用会更改模型视图矩阵,该矩阵是几何体转换的第一个矩阵。更改矩阵意味着矩阵之后的管道中的所有内容都将无效,这是因为它的第一步实际上就是一切。通过翻译,而不是移动“相机”,更像是移动整个世界,相机保持静止。

除了OpenGL(和视频硬件)之外,根本无法以您想要的方式工作。

有一种称为广告牌的技术,用于渲染远处的几何体。几何体渲染为纹理,然后在渲染主场景时将其用作精灵。只要相机保持接近生成广告牌的点,那么错误是可接受的(或不可察觉的)。场景仍然仍在每帧渲染,但你有点作弊。这通常用于遥远的地形和树木。

Bilboarding不是你应该通过事物的声音来研究的东西,因为它很难做对。为了提高性能,首先要看看使用顶点缓冲对象和平截头体剔除。