本文共 2329 字,大约阅读时间需要 7 分钟。
(1)将相机固定在三脚架上,让它对准场景(视图变换);
(2)对场景进行安排,使照片中各物体位于读者所希望的位置(模型变换);
(3)选择照相机镜头,并调整放大倍数(投影变换);
(4)确定最终照片的大小,如放大(视口变换)。
当完成上述步骤之后,就可以绘制场景了。视图可以简单理解为一个场景拍照。
视口(Viewport):将世界坐标系中的三维物体经过一系列几何变化(包括平移、选择和伸缩等),为了使显示的物体能以合适的位置、大小和方向显示出来,必须要通过投影,然后定义一个三维视景体,对物体进行裁剪,只使投影在视景体内的部分显示出来,然后在屏幕窗口内定义一个矩形,称为视口。视景体投影后的图形就在视口内显示,最后做一些适当变换,使图形在屏幕坐标系下显示。OSG包含SimpleViewer、Viewer、CompositeViewer三大视口类。
osg::Camera类继承自osg::Transform和osg::CullSetting类,用来管理OSG中的模型——视图矩阵。相机的管理主要是通过各种变换实现的。
(1)视点变换:设置视点的方向和位置。默认情况下,视点定位为坐标原点,指向Y正方向。
OSG提供了多种方法来设置视点矩阵:
void setViewMatrixAsLookAt(const osg::Vec3d &eye, const osg::Vec3D ¢er, const osg::Vec3d &up)void getViewMatrixAsLookAt(osg::Vec3d &eye, osg::Vec3d ¢er, osg::Vec3d &up, double lookDistance=1.0)void getViewMatrixAsLookAt(osg::Vec3f &eye, osg::Vec3f ¢er, osg::Vec3f &up, float lookDistance=1.0)
(2)模型变换:对模型的位置、大小和角度的变换。如位置变换节点(osg::PositionAttitudeTransform)和矩阵变换节点(osg::MatrixTransform)。
(3)投影变换:经过上面的模型视景的转换后,场景中的物体放在了所希望的位置上,但由于显示器只能用二维图像显示三维物体,因此要靠投影来降低维数。事实上,投影变换的目的就是定义一个视景体,使视景体外多余的部分被裁减掉,最终进入图像的只是视景体内的有关部分。包括透视投影(Perspective Projection)和正视投影(Orthographic Projection)。
OSG提供了多种投影矩阵设置方法:
/*透视投影:透视视景体、对称透视视景体*/void setProjectionMatrixAsFrustum(double left, double right, double bottom, double top, double zNear, double zFar)bool getProjectionMatrixAsFrustum(double &left, double &right, double &bottom, double &top, double &zNear, double &zFar)void setProjectionMatrixAsPerspective(double fovy, double aspectRatio, double zNear, double zFar)bool getProjectionMatrixAsPerspective(double &fovy, double &aspectRatio, double &zNear, double &zFar)void setProjectionMatrixAsOrtho(double left, double right, double bottom, double top, double zNear, double zFar)bool getProjectionMatrixAsOrtho(double &left, double &right, double &bottom, double &top, double &zNear, double &zFar)void setProjectionMatrixAsOrtho2D(double left, double right, double bottom, double top)
(4)视口变换:将视景体内投影的物体显示在二维的视口平面上。即将经过几何变换、投影变换和裁剪变换后的物体显示于屏幕窗口内指定的区域内,这个区域通常为矩形,称为视口。
void setViewport(osg::Viewport *viewport)void setViewport(int x, int y, int width, int height)const Viewport *getViewport() constViewport *getViewport()
(5)裁剪变换:在OSG中,默认了6个裁剪平面以去除没有必要显示的物体。还可以定义其他裁剪平面来裁剪。定义裁剪平面的方法有很多,如osg::Scissor和osg::ClipPlane等。
通过以上变换步骤,可以实现从三维场景到二维显示的有效转换,确保图形在屏幕上准确、完整地呈现出来。
转载地址:http://ekvfk.baihongyu.com/