文章目录
说明
- OSG 入门看的,大佬绕道
- 示例来源于《OSG程序设计教程》
- 没有此电子书的小伙伴们,我已上传至CSDN
1. 模型的基本操作
1.1 添加模型
- 程序功能:添加模型
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
int main() {
// 新建 viewer
osgViewer::Viewer viewer;
// 新建 Group
osg::Group *root = new osg::Group();
// 添加2个 Node
root->addChild(osgDB::readNodeFile("glider.osg"));
root->addChild(osgDB::readNodeFile("osgcool.osg"));
// 这时候滑翔机会藏在牛肚子里,需要把牛放大了看
// 设置场景数据
viewer.setSceneData(root);
// 渲染
viewer.realize();
viewer.run();
}
// 如果想要添加别的模型,还可以 root->addChild
// 但是,如果想在飞机上面添加一些什么,就需要把飞机当成组结点,
// 然后再飞机结点上再添加一些东西,见下
#if 0
osg::Group *root = new osg::Group();
osg::Node *glider = osgDB::ReadNodeFile(“glider.osg”);
glider->asGroup()->addChild(osgDB::ReadNodeFile(“xxx.osg””));
root->addChild(glider);
root->addChild(osgDB::readNodeFile(“osgcool.osg”));
#endif
1.2 删除模型
1.3 隐藏模型
- 程序功能:注意模型虽然隐藏了,但是还是会参与渲染,时间并不会减少
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
void main() {
osgViewer::Viewer viewer;
osg::Group *root = new osg::Group();
osg::Node *cow = osgDB::readNodeFile("cow.osg");
root->addChild(cow);
root->addChild(osgDB::readNodeFile("glider.osg"));
cow->setNodeMask(0x0); /// cow->setNodeMask(1); 代表显示
// 你会发现牛消失了
viewer.setSceneData(root);
viewer.realize();
viewer.run();
}
1.4 结点开关
-
定义:隐掉一个结点,使它在内存当中消失,想要的时候调出来,不使用的时候不存在与内存中
-
程序功能:打开或关闭一个/些结点,而在关闭时这些结点占用的内存会被释放掉
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Switch>
void main() {
osgViewer::Viewer viewer;
osg::Group *root = new osg::Group();
osg::Switch *sw = new osg::Switch();
osg::Node *cow = osgDB::readNodeFile("cow.osg");
sw->addChild(cow, false);
sw->addChild(osgDB::readNodeFile("glider.osg"));
root->addChild(sw);
viewer.setSceneData(root);
viewer.realize();
viewer.run();
}
- 这时候滑翔机在屏幕中间,这是因为牛的确不在内存中。而上一个示例代码的滑翔机并不在屏幕中间,是因为牛在内存中。注意 隐藏 和 开关 两者区别。
1.5 超级指针(其实就是智能指针,smart pointer)
2. 移动/旋转/缩放模型
- 功能:移动/旋转/缩放模型,这里加入了四个 cow,一个是默认加入在最中间,一个向上移 2 单位,一 个是向下移 2 单位且缩放 0.5 倍,另一个是向右 4 单位,缩放 0.5 且平躺 45 度
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/MatrixTransform>
void main() {
osgViewer::Viewer viewer;
osg::ref_ptr <osg::Group> root = new osg::Group();
osg::ref_ptr <osg::Node> cow = osgDB::readNodeFile("cow.osg"); // 默认在中间
osg::ref_ptr <osg::MatrixTransform> trans = new osg::MatrixTransform;
trans->setMatrix(osg::Matrix::translate(0, 0, 2)); // 3 个参数分别是 X、Y、Z
// 默认 X 轴是 X 轴,向里的是 Y 轴,而向上是 Z 轴,这与传统的 OPENGL 坐标轴不同
trans->addChild(cow.get()); // 向上平移 2 个单位
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(cow.get()); // 向下平移 2 个单位,外加缩小 1 倍
osg::ref_ptr < osg::MatrixTransform > rot = new osg::MatrixTransform;
// 函数 DegreesToRadians 可以把角度转为弧度
rot->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), 1, 0, 0)*osg::Matrix::scale(0.5, 0.5, 0.5)*osg::Matrix::translate(4, 0, -2)); // 向左 4 个单位,向下 2 个单位,缩小 1 倍,绕 X 轴转 45 度
rot->addChild(cow.get());
root->addChild(cow.get()); // 原始图
root->addChild(trans.get());
root->addChild(scale.get());
root->addChild(rot.get());
viewer.setSceneData(root.get());
viewer.realize();
viewer.run();
}