OSG 逼真的渲染效果 -- 基礎篇一

1 渲染狀態機

opengl採用狀態機來跟蹤所有的渲染狀態.被狀態機管理的opengl渲染狀態有: scene lights(場景光照), materials(材質), textures(紋理)and texture environments(環境紋理), 以及所處的狀態,glEnable()---開啟狀態 glDisable()---關閉狀態.當一個opengl的狀態機進行了設置(開啟或關閉)那麼在渲染管線中就會存在一個特殊的棧進行狀態機的保存,並且所對應的效果會一直存在至有方法把它修改.

//opengl透明時需要打開和關閉的狀態機
glDisable(GL_DEPTH_TEST);//關閉深度測試,也就是在渲染一個像素的時候會檢查當前像素的前面是否還有像素如果別的像素擋道了它,那它就不會繪製
glEnable(GL_BLEND);//開啟混合渲染,把同一位置的前一個像素和後一個像素進行疊加後顯示.所以透明渲染會影響渲染速度
glColor4f(1.0f,1.0f,1.0f,0.5f);//設置透明度
glBlendFunc(GL_SRC_ALPHA,GL_ONE);//基於源像素Alpha通道值的半透明混合函數

osg也採用狀態機機制(osg::StateSet),因為為了配合osg場景樹這種結構,osg把opengl的狀態機進行了重新的封裝.osg::StateSet對渲染狀態值的操作是在the culling traversals(裁剪循環)和 rendering traversals(渲染循環)的時候,進行壓棧和彈出操作.osg::StateSet主要是管理rendering attribute和rending modes.rendering attributes 渲染屬性,通俗的說就是這個狀態對應的是那種類型的渲染模式,例如lights,materials,以及fogs.rendering modes 渲染模式(開關或者有一個枚舉類型),它用於對是否啟用渲染屬性(rendering attribute)的控制或者採用那種模式來控制渲染屬性.

osg::StateSet把rendering attribute和rending modes分成了兩組,一組是無紋理的rendering attribute和rending modes.另一組是有紋理的rendering attribute和rending modes.無紋理使用setAttribute()/setMode()以及setAttributeAndModes(),來綁定rendering attribute和rending modes.

stateset->setAttributeAndModes( attr, osg::StateAttribute::ON );

有紋理需要指定此rendering attribute和rending modes作用與那個紋理單元(每個顯卡都會內定它支持多少個紋理單元,有8個和16個等),使用setTextureAttribute() , setTextureMode() , 和setTextureAttributeAndModes()來綁定rendering attribute和rending modes到某個紋理單元.

stateset->setTextureAttributeAndModes(0, texattr, osg::StateAttribute::ON );

2.渲染狀態的繼承關係

每一個node的渲染狀態都將繼承父節點的渲染狀態,除非這個節點改變了它自己的渲染狀態或者設定了不繼承模式(保護模式).

stateset->setAttributeAndModes( attr,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE );//子節點的渲染狀態將被父節點的渲染狀態覆蓋.

或者

stateset->setAttributeAndModes( attr,osg::StateAttribute::ON|osg::StateAttribute::PROTECTED );//此節點的渲染狀態不會被父節點的狀態所覆蓋

例子:

#include <osg/PolygonMode>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

int main( int argc, char** argv )
{
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile( "glider.osg" );

osg::ref_ptr<osg::MatrixTransform> transformation1 = new osg::MatrixTransform;
transformation1->setMatrix( osg::Matrix::translate(-0.5f, 0.0f, 0.0f) );
transformation1->addChild( model.get() );
transformation1->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF );

osg::ref_ptr<osg::MatrixTransform> transformation2 = new osg::MatrixTransform;
transformation2->setMatrix( osg::Matrix::translate(0.5f, 0.0f, 0.0f) );
transformation2->addChild( model.get() );
transformation2->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED );

osg::ref_ptr<osg::Group> root = new osg::Group;
root->getOrCreateStateSet()->setMode(
GL_LIGHTING, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE );
root->addChild( transformation1.get() );
root->addChild( transformation2.get() );

osgViewer::Viewer viewer;
viewer.setSceneData( root.get() );
return viewer.run();
}

OSG中渲染屬性

歡迎大家來我的新家看一看3wwang個人博客-記錄走過的技術之路

推薦閱讀:

TAG:渲染器 | 渲染 | Lumion |