osg 入门知识点
osg 入門知識點
- osg第一天 -- 認識osg
- osg 坐標系
- osg點和向量
- 向量的基本接口功能(點乘、叉乘、求模)
- osg矩陣
- 四元數(shù)
- osg第二天 -- osg場景圖
- 智能指針(osg::ref_ptr)
- 觀察指針(osg::observer_ptr)
- 智能指針和觀察指針的用處
- 常用的osg節(jié)點類
- osg第三天 -- 圖元
- 頂點屬性
- 圖元類型
- 圖元組
- osg第四天 -- 圖元紋理、屬性
- StateSet 狀態(tài)集
- 紋理貼圖
- osg第五天 -- 時間響應(yīng)和碰撞檢測
- 事件適配器 GUIEventAdapter
- 動作適配器 GUIActionAdapter
- 碰撞檢測實戰(zhàn)(類似于點擊事件)
- osg第六天 -- 遍歷
- NodeVisitor 類
- osg遍歷實例
- osg第七天 -- 回調(diào)
- 使用回調(diào)實現(xiàn)地球的公轉(zhuǎn)自轉(zhuǎn)效果
- 使用粒子效果繪制行星尾跡
- osg第八天 -- 相機及其應(yīng)用
- HUD相機
- HUD相機實例
- 注意
- osg第九天 -- 漫游
- 漫游的使用
osg第一天 – 認識osg
osg 坐標系
osg 坐標系運用的時 右手坐標系
osg坐標系系統(tǒng)分為三種:
- 世界坐標
世界坐標系為所有對象的位置提供一個絕對的參考標準;
世界坐標系也被廣泛地成為全局坐標系或宇宙坐標系;
一般用于:繪制體、幾何體 - 局部坐標
物體坐標系是針對某一特定的物體而建立的獨立坐標系;
每一個物體都有自己的坐標系;
物體坐標系對于描述特定的物體非常方便;
一般用于:頂點、法線等 - 相機坐標
攝像機坐標系可以被看作是一種特殊的物體坐標系,該物體坐標系就定義在攝像機的屏幕可視區(qū)域。
osg點和向量
概念:
向量一般是指,一個帶有方向和大小的量;
一般有二維向量、三維向量、三維向量等等, n維向量;
在osg中分別用 vec2、vec3、 vec4 來表示;
點:
在三維中,點一般用vec3(x, y, z) 來表示;
向量的基本接口功能(點乘、叉乘、求模)
點乘: n1·n2
點乘 又名 “ 內(nèi)積 ” 和 “ 數(shù)量積 ”;
用法: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的叉乘結(jié)果是一個向量,更為熟知的叫法是法向量,該向量垂直于a和b向量構(gòu)成的平面。
在3D圖像學(xué)中,叉乘的概念非常有用,可以通過兩個向量的叉乘,生成第三個垂直于a,b的法向量,從而構(gòu)建X、Y、Z坐標系。
在二維空間中,叉乘還有另外一個幾何意義就是:aXb等于由向量a和向量b構(gòu)成的平行四邊形的面積。
求模:
公式: n[0] * n[0] + n[1] * n[1] + n[2] * n[2] 的平方根
( n代表三維向量)
作用:
求距離
osg矩陣
左乘和右乘
( 左乘 )點和向量在左邊,向右乘
( 右乘 )點和向量在右邊,向左乘
Matrix 采用了左乘操作
OpenGL 采用了右乘操作
矩陣變換中的級聯(lián)順序
矩陣變換順序執(zhí)行 SRT 原則
(一般先縮小和旋轉(zhuǎn),最后平移)
四元數(shù)
四元數(shù)是通過使用四個數(shù)來表達方位,其目的是避免旋轉(zhuǎn)過程中的萬向鎖問題。所以在3D中,四元數(shù)的主要用途即是用于旋轉(zhuǎn)。
四元數(shù)轉(zhuǎn)矩陣
osg::Matrix mat; osg::Quat qat; qat.get(mat);歐拉角轉(zhuǎn)四元數(shù)
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 執(zhí)行內(nèi)存管理
通過智能指針的方式讓osg自己處理對象的銷毀操作
get() 和 release() 的區(qū)別
get()
- 獲取原始指針
release()
- 獲取原始指針后,并釋放智能指針
觀察指針(osg::observer_ptr)
觀察指針也屬于智能指針;
osg::ref_ptr 是強指針類型
osg::observer_ptr 是弱指針類型
觀察指針沒有引用計數(shù)功能,僅僅記錄該對象的地址
智能指針和觀察指針的用處
在接收別人的指針時,用普通指針,避免智能指針給析構(gòu)掉
如果接受的指針暫時不用,就用觀察者指針接收
自己管理的指針一般用智能指針
常用的osg節(jié)點類
Referenced
通用的基類,所有節(jié)點均繼承于Referenced, 它包含了一個整形的引用計數(shù)器;
Node
節(jié)點
Group
- 組節(jié)點,可以添加任意數(shù)量的子節(jié)點,子節(jié)點本身也可以繼續(xù)分發(fā)子節(jié)點
- 根節(jié)點一般也用Group, 一個場景一般只有一個根節(jié)點
Geode
- 葉子節(jié)點,用來保存幾何信息以便渲染
- geode不會再有葉子節(jié)點
- geode 是 “ geometry node ” 的簡稱
- Geode 提供了 addDrawable() 的方法用來關(guān)聯(lián)程序中的幾何信息
Drawable
- 繪制體,用于保存要渲染的數(shù)據(jù);
- 無法直接實例化
Geometry
幾何
- 指定頂點、法線和顏色
- 指定數(shù)據(jù)繪制的方式
- 將幾何圖形添加到葉子節(jié)點中
Transform
變換節(jié)點
osg 通過 osg::Transform 家族來實現(xiàn)幾何數(shù)據(jù)的變換
MatrixTransform
矩陣變換節(jié)點
LOD
細節(jié)層次節(jié)點可以根據(jù)觀察者的距離調(diào)用不同的子節(jié)點
AutoTransform
自動變換節(jié)點, 繼承自Transform, 可以自動的調(diào)整大小和角度
void setAutoRotateMode(AutoRotateMode mode)enum osg::AutoTransform::AutoRotateMode Enumerator: NO_ROTATION ROTATE_TO_SCREEN // 自動朝向屏幕 ROTATE_TO_CAMERA // 自動朝向攝像機PositionAttitudeTransform
位置變換節(jié)點, 繼承自Transform,
主要作用是提供 模型的位置變換、大小縮放、原點位置的設(shè)置以及坐標系的變化
主要函數(shù):
- void setPosition(const Vec3d &pos); // 設(shè)置位置
- const Vec3d &getPosition() const; // 得到位置
- void setAttitude(const Quat &quat) // 設(shè)置姿態(tài)
- const Quat &getAttitude() const // 得到姿態(tài)
Switch
開關(guān)節(jié)點,可以渲染或跳過指定的子節(jié)點
osg第三天 – 圖元
頂點屬性
- 幾何體是由多個點組成的
- 頂點是屬性定義每個點的信息:
– 頂點坐標
– 頂點顏色
– 頂點法線
– 紋理坐標
(其中, 頂點坐標是必須要的, 其他屬性可選)
對于顏色、法線等,提供了綁定方式。 包括;
1、 綁定每個頂點( BING_PER_VERTEX )
2、 綁定圖元組 ( BING_PER_PRIMITIVE_SET )
3、 綁定所有 ( BING_OVERALL )
圖元類型
osg::PrimitiveSet 類, 該類主要松散封裝了OpenGL的繪制基元;
| POINTS | 繪制點 | 繪制用戶指定的所有頂點 | 0、1、2、3、4、5 |
| LINES | 繪制直線 | 直線的起點、終點由數(shù)組中先后相鄰的兩個點決定,用戶提供的點不止兩個時,將嘗試繼續(xù)繪制新的直線。 | 01、23、45 |
| LINE_STRIP | 繪制多段直線 | 多段直線的第一段由數(shù)組的前兩個點決定,其余段的起點位置為上一段的終點坐標,而終點位置由數(shù)組中隨后的點決定。 | 012345 |
| LINE_LOOP | 繪制封閉直線 | 繪制方式與多端直線相同,但是最后將自動封閉該直線。 | 0123450 |
| TRIANGLES | 繪制三角形 | 三角形的三個頂點由數(shù)組相鄰的三個點決定;用戶提供的點不止三個時,將嘗試繼續(xù)繪制新的三角形。( 方向為逆時針時,朝向屏幕面是正面 ) | 012、345 |
| TRIANGLE_STRIP | 繪制多段三角形 | 第一段三角形的由數(shù)組的前三個點決定; 其余段的三角形繪制,起始邊由上一段三角形的后兩個點決定,第三點由數(shù)組中隨后的一點決定。 | 012、213、234、435、456 |
| TRIANGLE_FAN | 繪制三角形扇面 | 第一段三角形的由數(shù)組中的前三個點決定;其余段三角形的繪制, 起始邊由整個數(shù)組的第一點和上一段三角形的最后一個點決定,第三點由數(shù)組中隨后的一點決定。 | 012、023、034、045、056 |
| QUADS | 繪制四邊形 | 四邊形的四個頂點由數(shù)組中相鄰的四個頂點決定,并按照逆時針的順序進行繪制;用戶提供的點不止四個時,將嘗試繼續(xù)繪制新的四邊形。 | |
| QUAD_STRIP | 繪制多段四邊形 | 第一段四邊形的起始邊由數(shù)組中的前兩個點決定,邊的矢量方向由這兩點的延伸方向決定;起始邊的對邊由其后的兩個點決定,如果起始邊和對邊的矢量方向不同,那么四邊形將會扭曲;其余段四邊形的繪制,起始邊由上一段決定,其對邊由隨后的兩點及其延伸方向決定。 | |
| POLYGON | 繪制任意多邊形 | 根據(jù)用戶提供的頂點數(shù)量,繪制多邊形。 | 0123450 |
圖元組
作用:
圖元組用來告訴OSG, 在繪制圖形時,使用哪些頂點、使用哪個圖元對頂點進行組合。
圖元組分兩種:
DrawArrays 直接告訴 OSG 使用的頂點在頂點數(shù)組中的起點、終點、使用的圖元屬性,該方式效率高,
但對于復(fù)雜的模型需要傳入較多的點時比較麻煩。
DrawElements 告訴 OSG 使用頂點的索引值數(shù)組和圖元,該方式不需要傳入重復(fù)的點,使用簡單,
但由于內(nèi)部需要復(fù)制數(shù)據(jù),因此效率不如第一種。
在osg中,有三種生成幾何體的手段:
osg第四天 – 圖元紋理、屬性
StateSet 狀態(tài)集
為什么引用狀態(tài)集?
由于 OpenGL 狀態(tài)集的存在,需要手動保存原始狀態(tài),在繪制完恢復(fù)原始狀態(tài),給使用者帶來較大困難,OSG 為了解決這個問題,引用了 OSG 狀態(tài)集( osg::StateSet )。
了解狀態(tài)集
狀態(tài)集中保存了用戶修改的狀態(tài)信息,在退出時自動恢復(fù)狀態(tài)
狀態(tài)集提供了兩個接口,設(shè)置狀態(tài)屬性或狀態(tài)
- setAttributeAndModes()
- setMode()
osg 的狀態(tài)較多,例如 Txxture2D、Point、LineWidth 等都為一種屬性。
紋理貼圖
紋理概念:
- 紋理 ( Texture ) 是一種狀態(tài)屬性,其特點與以他狀態(tài)相同;
- 紋理的內(nèi)部時數(shù)組的概念,保存了圖像的像素值,可貼在幾何體上,使幾何體更真實;
- 其中,二維紋理 ( Texture2D ) 是最常用的紋理;
二維紋理:
- 對于二維紋理,在內(nèi)部其橫縱坐標被歸一化為 ( 0~1 ) ;
- 為了區(qū)別于世界空間的坐標系,其坐標不使用 x 、y 表示, 而是 s 、t 。
紋理坐標:
- 紋理坐標是一種頂點屬性,表示該頂點使用紋理的那個像素值
- 紋理貼圖必須設(shè)置紋理坐標,否則無法貼圖
紋理環(huán)繞模式:
紋理環(huán)繞模式為了解決紋理坐標超過紋理范圍時該怎樣獲取像素值的情況,規(guī)定幾種模式:
- CLAMP ----------// 截取
- CLAMP_TO_EDGE ---------- // 邊框始終被忽略
- CLAMP_TO_BORDER ---------- // 它使用的紋理取自圖像的邊框,沒有邊框就使用常量邊框顏色
- REPEAT -------- // 紋理重復(fù)映射
- MIRROR -------- // 紋理鏡像的重復(fù)映射
紋理環(huán)繞模式通過setWrap設(shè)置,第一個參數(shù)表示紋理坐標軸STR,第二個參數(shù)為選擇的環(huán)繞模式
紋理的過濾方法:
- MIN_FILTER -------- // 用于縮小
- MAG_FILTER --------- // 用于放大
紋理采樣:
- 在幾何體顯示在屏幕上時,顯示的像素與紋理的像素位置不能完全對應(yīng), 總會有些差值;
- OpenGL 內(nèi)部通過紋理采樣來獲取紋理像素值;
多重紋理:
- 為了展現(xiàn)幾何體真實效果,有時需要多個紋理; 例如:墻壁的污漬紋理
- 幾何體可以有多重紋理,內(nèi)部通過紋理單元來進行切換
- 固定線管下,OpenGL 支持 8 個紋理單元
- 當(dāng)我們需要向某個紋理單元設(shè)置紋理時,需要設(shè)置該紋理單元對應(yīng)的紋理坐標。
osg第五天 – 時間響應(yīng)和碰撞檢測
OSG 中主要使用 osgGA 庫來處理用戶的交互動作,GA 的全稱是 GUI Abstraction, 即圖形接口抽象層;
事件適配器 GUIEventAdapter
- 在用戶端,通常使用 GUIEventAdapter 類作為系統(tǒng)交互事件和 OSG 交互時間的適配接口,
- 它定義了一個且僅有一個人機交互事件,
- 基本包括了常見窗口系統(tǒng)中的鼠標、鍵盤、甚至觸摸板的操作。
動作適配器 GUIActionAdapter
- 用戶向系統(tǒng)傳遞請求通過 GUIActionAdapter 類來實現(xiàn)。
- 常見的用戶請求包括窗口的刷新以及鼠標坐標的位置。
碰撞檢測實戰(zhàn)(類似于點擊事件)
osg第六天 – 遍歷
NodeVisitor 類
- NodeVisitor 類是 OSG 對于訪問器設(shè)計思想的具體實現(xiàn)。
- 從本質(zhì)上說,NodeVisitor 類遍歷了一個場景圖形并為每一個被訪問節(jié)點調(diào)用特定的函數(shù)
- NodeVisitor 在 OSG 的應(yīng)用中無處不在
osg遍歷實例
osg遍歷的使用實例: 遍歷顯示節(jié)點信息
1、繼承 osg::NodeVisitor
2、重載 apply() 函數(shù)
3、調(diào)用函數(shù) accept() 方法
osg第七天 – 回調(diào)
使用回調(diào)實現(xiàn)地球的公轉(zhuǎn)自轉(zhuǎn)效果
osg回調(diào)的使用實例: ----使用回調(diào)實現(xiàn) 地球的公轉(zhuǎn)和自轉(zhuǎn)
使用粒子效果繪制行星尾跡
實現(xiàn)粒子效果
// Star.cpp osg::ref<osg::Geode> Star::buildTail(osg::Vec3 position, osg::MatrixTransform* scalar) {// 參數(shù)為位置和大小osg::ref_ptr<osgParticle::FireEffect> fire = new osgParticle::FireEffect(position,10);fire->setUserLocalParticleSystem(false);// 設(shè)置粒子噴射時間為--無限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第八天 – 相機及其應(yīng)用
HUD相機
HUD相機 全稱為 head up display : 意思為 “ 頭顯示 ”
( 用于常顯在屏幕坐標系的固定位置來展示信息)
HUD相機實例
osg HUD相機使用實例:
注意
HUD顯示文字時,需注意以下幾點:
osg第九天 – 漫游
漫游的使用
1、繼承 osg::CameraManipulator
2、重寫四個虛函數(shù) (其中兩個set方法,實現(xiàn)可為空)
3、重寫事件處理
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);4、調(diào)用
osg::ref_ptr<CDriveManupulator> rpDrive = new CDriverManupulator(); rpViewer->setCameraManipulator(rpDrive);總結(jié)
- 上一篇: 通过经纬度坐标计算两点间的距离以及角度关
- 下一篇: 阿里云Vod视频点播遇到的坑