osg-02-模型简单控制

1.创建一个组,将节点文件添加到组中并渲染出来

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
int main(int argc,char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::Group* root = new osg::Group();
	root->addChild(osgDB::readNodeFile("glider.osg"));
	root->addChild(osgDB::readNodeFile("osgcool.osgt"));

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();

	// 进行渲染
	return viewer.run();
}

2.将节点作为组,在其基础上添加其他节点文件

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
//将节点作为组,在其基础上添加其他节点文件
int main(int argc, char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::Group* root = new osg::Group();
	osg::Node* glider = osgDB::readNodeFile("glider.osg");
	glider->asGroup()->addChild(osgDB::readNodeFile("osgcool.osgt"));
	root->addChild(glider);

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();

	// 进行渲染
	return viewer.run();
}

3.删除结点

*如果要删除一个结点,那么该结点下的所有结点都会被删除。如果一个结点被加入
到一个组中两次,那么这两次是分别存在的,删除一次还有另一次。

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
//将节点作为组,在其基础上添加其他节点文件
int main(int argc, char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::Group* root = new osg::Group();
	osg::Node* glider = osgDB::readNodeFile("glider.osg");
	glider->asGroup()->addChild(osgDB::readNodeFile("osgcool.osgt"));
	root->addChild(glider);

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();

	//删除结点
	root->removeChild(glider);
	//root->removeChildren()

	// 进行渲染
	return viewer.run();
}

4.隐藏结点

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
//隐藏结点
int main(int argc, char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::Group* root = new osg::Group();
	osg::Node* glider = osgDB::readNodeFile("glider.osg");
	glider->asGroup()->addChild(osgDB::readNodeFile("osgcool.osgt"));
	root->addChild(glider);

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();

	//隐藏结点
	osg::Group* gliderGroup = glider->asGroup();
	int count = gliderGroup->getNumChildren();
	for (int i = 1; i < count; i++)
	{
		osg::Node* node = gliderGroup->getChild(i);
		node->setNodeMask(0x0); //0x0   0xffffffff
	}

	// 进行渲染
	return viewer.run();
}

5.结点开关

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Switch>
//结点开关
int main(int argc, char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::Group* root = new osg::Group();
	osg::Switch* sw = new osg::Switch();
	osg::Node* osgcool = osgDB::readNodeFile("osgcool.osgt");
	sw->addChild(osgcool, false);	//关
	sw->addChild(osgDB::readNodeFile("glider.osg"));

	root->addChild(sw);

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();

	sw->setChildValue(osgcool, true);//开
	// 进行渲染
	return viewer.run();
}

6.超级指针

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Switch>
//超级指针
int main(int argc, char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::Group* root = new osg::Group();
	//方法一最好的方法,十分安全,也是OSG中最常用的方法,多少版本它都没变
	osg::ref_ptr<osg::Node> aNode(new osg::Node);
	root->addChild(aNode.get());

	//方法二,也是非常好的方法,有时候不适用,但也十分安全
	root->addChild(new osg::Node());

	//方法三,非常危险,但是令许多人无故铤而走险的方法
	osg::Node* anotherNode = new osg::Node();
	root->addChild(anotherNode);

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();
	// 进行渲染
	return viewer.run();
}

方法一:在 new::Node()时申请了一个 Node 的资源,这时在堆内引用该 Node 的计算器会被置 1。在 group
->addChild(aNode.get())时又引用了一次,会再加 1。在这两次引用都结束时,Node 的资源就会被释放。 方法二:这个方法也是很实用的,但是无法引出 Node 的指针,也许在别处可以用到,事实上会经常用到。 如果已经这样做了,得到 Node
指针也不是不可以的,可以使用 NodeVisitor 来得到 Node 的指针,也可以使 用 findChild 方法来做这件事。
方法三:这个应该是最常用,但是最烂的方法了,原因在于如果在 osg::Node*antherode = new osg::Node()
之后发生了错误,抛出了异常,谁来释放 Node 所占用的资源呢。而这个异常在后面被捕获,程序正常的走 下去,而内存却没有被正常的放掉。
通常说,我们建议一直使用 osg::ref_ptf,今天论坛上有位朋友问,官方例子也没有见用啊,在这里我要解
释一下。有几个原因,首先官方的例子代码都短,没有复杂的交互与场景的换入换入,物体的显示与隐藏
等等。其二,如果代码在分配之后有抛出异常的代码是需要超级指针的,而那里面没有那些代码。在有大 量交互的时候以及场景变换时,建议使用超级指针。

7.移动、旋转、缩放模型

移动/旋转/缩放模型,这里加入了四个 coolosg,一个是默认加入在最中间,一个向上移 2 单位,一 个是向下移 2 单位且缩放 0.5
倍,另一个是向右 4 单位,缩放 0.5 且平躺 45 度

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/MatrixTransform>
//移动/旋转/缩放模型
//在 OSG 中坐标轴是可以设置的,默认 X 轴是 X 轴,向里的是 Y 轴,而向上是 Z 轴,这与传统的 OPENGL 坐标轴多有不同。

int main(int argc, char** argv)
{
	//创建窗口
	osgViewer::Viewer viewer;

	osg::ref_ptr<osg::Group> root = new osg::Group();

	osg::ref_ptr<osg::Node> osgcool = osgDB::readNodeFile("osgcool.osgt");

	//移动
	osg::ref_ptr<osg::MatrixTransform> translate = new osg::MatrixTransform;
	translate->setMatrix(osg::Matrix::translate(0, 0, -2));
	translate->addChild(osgcool.get());

	//缩放
	osg::ref_ptr<osg::MatrixTransform> scale = new osg::MatrixTransform;
	scale->setMatrix(osg::Matrix::scale(0.5, 0.5, 0.5) * osg::Matrix::translate(0, 0, 2));
	scale->addChild(osgcool.get());

	//旋转
	osg::ref_ptr<osg::MatrixTransform> rotate = new osg::MatrixTransform;
	//函数 DegreesToRadians 可以把角度转为弧度
	rotate->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(90.0), 0, 1, 0) * osg::Matrix::scale(0.5, 0.5, 0.5) * osg::Matrix::translate(4, 0, -2));
	rotate->addChild(osgcool.get());

	root->addChild(osgcool.get());
	root->addChild(translate.get());
	root->addChild(scale.get());
	root->addChild(rotate.get());

	//加载数据
	viewer.setSceneData(root);

	//使设置生效
	viewer.realize();
	// 进行渲染
	return viewer.run();
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值