OSG编程杂记
Geometry不是一个节点(Node)继承自Drawable
从字面上也可以大致看出来,Geode 是一个包含Drawable的节点(Node),
Drawable --> Geometry
Node --> Geode
geode->addDrawable( geometry );
modes vs. attributes: OSG 模式(modes) 与OpenGL的模式(modes)直接关联,如着色,混合等
属性(Attributes)是模式的参数,如阴影模型和混合方程
OSG定义了一系列的属性类,这些类继承自StateAttribute,如BlendFunc等
mode是StateSet的一部分,所以可以这样使用:
osg::StateSet::setMode()
为了简单起见,使用方法setAttributeAndModes()可以同时设置模式(mode)和属性(attribute)
如下:
osg::BlendFunc* bf = new osg::BlendFunc();
state->setAttributeAndModes( bf, osg::StateAttribute::ON );
state->setAttributeAndModes( bf ); // 默认设置为ON
状态继承 一个子对象的状态继承自其父对象 osg::StateAttribute::OVERRIDE 如果你将一个渲染属性和模式设置为
OVERRIDE,那么所有的子节点都将继承这一属性或模式,子节点对它
们更改将会无效。 osg::StateAttribute::PROTECTED 这种形式可以视为OVERRIDE 的一
个例外。凡是设置为PROTECTED 的渲染属性或模式,均不会受到父节
点的影响。
默认情况下,子节点的STATESET渲染模式为OVERRIDE [Martz].
A
/ /
B C
A 颜色设置为Blue
B 颜色设置为Red
C 不改变颜色
那么c的颜色会是什么样?
C的颜色是Red!
是不是有点惊讶?
因为OSG会保留最后执行的glColor()函数的效果(此函数在设置B的时候被调用)
从B-->A的"回访"不会保存或弹出OpenGL状态
这并不是OSG所独有的(这是其他场景图库的通用做法);
停用节点: node->setNodeMask(0)
这可以有效的禁用不太明显的类如Cameras等
访问者模式 OSG使用访问者模式,并apply()相当于访问者模式中的visit()方法
从NodeVisitor 派生出来的对象,要重写apply()方法
class Visitor : public osg::NodeVisitor
{
virtual void apply( osg::Node& node ) // visit() method
{
...
// Keep searching.
traverse( node );
}
};
屏幕截图,记录和图像: osg::Image* shot = new osg::Image();
shot->allocateImage(width, height, 24, GL_RGB, GL_UNSIGNED_BYTE);
camera->attach(osg::Camera::COLOR_BUFFER, shot);
osgDB::writeImageFile(*shot,"image_file.png");
若要获取屏幕截图,需要使用Viewer渲染一个帧(frame) Direct rendering: OSG 提供几种方式用于直接调用OpenGL:
1.osg::Operation -osg::Window 的回调函数
2.osg::Camera::DrawCallback
3.继承osg::Drawable
前两种方式以frame为单位进行渲染
第三种方式(osg::Drawable)以节node为单位进行渲染
对于节点渲染(osg::Drawable),一个极好的例子是osgteapot.
class Teapot : public osg::Drawable
{
virtual void drawImplementation( osg::RenderInfo& ) const;
// 我们需要为数据建立一个包容盒,这样场景才能知道
// 对象的位置,这对初始化时确定相机位置和
// 执行拣选(culling)十分重要
virtual osg::BoundingBox computeBound() const;
};
渲染元: [Martz]
"主题: Re: [osg-users] 渲染序列
osgUtil::CullVisitor 从可见的Drawable对象创建渲染元(RenderBins)
然后处理每一个RenderBin。所以,查看CullVisitor和RenderBin的代码
然后在看看osg::Geometry::apply等,了解Geometry是如何传递给OpenGL的。
你可以使用GLIntercept等工具来捕获OpenGL命令,这样可以让你看到OSG是如何渲染场景的"
[Osfield]
"在将多个Drawable,Stateset和RenderBin/RenderStage以及一个状态图放入渲染后端时,
OSG 中的状态排序(state sorting)是作为拣选过程的一部分来完成的,一个渲染元(RenderBin )排序完成时,
其状态值(state)为sorted,这个过程是通过一个STL的映射容器完成的,此容器保存指针与StateSet的映射"
禁用光照: osg::StateAttribute::OVERRIDE 渲染模式下可以禁用光照,但PROTECTED下不行,如下: mSwitchNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF ); 多光源: osg::Light 是一个状态属性(state attribute);
osg::LightSource 是一个组(Group)
一个LightSource只能包含一个osg::Light
所以,要使用多光源,需要建立由一个由LightSource组成的线性链表
然后将渲染对象(geometry)放置到此链表的末端
root
|
V
lightSource 0
|
V
lightSource 1
|
V
geodes
处理ESC键: viewer->setKeyEventSetsDone( 0 );
相机: Cameras 定义3D的模型视图矩阵(modelview matrix),2D的视点和渲染对象。
Cameras 包含在一个图形窗口的图形上下文中
Cameras 可以作为节点(node)放入一个场景图中(原始方式)
或添加到osg::Viewer中(新方式)
操作机(Manipulator)可以控制Camera
Manipulator可以高效的定义一个模型视图矩阵(modelview matrix)
使用Manipulator::getInverseMatrix()可以提取一个模型视图矩阵
一个Camera定义需要渲染的目标
对于2D窗口中不同视角,OSG通过添加多个Camera来对每一个视角进行单独渲染
纹理渲染(RTT)也是由osg::Camera完成的,
将一个纹理设置为camera的"渲染目标"(render target)即可.
在绘制视图前/后调用的回调函数(Callbacks),可以通过osg::Camera来注册.
在视图中启用窗口模式: viewer.setUpViewInWindow( 0, 0, 1024, 768 ); |