日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

osg 入门知识点

發布時間:2024/1/1 编程问答 75 豆豆
生活随笔 收集整理的這篇文章主要介紹了 osg 入门知识点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

osg 入門知識點

    • osg第一天 -- 認識osg
        • osg 坐標系
        • osg點和向量
        • 向量的基本接口功能(點乘、叉乘、求模)
        • osg矩陣
        • 四元數
    • osg第二天 -- osg場景圖
        • 智能指針(osg::ref_ptr)
        • 觀察指針(osg::observer_ptr)
        • 智能指針和觀察指針的用處
        • 常用的osg節點類
    • osg第三天 -- 圖元
        • 頂點屬性
        • 圖元類型
        • 圖元組
    • osg第四天 -- 圖元紋理、屬性
        • StateSet 狀態集
        • 紋理貼圖
    • osg第五天 -- 時間響應和碰撞檢測
        • 事件適配器 GUIEventAdapter
        • 動作適配器 GUIActionAdapter
        • 碰撞檢測實戰(類似于點擊事件)
    • osg第六天 -- 遍歷
        • NodeVisitor 類
        • osg遍歷實例
    • osg第七天 -- 回調
        • 使用回調實現地球的公轉自轉效果
        • 使用粒子效果繪制行星尾跡
    • osg第八天 -- 相機及其應用
        • HUD相機
        • HUD相機實例
        • 注意
    • osg第九天 -- 漫游
        • 漫游的使用

osg第一天 – 認識osg

osg 坐標系

osg 坐標系運用的時 右手坐標系

osg坐標系系統分為三種:

  • 世界坐標
    世界坐標系為所有對象的位置提供一個絕對的參考標準;
    世界坐標系也被廣泛地成為全局坐標系或宇宙坐標系;
    一般用于:繪制體、幾何體
  • 局部坐標
    物體坐標系是針對某一特定的物體而建立的獨立坐標系;
    每一個物體都有自己的坐標系;
    物體坐標系對于描述特定的物體非常方便;
    一般用于:頂點、法線等
  • 相機坐標
    攝像機坐標系可以被看作是一種特殊的物體坐標系,該物體坐標系就定義在攝像機的屏幕可視區域。

osg點和向量

概念:
向量一般是指,一個帶有方向和大小的量;
一般有二維向量、三維向量、三維向量等等, n維向量;
在osg中分別用 vec2、vec3、 vec4 來表示;

點:
在三維中,點一般用vec3(x, y, z) 來表示;

向量的基本接口功能(點乘、叉乘、求模)

點乘: n1·n2

點乘 又名 “ 內積 ” 和 “ 數量積 ”;
用法:n1^n2

公式n1[0] * n2[0] + n1[1] * n2[1] + n1[2] * n2[2]
( n1、n2 代表三維向量,下標123 分別代表 osg坐標的 x y z )

作用:一般用來計算兩個向量的夾角

叉乘: n1^n2

叉乘 又名 “ 向量積 ” 、“ 外積 ” 和 “ 叉積 ”;

公式:
x = ay * bz - az * by
y = -( ax*bz - az * bx )
z = ax * by - ay * bx
( a、b 代表三維向量,x y z 分別代表 osg坐標的 x y z )

作用:
在三維幾何中,向量a和向量b的叉乘結果是一個向量,更為熟知的叫法是法向量,該向量垂直于a和b向量構成的平面。
在3D圖像學中,叉乘的概念非常有用,可以通過兩個向量的叉乘,生成第三個垂直于a,b的法向量,從而構建X、Y、Z坐標系。
在二維空間中,叉乘還有另外一個幾何意義就是:aXb等于由向量a和向量b構成的平行四邊形的面積。

求模:

公式: n[0] * n[0] + n[1] * n[1] + n[2] * n[2] 的平方根
( n代表三維向量)

作用:
求距離

osg矩陣

左乘和右乘

( 左乘 )點和向量在左邊,向右乘
( 右乘 )點和向量在右邊,向左乘
Matrix 采用了左乘操作
OpenGL 采用了右乘操作

矩陣變換中的級聯順序

矩陣變換順序執行 SRT 原則
(一般先縮小和旋轉,最后平移)

四元數

四元數是通過使用四個數來表達方位,其目的是避免旋轉過程中的萬向鎖問題。所以在3D中,四元數的主要用途即是用于旋轉。

四元數轉矩陣

osg::Matrix mat; osg::Quat qat; qat.get(mat);

歐拉角轉四元數

osg::Quat HPRToQuat(double heading, double pitch, double roll) {osg::Quat q(roll, osg::Vec3d(0.0, 1.0, 0.0), pitch, osg::Vec3d(1.0, 0.0, 0.0),heading, osg::Vec3d(0.0, 0.0, 1.0));return q; }

osg第二天 – osg場景圖

智能指針(osg::ref_ptr)

為 osg 執行內存管理
通過智能指針的方式讓osg自己處理對象的銷毀操作

get() 和 release() 的區別

get()

  • 獲取原始指針

release()

  • 獲取原始指針后,并釋放智能指針

觀察指針(osg::observer_ptr)

觀察指針也屬于智能指針;

osg::ref_ptr 是強指針類型
osg::observer_ptr 是弱指針類型

觀察指針沒有引用計數功能,僅僅記錄該對象的地址

智能指針和觀察指針的用處

在接收別人的指針時,用普通指針,避免智能指針給析構掉
如果接受的指針暫時不用,就用觀察者指針接收
自己管理的指針一般用智能指針

常用的osg節點類

Referenced

通用的基類,所有節點均繼承于Referenced, 它包含了一個整形的引用計數器;

Node

節點

Group

  • 組節點,可以添加任意數量的子節點,子節點本身也可以繼續分發子節點
  • 根節點一般也用Group, 一個場景一般只有一個根節點

Geode

  • 葉子節點,用來保存幾何信息以便渲染
  • geode不會再有葉子節點
  • geode 是 “ geometry node ” 的簡稱
  • Geode 提供了 addDrawable() 的方法用來關聯程序中的幾何信息

Drawable

  • 繪制體,用于保存要渲染的數據;
  • 無法直接實例化

Geometry

幾何

  • 指定頂點、法線和顏色
  • 指定數據繪制的方式
  • 將幾何圖形添加到葉子節點中

Transform

變換節點
osg 通過 osg::Transform 家族來實現幾何數據的變換

MatrixTransform

矩陣變換節點

LOD

細節層次節點可以根據觀察者的距離調用不同的子節點

AutoTransform

自動變換節點, 繼承自Transform, 可以自動的調整大小和角度

void setAutoRotateMode(AutoRotateMode mode)enum osg::AutoTransform::AutoRotateMode Enumerator: NO_ROTATION ROTATE_TO_SCREEN // 自動朝向屏幕 ROTATE_TO_CAMERA // 自動朝向攝像機

PositionAttitudeTransform

位置變換節點, 繼承自Transform,
主要作用是提供 模型的位置變換、大小縮放、原點位置的設置以及坐標系的變化
主要函數:

  • void setPosition(const Vec3d &pos); // 設置位置
  • const Vec3d &getPosition() const; // 得到位置
  • void setAttitude(const Quat &quat) // 設置姿態
  • const Quat &getAttitude() const // 得到姿態

Switch

開關節點,可以渲染或跳過指定的子節點

osg第三天 – 圖元

頂點屬性

  • 幾何體是由多個點組成的
  • 頂點是屬性定義每個點的信息:
    – 頂點坐標
    – 頂點顏色
    – 頂點法線
    – 紋理坐標
    (其中, 頂點坐標是必須要的, 其他屬性可選)
    對于顏色、法線等,提供了綁定方式。 包括;
    1、 綁定每個頂點( BING_PER_VERTEX )
    2、 綁定圖元組 ( BING_PER_PRIMITIVE_SET )
    3、 綁定所有 ( BING_OVERALL )

圖元類型

osg::PrimitiveSet 類, 該類主要松散封裝了OpenGL的繪制基元;

類型功能功能描述連線順序
POINTS繪制點繪制用戶指定的所有頂點0、1、2、3、4、5
LINES繪制直線直線的起點、終點由數組中先后相鄰的兩個點決定,用戶提供的點不止兩個時,將嘗試繼續繪制新的直線。01、23、45
LINE_STRIP繪制多段直線多段直線的第一段由數組的前兩個點決定,其余段的起點位置為上一段的終點坐標,而終點位置由數組中隨后的點決定。012345
LINE_LOOP繪制封閉直線繪制方式與多端直線相同,但是最后將自動封閉該直線。0123450
TRIANGLES繪制三角形三角形的三個頂點由數組相鄰的三個點決定;用戶提供的點不止三個時,將嘗試繼續繪制新的三角形。( 方向為逆時針時,朝向屏幕面是正面 )012、345
TRIANGLE_STRIP繪制多段三角形第一段三角形的由數組的前三個點決定; 其余段的三角形繪制,起始邊由上一段三角形的后兩個點決定,第三點由數組中隨后的一點決定。012、213、234、435、456
TRIANGLE_FAN繪制三角形扇面第一段三角形的由數組中的前三個點決定;其余段三角形的繪制, 起始邊由整個數組的第一點和上一段三角形的最后一個點決定,第三點由數組中隨后的一點決定。012、023、034、045、056
QUADS繪制四邊形四邊形的四個頂點由數組中相鄰的四個頂點決定,并按照逆時針的順序進行繪制;用戶提供的點不止四個時,將嘗試繼續繪制新的四邊形。
QUAD_STRIP繪制多段四邊形第一段四邊形的起始邊由數組中的前兩個點決定,邊的矢量方向由這兩點的延伸方向決定;起始邊的對邊由其后的兩個點決定,如果起始邊和對邊的矢量方向不同,那么四邊形將會扭曲;其余段四邊形的繪制,起始邊由上一段決定,其對邊由隨后的兩點及其延伸方向決定。
POLYGON繪制任意多邊形根據用戶提供的頂點數量,繪制多邊形。0123450

圖元組

作用:

圖元組用來告訴OSG, 在繪制圖形時,使用哪些頂點、使用哪個圖元對頂點進行組合。

圖元組分兩種:

  • DrawArrays
    DrawArrays 直接告訴 OSG 使用的頂點在頂點數組中的起點、終點、使用的圖元屬性,該方式效率高,
    但對于復雜的模型需要傳入較多的點時比較麻煩。
  • DrawElements
    DrawElements 告訴 OSG 使用頂點的索引值數組和圖元,該方式不需要傳入重復的點,使用簡單,
    但由于內部需要復制數據,因此效率不如第一種。
  • 在osg中,有三種生成幾何體的手段:

  • 松散封裝的OpenGLh繪制基元osg::Geometry
  • 使用OSG中預定義的基本幾何體
  • 從文件中導入場景模型
  • osg第四天 – 圖元紋理、屬性

    StateSet 狀態集

    為什么引用狀態集?

    由于 OpenGL 狀態集的存在,需要手動保存原始狀態,在繪制完恢復原始狀態,給使用者帶來較大困難,OSG 為了解決這個問題,引用了 OSG 狀態集( osg::StateSet )。

    了解狀態集

    狀態集中保存了用戶修改的狀態信息,在退出時自動恢復狀態
    狀態集提供了兩個接口,設置狀態屬性或狀態

    • setAttributeAndModes()
    • setMode()

    osg 的狀態較多,例如 Txxture2D、Point、LineWidth 等都為一種屬性。

    紋理貼圖

    紋理概念:

    • 紋理 ( Texture ) 是一種狀態屬性,其特點與以他狀態相同;
    • 紋理的內部時數組的概念,保存了圖像的像素值,可貼在幾何體上,使幾何體更真實;
    • 其中,二維紋理 ( Texture2D ) 是最常用的紋理;

    二維紋理:

    • 對于二維紋理,在內部其橫縱坐標被歸一化為 ( 0~1 ) ;
    • 為了區別于世界空間的坐標系,其坐標不使用 x 、y 表示, 而是 s 、t 。

    紋理坐標:

    • 紋理坐標是一種頂點屬性,表示該頂點使用紋理的那個像素值
    • 紋理貼圖必須設置紋理坐標,否則無法貼圖

    紋理環繞模式:

    紋理環繞模式為了解決紋理坐標超過紋理范圍時該怎樣獲取像素值的情況,規定幾種模式:

    • CLAMP ----------// 截取
    • CLAMP_TO_EDGE ---------- // 邊框始終被忽略
    • CLAMP_TO_BORDER ---------- // 它使用的紋理取自圖像的邊框,沒有邊框就使用常量邊框顏色
    • REPEAT -------- // 紋理重復映射
    • MIRROR -------- // 紋理鏡像的重復映射

    紋理環繞模式通過setWrap設置,第一個參數表示紋理坐標軸STR,第二個參數為選擇的環繞模式


    紋理的過濾方法:

    • MIN_FILTER -------- // 用于縮小
    • MAG_FILTER --------- // 用于放大

    紋理采樣:

    • 在幾何體顯示在屏幕上時,顯示的像素與紋理的像素位置不能完全對應, 總會有些差值;
    • OpenGL 內部通過紋理采樣來獲取紋理像素值;

    多重紋理:

    • 為了展現幾何體真實效果,有時需要多個紋理; 例如:墻壁的污漬紋理
    • 幾何體可以有多重紋理,內部通過紋理單元來進行切換
    • 固定線管下,OpenGL 支持 8 個紋理單元
    • 當我們需要向某個紋理單元設置紋理時,需要設置該紋理單元對應的紋理坐標。

    osg第五天 – 時間響應和碰撞檢測

    OSG 中主要使用 osgGA 庫來處理用戶的交互動作,GA 的全稱是 GUI Abstraction, 即圖形接口抽象層

    事件適配器 GUIEventAdapter

    • 在用戶端,通常使用 GUIEventAdapter 類作為系統交互事件和 OSG 交互時間的適配接口,
    • 它定義了一個且僅有一個人機交互事件
    • 基本包括了常見窗口系統中的鼠標、鍵盤、甚至觸摸板的操作。

    動作適配器 GUIActionAdapter

    • 用戶向系統傳遞請求通過 GUIActionAdapter 類來實現。
    • 常見的用戶請求包括窗口的刷新以及鼠標坐標的位置。

    碰撞檢測實戰(類似于點擊事件)

  • 繼承osgGA::GUIEventHandler
  • 重寫handle 方法
  • 調用
  • // CPickHandle.h class CPickHandle :public osgGA::GUIEventHandler {// 重寫handle, 參數為 事件適配器 和 動作適配器bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);// 拾取void pick(osg::ref_ptr<<osgViewer::View> view, float x, float y); } // CPickHandle.cpp // 事件處理函數 bool CPickHandle::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {// 把動作適配器轉化為 viewosg::ref_ptr<osgViewer::View> view = dynamic_cast<osgViewer::View*> (&aa);if(!view){return false;}switch(ea.getEventType()){// 鼠標按下case(osgGA::GUIEventAdapter::PUSH):{m_fx = ea.getX();m_fy = ea.getY();break;}// 鼠標釋放case(osgGA::GUIEventAdapter::RELEASE):{if(m_fx == ea.getX() && m_fy = ea.getY()){pick(view.get(), ea.getX(), ea.getY());}break;}default:break;} }// 拾取 void CPickHandle::pick(osg::ref_ptr<osgViewer::View> view, float x, float y) {// 線段相交檢測平臺osgUtil::LineSegmentIntersector::Intersections intersection;if(view->computeIntersections(x, y, intersection)){osgUtil::LineSegmentIntersector::Intersections::iterator it = intersection.begin();// 操作節點............}}

    osg第六天 – 遍歷

    NodeVisitor 類

    • NodeVisitor 類是 OSG 對于訪問器設計思想的具體實現。
    • 從本質上說,NodeVisitor 類遍歷了一個場景圖形并為每一個被訪問節點調用特定的函數
    • NodeVisitor 在 OSG 的應用中無處不在

    osg遍歷實例

    osg遍歷的使用實例: 遍歷顯示節點信息
    1、繼承 osg::NodeVisitor
    2、重載 apply() 函數
    3、調用函數 accept() 方法

    // CFindNode.h // 繼承osg::NodeVisitor class CFindNode :public osg::NodeVisitor { public:CFindNode();virtual void apply(osg::Node& node);osg::Node* getNode(); protected:osg::ref_ptr<osg::Node> _node; } // CFindNode.cpp CFindNode::CFindNode() :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { } // 重載 apply() 函數 void CFindNode::apply(osg::Node& node) {if(node.getName() == "Ball"){_node = &node;}traverse(node); }osg::Node* CFindNode::getNode() {return _node.get(); } // main.cpp osg::ref_ptr<osgViewer::Viewer> rpViewer = new osgViewer::Viewer; CFindNode cfd; // 調用函數 accept() 方法 osg::ref_ptr<osg::Group> group = new osg::Group(); group->accept(cfd);

    osg第七天 – 回調

    使用回調實現地球的公轉自轉效果

    osg回調的使用實例: ----使用回調實現 地球的公轉和自轉

  • 繼承 NodeCallBack 類
  • 重寫操作符 NodeCallback::operator()
  • 通過 setXXXCallback 或 addXXXCallback 注冊到節點對象
  • // CPlanetRotate.h // 繼承 NodeCallBack 類 class CPlanetRotate :public osg::NodeCallBack { public:virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); } // CPlanetRotate.cpp void CPlanetRotate::operator(osg::Node* node, osg::NodeVisitor* nv) {// 轉為矩陣變換節點if(osg::ref_ptr<osg::MatrixTransform> rpMt = dynamic_cast<osg::MatrixTransform*>(node)){if(rpMt.valid()){osg::Matrix mtRotate,MT,MR;MR.makeRotate(m_dAngle, osg::Z_AXIS); // 自轉MT.makeTranslate(osg::Vec3(getRevolutionRadius(), 0, 0)); // 位移mtRotate.makeRotate(m_dAngle, osg::Z_AXIS); // 公轉rpMt.setMatrix(MR * MT * mtRotate); // 設置矩陣 (括號里的順序不可改變)m_dAngle += 0.01;}}traverse(node, nv); // 繼續遍歷 } // main.cpp m_pCPlanetRotate = new CPlanetRotate(); // 創建對象 trans->setUpdateCallBack(m_pCPlanetRotate); // 調用回調

    使用粒子效果繪制行星尾跡

    實現粒子效果

    // Star.cpp osg::ref<osg::Geode> Star::buildTail(osg::Vec3 position, osg::MatrixTransform* scalar) {// 參數為位置和大小osg::ref_ptr<osgParticle::FireEffect> fire = new osgParticle::FireEffect(position,10);fire->setUserLocalParticleSystem(false);// 設置粒子噴射時間為--無限fire->getEmitter()->setEnabless(true);fire->getEmitter()->setLifeTime(1);scalar->addChild(fire);osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(fire->getParticleSystem());return geode; }

    添加粒子

    // main.cpp osg::ref_ptr<osg::Geode> tail = bulidTail(osg::Vec3(0,0,0), trans); group->addChild(tail);

    osg第八天 – 相機及其應用

    HUD相機

    HUD相機 全稱為 head up display : 意思為 “ 頭顯示
    ( 用于常顯在屏幕坐標系的固定位置來展示信息)

    HUD相機實例

    osg HUD相機使用實例:

  • 創建HUD相機
  • 把相機添加到視圖
  • // CHUDProvider.h class CHUDProvider { public:osg::Camera* createHUD(); // 創建HUD相機 }; // CHUDProvider.cpp osg::Camera* CHUDProvider::createHUD() {osg::Camera* pCamera = new osg::Camera;// 設置投影矩陣內容pCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1580, 0, 1024));// 設置視圖矩陣內容pCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);pCamera->setViewMatrix(osg::Matrix:identity());// 清理深度緩沖pCamera->setClearMask(GL_DEPTH_BUFFER_BIT);// 設置相機的渲染順序pCamera->setRenderOrder(osg::Camera::POST_RENDER);// 設置相機是否接受圖形設備傳遞的人機交互事件pCamera->setAllowEventFocus(false);{osg::Geode* pGeode = new osg::Geode();osg::StateSet* pStateset = pGeode->getOrCreateStateSet();pStateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);std::string strTimeFont("fonts/arial.ttf");float fFontSize = 25.0;osg::Vec3 position(150.0f, 800.0f, 0.0f);// 文字{osgText::Text* pText = new osgText::Text; // 新建文本字節pGeode->addDrawable(pText); // 添加文字節點到幾何節點中pText->setFont(strTimeFont); // 設置字體pText->setPosition(position); // 設置文字節點位置pText->setText("顯示文字內容"); // 設置文字內容}pCamera->addChild(pGeode);}return pCamera; } // main.cpp CHUDProvider cHUDProvider = new CHUDPrivider(); // 創建HUD對象 osg::Camera* camera = cHUDProvider.createHUD(); // 創建HUD相機 group->addChild(camera); // 將HUD相機添加到節點中

    注意

    HUD顯示文字時,需注意以下幾點:

  • 渲染順序設置為POST,否則可能被其他圖形所覆蓋
  • 注意關閉光照和深度
  • 投影矩陣通常設置為屏幕尺寸大小
  • osg第九天 – 漫游

    漫游的使用

    1、繼承 osg::CameraManipulator
    2、重寫四個虛函數 (其中兩個set方法,實現可為空)

    virtual void setByMatrix(const osg::Matrixd& matrix); virtual void setByInverseMatrix(const osg::Matrixd& matrix); virtual osg::Matrixd getMatrix() const; virtual osg::Matrixd getInverMatrix() const;

    3、重寫事件處理

    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);

    4、調用

    osg::ref_ptr<CDriveManupulator> rpDrive = new CDriverManupulator(); rpViewer->setCameraManipulator(rpDrive);

    總結

    以上是生活随笔為你收集整理的osg 入门知识点的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。