osg 相机
目錄
osg::Camera類 (相機(jī)類)
1、視點(diǎn)變換
2、投影變換
3、視口變換
4、裁剪變換
osg::ClipPlane
osg::Scissor
?5、其他
HUD相機(jī)
HUD相機(jī)示例
osg::Camera類 (相機(jī)類)
osg::Camera 類繼承自 osg::Transform(變換類) 和 osg::CullSettings(裁剪類) 類,用來(lái)管理 OSG 中的模型(視圖矩陣);
相機(jī)的管理主要是通過(guò)各種變換來(lái)實(shí)現(xiàn)的;
1、視點(diǎn)變換
- 視點(diǎn)變換就是設(shè)置視點(diǎn)的方向和位置。
- 默認(rèn)情況下,視點(diǎn)定位為坐標(biāo)原點(diǎn),指向Y正方向。
在 Camera 中的視點(diǎn)變換函數(shù)如下:
/* 第一個(gè)參數(shù)是視點(diǎn)的位置 第二個(gè)參數(shù)是參考點(diǎn)的位置,該點(diǎn)通常為場(chǎng)景中中心軸上的點(diǎn) 第三個(gè)參數(shù)是視點(diǎn)向上的方向向量 */ 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);2、投影變換
????????投影變換在顯示流程中是一個(gè)非常重要的環(huán)節(jié),由于顯示器只能用二維圖像顯示三維物體,因此就要靠投影來(lái)降低維數(shù)。
? ? ? ? 事實(shí)上,投影變換的目的就是定義一個(gè)視景體,使視景體多余的部分裁剪掉,最終進(jìn)入圖像的只是視景體內(nèi)的有關(guān)部分。投影包括透視投影和正視投影兩種。
? ? ? ? 透視投影比較好理解,符合正常的視覺(jué)現(xiàn)象。離視點(diǎn)越近,物體越大;離視點(diǎn)越遠(yuǎn),物體越小;當(dāng)遠(yuǎn)到極點(diǎn)時(shí),物體小時(shí),變?yōu)?span style="background-color:#ffd900;">滅點(diǎn);
在OSG中,有兩種透視投影,即透視視景體和對(duì)稱透視視景體。
- 透視視景體函數(shù)如下 :
- 對(duì)稱透視視景體函數(shù)如下:
在OSG中,正射投影也包括兩種,即正射投影和特殊的正射投影
- ?正射投影函數(shù)如下:
- 特殊正射投影函數(shù)如下:
3、視口變換
- 視口變換就是將視景器內(nèi)投影的物體顯示在二維的視口平面上。
- 它的意義是將經(jīng)過(guò)幾何變換、投影變換和裁剪變換后的物體顯示于屏幕窗口內(nèi)指定的區(qū)域內(nèi),這個(gè)區(qū)域通常為矩形,成為視口。
視口變換函數(shù)如下:
/* 創(chuàng)建或者得到一個(gè)視口 第1~2個(gè)參數(shù)表示屏幕左下角的坐標(biāo); 第三個(gè)參數(shù)表示屏幕寬度,第四個(gè)參數(shù)表示屏幕高度。默認(rèn)表示整個(gè)屏幕大小。 */ void setViewport(osg::Viewer* viewport); void setViewport(int x, int y, int width, int height); const Viewport* getViewport() const; Viewport* getViewport();4、裁剪變換
在OSG中,默認(rèn)了6個(gè)裁剪平面以去除沒(méi)有必要顯示的物體。
還可以定義其他的裁剪平面來(lái)確定裁減,定義裁剪平面的方法有很多,
如: osg::Scissor 和 osg::ClipPlane
osg::ClipPlane
osg::ClipPlane 類繼承自 osg::StateAttribute 類,封裝了OpenGL 中的glClipPlane() 函數(shù)。
設(shè)置裁剪平面的有下面幾個(gè)函數(shù):
/* 參數(shù)都指向一個(gè)裁剪平面,裁剪平面可以用 Ax + By + Cz + D = 0 方程表示, 因此,A 、B 、C、D 4個(gè)數(shù)一次表示裁剪平面方程的4個(gè)參數(shù) */ void setClipPlane(const Plane &plane); void setClipPlane(double a, double b, double c, double d); void setClipPlane(const Vec4d &plane);?上面方法只是設(shè)置一個(gè)裁剪平面的參數(shù),如果要調(diào)用,還需要在屬性中開(kāi)啟該裁剪平面:
root->getOrCreateStateSet()->setAttributeAndModes(cc, osg::StateAttribute::ON);如果要指定多個(gè)裁剪平面,需要指定平面的索引,否則前面指定的裁剪平面會(huì)被覆蓋。
可以使用以下函數(shù):
// 得到一個(gè)裁剪平面的索引或者指定一個(gè)平面的索引 void setClipPlaneNum(unsigned int num); unsigned int getClipPlaneNum() const;osg::Scissor
osg::Scissor 類繼承自 osg::StateAttribute 類,封裝可OpenGL 中g(shù)lScissor() 函數(shù)。
該類主要用于設(shè)置 一個(gè)視口裁剪平面矩陣。函數(shù)如下:
// 參數(shù)表示一個(gè)平面矩陣的信息(左下角坐標(biāo)、寬度和高度) void setScissor(int x, int y, int width, int height);上面方法只是設(shè)置了一個(gè)視口裁剪平面矩陣,如果要啟用該裁剪平面,可以用以下方法:
root->getOrCreateStateSet()->setAttributeAndModes(cc, osg::StateAttribute::ON);?5、其他
在osg::Camera 類中除了定義一些基本的變換外,還添加了其他的操作;
清除背景色函數(shù):
void setClearColor(const osg::Vec4 &color); void osg::Vec4& getClearColor() const;清除各種緩存信息函數(shù):
void setColorMask(osg::ColorMask* colorMask); void setColorMask(bool red, bool green, gool blue, bool alpha); const ColorMask* getColorMask() const; ColorMask* getColorMask();例如:
// 向函數(shù)中傳入OpenGL 緩存標(biāo)識(shí),表示清除顏色、深度和模板緩存。 viewer->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);HUD相機(jī)
HUD 相機(jī)用來(lái)在屏幕固定位置顯示一些信息(文字、圖片等)
HUD相機(jī)示例
// 創(chuàng)建HUD 相機(jī) osg::Camera* createHUD() {// 新建相機(jī)osg::ref_ptr<Camera> camera = new Camera;// 設(shè)置矩陣內(nèi)容camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1580, 0, 1024));// 設(shè)置視圖矩陣內(nèi)容camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);camera->setViewMatrix(osg::Matrix::identity());// 只清理深度緩沖區(qū)camera->setClearMask(GL_DEPTH_BUFFER_BIT);// 設(shè)置相機(jī)渲染順序camera->setRenderOrder(osg::Camera::POST_RENDER);// 設(shè)置相機(jī)是否接收?qǐng)D形設(shè)備傳遞的人機(jī)交互事件camera->setAllowEventFonce(false);// 創(chuàng)建節(jié)點(diǎn)osg::ref_ptr<Geode> geode = new Geode;// 把漢字或者圖片添加到節(jié)點(diǎn)即可 (此處以文字為例)osg::ref_ptr<osgText::Text> text = createText();geode->addDrawable(text);// 把節(jié)點(diǎn)放入相機(jī)camera->addChild(geode);return camera;}// 創(chuàng)建文字 osg::ref_ptr<osgText::Text> createText() { // 創(chuàng)建文字節(jié)點(diǎn)osg::ref_ptr<osgText::Text> text = new osgText::Text;// 設(shè)置字體text->setFont("fonts/arial.ttf");// 設(shè)置文字節(jié)點(diǎn)位置text->setPosition(osg::Vec3(150.0f, 800.0f, 0.0f));// 設(shè)置文字內(nèi)容text->setText("你好");return text;}總結(jié)
- 上一篇: SQL优化面试专题
- 下一篇: 程序员,为你的将来定位好学习的方向!