目录
osg::Camera类 (相机类)
1、视点变换
2、投影变换
3、视口变换
4、裁剪变换
osg::ClipPlane
osg::Scissor
5、其他
osg::Camera 类继承自 osg::Transform(变换类) 和 osg::CullSettings(裁剪类) 类,用来管理 OSG 中的模型(视图矩阵);
相机的管理主要是通过各种变换来实现的;
- 视点变换就是设置视点的方向和位置。
- 默认情况下,视点定位为坐标原点,指向Y正方向。
在 Camera 中的视点变换函数如下:
/*
第一个参数是视点的位置
第二个参数是参考点的位置,该点通常为场景中中心轴上的点
第三个参数是视点向上的方向向量
*/
void setViewMatrixAsLookAt(cost osg::Vec3d &eye, const osg::Vec3d ¢er, const osg::Vec3d &up);
void setViewMatrixAsLookAt(osg::Vec3d &eye, osg::Vec3d ¢er, osg::Vec3d &up, double lookDistance=1.0);
void setViewMatrixAsLookAt(osg::Vec3f &eye, osg::Vec3f ¢er, osg::Vec3f &up, float lookDistance=1.0f);
投影变换在显示流程中是一个非常重要的环节,由于显示器只能用二维图像显示三维物体,因此就要靠投影来降低维数。
事实上,投影变换的目的就是定义一个视景体,使视景体多余的部分裁剪掉,最终进入图像的只是视景体内的有关部分。投影包括透视投影和正视投影两种。
透视投影比较好理解,符合正常的视觉现象。离视点越近,物体越大;离视点越远,物体越小;当远到极点时,物体小时,变为灭点;
在OSG中,有两种透视投影,即透视视景体和对称透视视景体。
/*
创建或者得到一个透视视图平截体的矩阵,并把它与当前矩阵相乘
第1~4个参数分别是近截剪面的参数信息
第五个参数表示从视点到近截面的距离
第六个参数表示从视点到远截面的距离
注意:zNer 和 zFar 必须指定为正数
*/
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);
/*
创建或者得到一个对称透视视图平截体的矩阵,并把它与当前矩阵相乘
第1~4个参数分别是近截剪面的参数信息
第五个参数表示从视点到近截面的距离
第六个参数表示从视点到远截面的距离
注意:zNer 和 zFar 必须指定为正数
*/
void setProjectionMatrixAsPerspective(double left, double right, double bottom, double top, double zNear, double zFar);
bool getProjectionMatrixAsPerspective(double &left, double &right, double &bottom, double &top,
double &zNear, double &zFar);
在OSG中,正射投影也包括两种,即正射投影和特殊的正射投影
/*
创建得到一个平行正射投影矩阵,并与当前矩阵相乘
第1~4个参数分别是近裁剪平面的参数信息
第五个参数表示视点距近裁剪面的距离
第六个参数表示视点距远裁剪面的距离
注意:zNear 和 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);
/*
创建一个表示把二维投影坐标投影到屏幕的矩阵,并与当前矩阵相乘
第1~4个参数表示一个矩阵的信息
*/
void setProjectionMatrixAsOrtho2D(double left, double right, double bottom, double top);
- 视口变换就是将视景器内投影的物体显示在二维的视口平面上。
- 它的意义是将经过几何变换、投影变换和裁剪变换后的物体显示于屏幕窗口内指定的区域内,这个区域通常为矩形,成为视口。
视口变换函数如下:
/*
创建或者得到一个视口
第1~2个参数表示屏幕左下角的坐标;
第三个参数表示屏幕宽度,第四个参数表示屏幕高度。默认表示整个屏幕大小。
*/
void setViewport(osg::Viewer* viewport);
void setViewport(int x, int y, int width, int height);
const Viewport* getViewport() const;
Viewport* getViewport();
在OSG中,默认了6个裁剪平面以去除没有必要显示的物体。
还可以定义其他的裁剪平面来确定裁减,定义裁剪平面的方法有很多,
如: osg::Scissor 和 osg::ClipPlane
osg::ClipPlane 类继承自 osg::StateAttribute 类,封装了OpenGL 中的glClipPlane() 函数。
设置裁剪平面的有下面几个函数:
/*
参数都指向一个裁剪平面,裁剪平面可以用 Ax + By + Cz + D = 0 方程表示,
因此,A 、B 、C、D 4个数一次表示裁剪平面方程的4个参数
*/
void setClipPlane(const Plane &plane);
void setClipPlane(double a, double b, double c, double d);
void setClipPlane(const Vec4d &plane);
上面方法只是设置一个裁剪平面的参数,如果要调用,还需要在属性中开启该裁剪平面:
root->getOrCreateStateSet()->setAttributeAndModes(cc, osg::StateAttribute::ON);
如果要指定多个裁剪平面,需要指定平面的索引,否则前面指定的裁剪平面会被覆盖。
可以使用以下函数:
// 得到一个裁剪平面的索引或者指定一个平面的索引
void setClipPlaneNum(unsigned int num);
unsigned int getClipPlaneNum() const;
osg::Scissor 类继承自 osg::StateAttribute 类,封装可OpenGL 中glScissor() 函数。
该类主要用于设置 一个视口裁剪平面矩阵。函数如下:
// 参数表示一个平面矩阵的信息(左下角坐标、宽度和高度)
void setScissor(int x, int y, int width, int height);
上面方法只是设置了一个视口裁剪平面矩阵,如果要启用该裁剪平面,可以用以下方法:
root->getOrCreateStateSet()->setAttributeAndModes(cc, osg::StateAttribute::ON);
在osg::Camera 类中除了定义一些基本的变换外,还添加了其他的操作;
清除背景色函数:
void setClearColor(const osg::Vec4 &color);
void osg::Vec4& getClearColor() const;
清除各种缓存信息函数:
void setColorMask(osg::ColorMask* colorMask);
void setColorMask(bool red, bool green, gool blue, bool alpha);
const ColorMask* getColorMask() const;
ColorMask* getColorMask();
例如:
// 向函数中传入OpenGL 缓存标识,表示清除颜色、深度和模板缓存。
viewer->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);