在上一篇文章http://blog.csdn.net/pursue16/article/details/71453750的例子中,存在着很多不方便的地方。
例如:程序在渲染了C原子之后不能马上继续使用当前的渲染状态继续进行第一个O原子的渲染,这是因为,,此时的渲染状态还没有恢复到先前使用的状态,即材质节点中的颜色变量值仍旧保持着前一描绘过程中的颜色,而没有恢复到系统的默认颜色。与之相类似的是,在渲染了第一个O原子后,还不能直接进行第二个O原子的渲染工作,因为此时的变换节点变量没有恢复到系统原点,而仍旧处于X的负1.2个单位处。这些都为建立更为复杂的模型带来了麻烦。
分隔符节点(Separator Node)可以更好的解决上述问题。分隔符节点能够屏蔽群组节点中子节点对便利状态变量值的修改,从而使前一个群组对状态变量值的修改不会影响下一个群组节点中的子节点。分隔符四群组节点类SoGroup中的一个子类。每次在遍历前一个群组节点时的值,从而使处于分隔符节点中的子节点不会对场景图中的左侧或者又测节点产生其他任何影响。
例如:可以首先绘制一个立方体,并设置立方体的绘制方式、光照模型和材质等细节;然后,在另一个地方此阿勇默认值来重新绘制该立方体,则可以看出分隔符节点的不同作用。
#include <stdlib.h>
#include <Inventor\Win\SoWin.h>
#include <Inventor\Win\viewers\SoWinExaminerViewer.h>
#include <Inventor\nodes\SoDrawStyle.h>
#include <Inventor\nodes\SoMaterial.h>
#include <Inventor\nodes\SoSeparator.h>
#include <Inventor\nodes\SoCube.h>
#include <Inventor\nodes\SoTranslation.h>
#include <Inventor\nodes\SoLightModel.h>
SoSeparator *scene()
{
SoSeparator * cube = new SoSeparator;
SoSeparator * cube1 = new SoSeparator;
SoSeparator * cube2 = new SoSeparator;
cube->ref();
SoTranslation * transl = new SoTranslation;
SoDrawStyle *style = new SoDrawStyle;
SoMaterial * mat1 = new SoMaterial;
SoMaterial * mat2 = new SoMaterial;
transl->translation.setValue(3.0, 0.0, 0.0);
mat1->diffuseColor.setValue(0, 0, 1);
mat2->diffuseColor.setValue(1, 0, 0);
style->style.setValue(SoDrawStyle::LINES);
//创建层次结构
cube->addChild(cube1);
cube->addChild(cube2);
cube1->addChild(mat1);
cube1->addChild(style);
cube1->addChild(new SoCube);
cube2->addChild(transl);
cube2->addChild(mat2);
cube2->addChild(new SoCube);
cube->unrefNoDelete();
return cube;
}
int main(int, char **argv)
{
(void)printf("This example shows how to use the SoSeparator node...\n");
//初始化open inventor和Windows
HWND myWindow = SoWin::init(argv[0]);
if (myWindow == NULL)
exit(1);
SoSeparator *root = new SoSeparator;
root->ref();
//添加所创建的场景
root->addChild(scene());
SoWinExaminerViewer *myViewer = new SoWinExaminerViewer(myWindow);
myViewer->setSceneGraph(root);
myViewer->setBackgroundColor(SbColor(1,1,1));
//将背景色设置为白色
myViewer->setTitle("SoSeparator");
myViewer->show();
myViewer->viewAll();
SoWin::show(myWindow);//显示主窗口
SoWin::mainLoop();//进入主事件循环
delete myViewer;//释放myviewer资源
root->unref();//减少引用计数,删除节点
return 0;
}
从程序中可以看出,两个立方体分隔符节点中对状态变量的修改不会影响与之相邻的其他节点。
程序运行结果如下: