首先分析函数_create_scene(),此函数创建的图片如下:
下面分析这几个相互移动的物体是怎么画出来的,先不考虑纹理的问题。
代码和注释如下:
ref_ptr
<
Group
>
_create_scene()
... {
//要返回的scene,是一个Group类型的
ref_ptr<Group> scene = new Group;
//创建叶节点并加入到scene中,它包括中间的大球和底盘
ref_ptr<Geode> geode_1 = new Geode;
scene->addChild(geode_1.get());
//创建叶节点2,把他加入到一个变换矩阵中,变换矩阵加入到sence
//由后面可知,叶节点2包括一个锥体,一个圆柱体,一个小圆球
//(相对于中间的大圆球),一个立方体。
ref_ptr<Geode> geode_2 = new Geode;
ref_ptr<MatrixTransform> transform_2 = new MatrixTransform;
transform_2->addChild(geode_2.get());
//变换矩阵设置动画,绕y轴以每秒45度角的速度旋转
transform_2->setUpdateCallback(new osg::AnimationPathCallback(Vec3(0, 0, 0), Y_AXIS, inDegrees(45.0f)));
scene->addChild(transform_2.get());
//同叶节点2类似,叶节点3包括一个平板(最上方),反方向旋转
ref_ptr<Geode> geode_3 = new Geode;
ref_ptr<MatrixTransform> transform_3 = new MatrixTransform;
transform_3->addChild(geode_3.get());
transform_3->setUpdateCallback(new osg::AnimationPathCallback(Vec3(0, 0, 0), Y_AXIS, inDegrees(-22.5f)));
scene->addChild(transform_3.get());
//这2个变量限制了图像的大小
const float radius = 0.8f;
const float height = 1.0f;
//网格化(分格化tessellation)即把凹多边形,包含洞,岛的多边型,
//或者自交叉多边型划分为简单凸多边形的过程
//详细参考《opengl编程指南》第11章《分格化和二次方程表面》
ref_ptr<TessellationHints> hints = new TessellationHints;
//设置分格化的半径,如果我们把此处设置为0.1,可看到球、锥、柱会有很明显的棱角
hints->setDetailRatio(2.0f);
ref_ptr<ShapeDrawable> shape;
shape = new ShapeDrawable(new Box(Vec3(0.0f, -2.0f, 0.0f), 10, 0.1f, 10), hints.get());
shape->setColor(Vec4(0.5f, 0.5f, 0.7f, 1.0f));
geode_1->addDrawable(shape.get());
shape = new ShapeDrawable(new Sphere(Vec3(0.0f, 0.0f, 0.0f), radius * 2), hints.get());
shape->setColor(Vec4(0.8f, 0.8f, 0.8f, 1.0f));
geode_1->addDrawable(shape.get());
shape = new ShapeDrawable(new Sphere(Vec3(-3.0f, 0.0f, 0.0f), radius), hints.get());
shape->setColor(Vec4(0.6f, 0.8f, 0.8f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Box(Vec3(3.0f, 0.0f, 0.0f), 2 * radius), hints.get());
shape->setColor(Vec4(0.4f, 0.9f, 0.3f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Cone(Vec3(0.0f, 0.0f, -3.0f), radius, height), hints.get());
shape->setColor(Vec4(0.2f, 0.5f, 0.7f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Cylinder(Vec3(0.0f, 0.0f, 3.0f), radius, height), hints.get());
shape->setColor(Vec4(1.0f, 0.3f, 0.3f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Box(Vec3(0.0f, 3.0f, 0.0f), 2, 0.1f, 2), hints.get());
shape->setColor(Vec4(0.8f, 0.8f, 0.4f, 1.0f));
geode_3->addDrawable(shape.get());
ref_ptr<Material> matirial = new Material;
//设置模式为散射,很大程度上决定了材质的颜色
// 设置材质模式,参考《opengl编程指南》的《5.6.5颜色材质模式》
//为了降低改变材质属性的开销,为了避免材质属性发生不必要的变化,
//只有指定的材质属性才发生变化
matirial->setColorMode(Material::DIFFUSE);
//设置环境光
matirial->setAmbient(Material::FRONT_AND_BACK, Vec4(0, 0, 0, 1));
//设置反射光
matirial->setSpecular(Material::FRONT_AND_BACK, Vec4(1, 1, 1, 1));
//设置反射指数
matirial->setShininess(Material::FRONT_AND_BACK, 64.0f);
scene->getOrCreateStateSet()->setAttributeAndModes(matirial.get(), StateAttribute::ON);
return scene;
}
... {
//要返回的scene,是一个Group类型的
ref_ptr<Group> scene = new Group;
//创建叶节点并加入到scene中,它包括中间的大球和底盘
ref_ptr<Geode> geode_1 = new Geode;
scene->addChild(geode_1.get());
//创建叶节点2,把他加入到一个变换矩阵中,变换矩阵加入到sence
//由后面可知,叶节点2包括一个锥体,一个圆柱体,一个小圆球
//(相对于中间的大圆球),一个立方体。
ref_ptr<Geode> geode_2 = new Geode;
ref_ptr<MatrixTransform> transform_2 = new MatrixTransform;
transform_2->addChild(geode_2.get());
//变换矩阵设置动画,绕y轴以每秒45度角的速度旋转
transform_2->setUpdateCallback(new osg::AnimationPathCallback(Vec3(0, 0, 0), Y_AXIS, inDegrees(45.0f)));
scene->addChild(transform_2.get());
//同叶节点2类似,叶节点3包括一个平板(最上方),反方向旋转
ref_ptr<Geode> geode_3 = new Geode;
ref_ptr<MatrixTransform> transform_3 = new MatrixTransform;
transform_3->addChild(geode_3.get());
transform_3->setUpdateCallback(new osg::AnimationPathCallback(Vec3(0, 0, 0), Y_AXIS, inDegrees(-22.5f)));
scene->addChild(transform_3.get());
//这2个变量限制了图像的大小
const float radius = 0.8f;
const float height = 1.0f;
//网格化(分格化tessellation)即把凹多边形,包含洞,岛的多边型,
//或者自交叉多边型划分为简单凸多边形的过程
//详细参考《opengl编程指南》第11章《分格化和二次方程表面》
ref_ptr<TessellationHints> hints = new TessellationHints;
//设置分格化的半径,如果我们把此处设置为0.1,可看到球、锥、柱会有很明显的棱角
hints->setDetailRatio(2.0f);
ref_ptr<ShapeDrawable> shape;
shape = new ShapeDrawable(new Box(Vec3(0.0f, -2.0f, 0.0f), 10, 0.1f, 10), hints.get());
shape->setColor(Vec4(0.5f, 0.5f, 0.7f, 1.0f));
geode_1->addDrawable(shape.get());
shape = new ShapeDrawable(new Sphere(Vec3(0.0f, 0.0f, 0.0f), radius * 2), hints.get());
shape->setColor(Vec4(0.8f, 0.8f, 0.8f, 1.0f));
geode_1->addDrawable(shape.get());
shape = new ShapeDrawable(new Sphere(Vec3(-3.0f, 0.0f, 0.0f), radius), hints.get());
shape->setColor(Vec4(0.6f, 0.8f, 0.8f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Box(Vec3(3.0f, 0.0f, 0.0f), 2 * radius), hints.get());
shape->setColor(Vec4(0.4f, 0.9f, 0.3f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Cone(Vec3(0.0f, 0.0f, -3.0f), radius, height), hints.get());
shape->setColor(Vec4(0.2f, 0.5f, 0.7f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Cylinder(Vec3(0.0f, 0.0f, 3.0f), radius, height), hints.get());
shape->setColor(Vec4(1.0f, 0.3f, 0.3f, 1.0f));
geode_2->addDrawable(shape.get());
shape = new ShapeDrawable(new Box(Vec3(0.0f, 3.0f, 0.0f), 2, 0.1f, 2), hints.get());
shape->setColor(Vec4(0.8f, 0.8f, 0.4f, 1.0f));
geode_3->addDrawable(shape.get());
ref_ptr<Material> matirial = new Material;
//设置模式为散射,很大程度上决定了材质的颜色
// 设置材质模式,参考《opengl编程指南》的《5.6.5颜色材质模式》
//为了降低改变材质属性的开销,为了避免材质属性发生不必要的变化,
//只有指定的材质属性才发生变化
matirial->setColorMode(Material::DIFFUSE);
//设置环境光
matirial->setAmbient(Material::FRONT_AND_BACK, Vec4(0, 0, 0, 1));
//设置反射光
matirial->setSpecular(Material::FRONT_AND_BACK, Vec4(1, 1, 1, 1));
//设置反射指数
matirial->setShininess(Material::FRONT_AND_BACK, 64.0f);
scene->getOrCreateStateSet()->setAttributeAndModes(matirial.get(), StateAttribute::ON);
return scene;
}